aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Gultsch <daniel.gultsch@rwth-aachen.de>2014-02-04 15:09:50 +0100
committerDaniel Gultsch <daniel.gultsch@rwth-aachen.de>2014-02-04 15:09:50 +0100
commit0d80d88736926d06e97f22f9ecc63d4fb696751c (patch)
treed61669953ae47a0c96dcc5dc814bc0f49527c547
parent14a171b088363d8e39b547eecc181570c4289428 (diff)
reworked account managment. now status display actually works
Diffstat (limited to '')
-rw-r--r--res/layout/account_row.xml6
-rw-r--r--src/de/gultsch/chat/entities/Account.java21
-rw-r--r--src/de/gultsch/chat/services/XmppConnectionService.java162
-rw-r--r--src/de/gultsch/chat/ui/ManageAccountActivity.java108
-rw-r--r--src/de/gultsch/chat/ui/OnAccountListChangedListener.java5
-rw-r--r--src/de/gultsch/chat/xml/TagWriter.java51
-rw-r--r--src/de/gultsch/chat/xmpp/OnStatusChanged.java7
-rw-r--r--src/de/gultsch/chat/xmpp/XmppConnection.java85
8 files changed, 286 insertions, 159 deletions
diff --git a/res/layout/account_row.xml b/res/layout/account_row.xml
index c10099dd..92e179f8 100644
--- a/res/layout/account_row.xml
+++ b/res/layout/account_row.xml
@@ -35,16 +35,16 @@
android:layout_height="wrap_content"
android:text="Status: "
android:textStyle="bold"
- android:textSize="14sp" />
+ android:textSize="16sp" />
<TextView
android:id="@+id/account_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#669900"
- android:text="Online"
+ android:text="unknown"
android:textStyle="bold"
- android:textSize="14sp"/>
+ android:textSize="16sp"/>
</LinearLayout>
diff --git a/src/de/gultsch/chat/entities/Account.java b/src/de/gultsch/chat/entities/Account.java
index 79712b15..3dfb298a 100644
--- a/src/de/gultsch/chat/entities/Account.java
+++ b/src/de/gultsch/chat/entities/Account.java
@@ -18,11 +18,20 @@ public class Account extends AbstractEntity{
public static final int OPTION_USETLS = 0;
+ public static final int STATUS_OFFLINE = 0;
+ public static final int STATUS_ONLINE = 1;
+ public static final int STATUS_UNAUTHORIZED = 2;
+ public static final int STATUS_NOINTERNET = 3;
+ public static final int STATUS_TLS_ERROR = 4;
+ public static final int STATUS_SERVER_NOT_FOUND = 5;
+
protected String username;
protected String server;
protected String password;
protected int options;
protected String rosterVersion;
+ protected String resource;
+ protected int status = 0;
protected boolean online = false;
@@ -70,8 +79,16 @@ public class Account extends AbstractEntity{
this.password = password;
}
- public boolean isOnline() {
- return online;
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public int getStatus() {
+ return this.status;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
}
public String getJid() {
diff --git a/src/de/gultsch/chat/services/XmppConnectionService.java b/src/de/gultsch/chat/services/XmppConnectionService.java
index fee2aafe..fbbaca5c 100644
--- a/src/de/gultsch/chat/services/XmppConnectionService.java
+++ b/src/de/gultsch/chat/services/XmppConnectionService.java
@@ -1,6 +1,5 @@
package de.gultsch.chat.services;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
@@ -10,7 +9,7 @@ import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation;
import de.gultsch.chat.entities.Message;
import de.gultsch.chat.persistance.DatabaseBackend;
-import de.gultsch.chat.ui.ConversationActivity;
+import de.gultsch.chat.ui.OnAccountListChangedListener;
import de.gultsch.chat.ui.OnConversationListChangedListener;
import de.gultsch.chat.ui.OnRosterFetchedListener;
import de.gultsch.chat.utils.UIHelper;
@@ -19,20 +18,15 @@ import de.gultsch.chat.xmpp.IqPacket;
import de.gultsch.chat.xmpp.MessagePacket;
import de.gultsch.chat.xmpp.OnIqPacketReceived;
import de.gultsch.chat.xmpp.OnMessagePacketReceived;
+import de.gultsch.chat.xmpp.OnStatusChanged;
import de.gultsch.chat.xmpp.XmppConnection;
-import android.R;
-import android.R.dimen;
import android.app.NotificationManager;
-import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
-import android.content.res.Resources;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
-import android.support.v4.app.NotificationCompat;
-import android.support.v4.app.TaskStackBuilder;
import android.util.Log;
public class XmppConnectionService extends Service {
@@ -48,6 +42,7 @@ public class XmppConnectionService extends Service {
private Hashtable<Account, XmppConnection> connections = new Hashtable<Account, XmppConnection>();
private OnConversationListChangedListener convChangedListener = null;
+ private OnAccountListChangedListener accountChangedListener = null;
private final IBinder mBinder = new XmppConnectionBinder();
private OnMessagePacketReceived messageListener = new OnMessagePacketReceived() {
@@ -79,6 +74,16 @@ public class XmppConnectionService extends Service {
}
}
};
+ private OnStatusChanged statusListener = new OnStatusChanged() {
+
+ @Override
+ public void onStatusChanged(Account account) {
+ Log.d(LOGTAG,account.getJid()+" changed status to "+account.getStatus());
+ if (accountChangedListener != null) {
+ accountChangedListener.onAccountListChangedListener();
+ }
+ }
+ };
public class XmppConnectionBinder extends Binder {
public XmppConnectionService getService() {
@@ -88,15 +93,10 @@ public class XmppConnectionService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
for (Account account : accounts) {
if (!connections.containsKey(account)) {
- XmppConnection connection = new XmppConnection(account, pm);
- connection
- .setOnMessagePacketReceivedListener(this.messageListener);
- Thread thread = new Thread(connection);
- thread.start();
- this.connections.put(account, connection);
+
+ this.connections.put(account, this.createConnection(account));
}
}
return START_STICKY;
@@ -107,6 +107,17 @@ public class XmppConnectionService extends Service {
databaseBackend = DatabaseBackend.getInstance(getApplicationContext());
this.accounts = databaseBackend.getAccounts();
}
+
+ public XmppConnection createConnection(Account account) {
+ PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+ XmppConnection connection = new XmppConnection(account, pm);
+ connection
+ .setOnMessagePacketReceivedListener(this.messageListener);
+ connection.setOnStatusChangedListener(this.statusListener );
+ Thread thread = new Thread(connection);
+ thread.start();
+ return connection;
+ }
@Override
public IBinder onBind(Intent intent) {
@@ -114,68 +125,49 @@ public class XmppConnectionService extends Service {
}
public void sendMessage(final Account account, final Message message) {
- new Thread() {
- @Override
- public void run() {
- Log.d(LOGTAG, "sending message for " + account.getJid()
- + " to: " + message.getCounterpart());
- databaseBackend.createMessage(message);
- MessagePacket packet = new MessagePacket();
- packet.setType(MessagePacket.TYPE_CHAT);
- packet.setTo(message.getCounterpart());
- packet.setFrom(account.getJid());
- packet.setBody(message.getBody());
- try {
- connections.get(account).sendMessagePacket(packet);
- message.setStatus(Message.STATUS_SEND);
- databaseBackend.updateMessage(message);
- } catch (IOException e) {
- Log.d(LOGTAG,
- "io exception during send. message is in database. will try again later");
- }
- }
- }.start();
+ Log.d(LOGTAG, "sending message for " + account.getJid() + " to: "
+ + message.getCounterpart());
+ databaseBackend.createMessage(message);
+ MessagePacket packet = new MessagePacket();
+ packet.setType(MessagePacket.TYPE_CHAT);
+ packet.setTo(message.getCounterpart());
+ packet.setFrom(account.getJid());
+ packet.setBody(message.getBody());
+ connections.get(account).sendMessagePacket(packet);
+ message.setStatus(Message.STATUS_SEND);
+ databaseBackend.updateMessage(message);
}
public void getRoster(final Account account,
final OnRosterFetchedListener listener) {
- new Thread() {
- @Override
- public void run() {
- IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
- Element query = new Element("query");
- query.setAttribute("xmlns", "jabber:iq:roster");
- query.setAttribute("ver", "");
- iqPacket.addChild(query);
- try {
- connections.get(account).sendIqPacket(iqPacket,
- new OnIqPacketReceived() {
+ IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
+ Element query = new Element("query");
+ query.setAttribute("xmlns", "jabber:iq:roster");
+ query.setAttribute("ver", "");
+ iqPacket.addChild(query);
+ connections.get(account).sendIqPacket(iqPacket,
+ new OnIqPacketReceived() {
- @Override
- public void onIqPacketReceived(Account account,
- IqPacket packet) {
- Element roster = packet.findChild("query");
- List<Contact> contacts = new ArrayList<Contact>();
- for (Element item : roster.getChildren()) {
- String name = item.getAttribute("name");
- String jid = item.getAttribute("jid");
- if (name == null) {
- name = jid.split("@")[0];
- }
- Contact contact = new Contact(account,
- name, jid, null);
- contacts.add(contact);
- }
- if (listener != null) {
- listener.onRosterFetched(contacts);
- }
- }
- });
- } catch (IOException e) {
- Log.d(LOGTAG, "io error during roster fetch");
- }
- }
- }.start();
+ @Override
+ public void onIqPacketReceived(Account account,
+ IqPacket packet) {
+ Element roster = packet.findChild("query");
+ List<Contact> contacts = new ArrayList<Contact>();
+ for (Element item : roster.getChildren()) {
+ String name = item.getAttribute("name");
+ String jid = item.getAttribute("jid");
+ if (name == null) {
+ name = jid.split("@")[0];
+ }
+ Contact contact = new Contact(account, name, jid,
+ null);
+ contacts.add(contact);
+ }
+ if (listener != null) {
+ listener.onRosterFetched(contacts);
+ }
+ }
+ });
}
public void addConversation(Conversation conversation) {
@@ -249,14 +241,32 @@ public class XmppConnectionService extends Service {
public void createAccount(Account account) {
databaseBackend.createAccount(account);
+ this.accounts.add(account);
+ this.connections.put(account, this.createConnection(account));
+ if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener();
}
public void updateAccount(Account account) {
databaseBackend.updateAccount(account);
+ XmppConnection connection = this.connections.get(account);
+ if (connection != null) {
+ connection.disconnect();
+ this.connections.remove(account);
+ }
+ this.connections.put(account, this.createConnection(account));
+ if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener();
}
public void deleteAccount(Account account) {
+ Log.d(LOGTAG,"called delete account");
+ if (this.connections.containsKey(account)) {
+ Log.d(LOGTAG,"found connection. disconnecting");
+ this.connections.get(account).disconnect();
+ this.connections.remove(account);
+ this.accounts.remove(account);
+ }
databaseBackend.deleteAccount(account);
+ if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener();
}
public void setOnConversationListChangedListener(
@@ -267,4 +277,12 @@ public class XmppConnectionService extends Service {
public void removeOnConversationListChangedListener() {
this.convChangedListener = null;
}
+
+ public void setOnAccountListChangedListener(OnAccountListChangedListener listener) {
+ this.accountChangedListener = listener;
+ }
+
+ public void removeOnAccountListChangedListener() {
+ this.accountChangedListener = null;
+ }
}
diff --git a/src/de/gultsch/chat/ui/ManageAccountActivity.java b/src/de/gultsch/chat/ui/ManageAccountActivity.java
index c7d6ce58..0a9b03de 100644
--- a/src/de/gultsch/chat/ui/ManageAccountActivity.java
+++ b/src/de/gultsch/chat/ui/ManageAccountActivity.java
@@ -6,7 +6,6 @@ import java.util.List;
import de.gultsch.chat.R;
import de.gultsch.chat.entities.Account;
import de.gultsch.chat.ui.EditAccount.EditAccountListener;
-import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -25,28 +24,72 @@ import android.widget.TextView;
public class ManageAccountActivity extends XmppActivity {
-
protected List<Account> accountList = new ArrayList<Account>();
protected ListView accountListView;
protected ArrayAdapter<Account> accountListViewAdapter;
-
+ protected OnAccountListChangedListener accountChanged = new OnAccountListChangedListener() {
+
+ @Override
+ public void onAccountListChangedListener() {
+ Log.d("xmppService", "ui on account list changed listener");
+ accountList.clear();
+ accountList.addAll(xmppConnectionService.getAccounts());
+ runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ if (accountList.size() == 1) {
+ startActivity(new Intent(getApplicationContext(),
+ NewConversationActivity.class));
+ }
+ accountListViewAdapter.notifyDataSetChanged();
+ }
+ });
+ }
+ };
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.manage_accounts);
-
+
accountListView = (ListView) findViewById(R.id.account_list);
- accountListViewAdapter = new ArrayAdapter<Account>(getApplicationContext(), R.layout.account_row, this.accountList) {
+ accountListViewAdapter = new ArrayAdapter<Account>(
+ getApplicationContext(), R.layout.account_row, this.accountList) {
@Override
public View getView(int position, View view, ViewGroup parent) {
+ Account account = getItem(position);
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = (View) inflater.inflate(R.layout.account_row, null);
}
- ((TextView) view.findViewById(R.id.account_jid)).setText(getItem(position).getJid());
-
+ ((TextView) view.findViewById(R.id.account_jid))
+ .setText(account.getJid());
+ TextView statusView = (TextView) view
+ .findViewById(R.id.account_status);
+ switch (account.getStatus()) {
+ case Account.STATUS_ONLINE:
+ statusView.setText("online");
+ statusView.setTextColor(0xFF83b600);
+ break;
+ case Account.STATUS_OFFLINE:
+ statusView.setText("offline");
+ statusView.setTextColor(0xFFe92727);
+ break;
+ case Account.STATUS_UNAUTHORIZED:
+ statusView.setText("unauthorized");
+ statusView.setTextColor(0xFFe92727);
+ break;
+ case Account.STATUS_SERVER_NOT_FOUND:
+ statusView.setText("server not found");
+ statusView.setTextColor(0xFFe92727);
+ break;
+ default:
+ break;
+ }
+
return view;
}
};
@@ -54,12 +97,12 @@ public class ManageAccountActivity extends XmppActivity {
accountListView.setOnItemClickListener(new OnItemClickListener() {
@Override
- public void onItemClick(AdapterView<?> arg0, View view, int position,
- long arg3) {
+ public void onItemClick(AdapterView<?> arg0, View view,
+ int position, long arg3) {
EditAccount dialog = new EditAccount();
dialog.setAccount(accountList.get(position));
dialog.setEditAccountListener(new EditAccountListener() {
-
+
@Override
public void onAccountEdited(Account account) {
xmppConnectionService.updateAccount(account);
@@ -67,41 +110,27 @@ public class ManageAccountActivity extends XmppActivity {
@Override
public void onAccountDelete(Account account) {
-
- Log.d("gultsch","deleting account:"+account.getJid());
-
xmppConnectionService.deleteAccount(account);
-
- //dont bother finding the right account in the frontend list. just reload
- accountList.clear();
- accountList.addAll(xmppConnectionService.getAccounts());
-
- accountListViewAdapter.notifyDataSetChanged();
-
}
});
- dialog.show(getFragmentManager(),"edit_account");
+ dialog.show(getFragmentManager(), "edit_account");
}
});
}
@Override
- public void onStart() {
- super.onStart();
+ protected void onStop() {
+ super.onStop();
if (xmppConnectionServiceBound) {
- this.accountList.clear();
- this.accountList.addAll(xmppConnectionService
- .getAccounts());
- accountListViewAdapter.notifyDataSetChanged();
- if (this.accountList.size() == 0) {
- getActionBar().setDisplayHomeAsUpEnabled(false);
- }
+ xmppConnectionService.removeOnAccountListChangedListener();
+ unbindService(mConnection);
+ xmppConnectionServiceBound = false;
}
}
-
+
@Override
void onBackendConnected() {
- Log.d("gultsch","called on backend connected");
+ xmppConnectionService.setOnAccountListChangedListener(accountChanged);
this.accountList.clear();
this.accountList.addAll(xmppConnectionService.getAccounts());
accountListViewAdapter.notifyDataSetChanged();
@@ -110,14 +139,14 @@ public class ManageAccountActivity extends XmppActivity {
addAccount();
}
}
-
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.manageaccounts, menu);
return true;
}
-
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -137,23 +166,18 @@ public class ManageAccountActivity extends XmppActivity {
final Activity activity = this;
EditAccount dialog = new EditAccount();
dialog.setEditAccountListener(new EditAccountListener() {
-
+
@Override
public void onAccountEdited(Account account) {
xmppConnectionService.createAccount(account);
- accountList.add(account);
- accountListViewAdapter.notifyDataSetChanged();
activity.getActionBar().setDisplayHomeAsUpEnabled(true);
- if (accountList.size() == 1) {
- activity.startActivity(new Intent(activity,NewConversationActivity.class));
- }
}
@Override
public void onAccountDelete(Account account) {
- //this will never be called
+ // this will never be called
}
});
- dialog.show(getFragmentManager(),"add_account");
+ dialog.show(getFragmentManager(), "add_account");
}
}
diff --git a/src/de/gultsch/chat/ui/OnAccountListChangedListener.java b/src/de/gultsch/chat/ui/OnAccountListChangedListener.java
new file mode 100644
index 00000000..4af5ac9b
--- /dev/null
+++ b/src/de/gultsch/chat/ui/OnAccountListChangedListener.java
@@ -0,0 +1,5 @@
+package de.gultsch.chat.ui;
+
+public interface OnAccountListChangedListener {
+ public void onAccountListChangedListener();
+}
diff --git a/src/de/gultsch/chat/xml/TagWriter.java b/src/de/gultsch/chat/xml/TagWriter.java
index 35f27477..401a6eee 100644
--- a/src/de/gultsch/chat/xml/TagWriter.java
+++ b/src/de/gultsch/chat/xml/TagWriter.java
@@ -3,12 +3,37 @@ package de.gultsch.chat.xml;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
import android.util.Log;
public class TagWriter {
- OutputStreamWriter writer;
+ private OutputStreamWriter outputStream;
+ private LinkedBlockingQueue<String> writeQueue = new LinkedBlockingQueue<String>();
+ private Thread writer = new Thread() {
+ public boolean shouldStop = false;
+ @Override
+ public void run() {
+ while(!shouldStop) {
+ try {
+ String output = writeQueue.take();
+ outputStream.write(output);
+ outputStream.flush();
+ } catch (IOException e) {
+ Log.d("xmppService", "error writing to stream");
+ } catch (InterruptedException e) {
+
+ }
+ }
+ }
+ };
+
public TagWriter() {
@@ -16,31 +41,29 @@ public class TagWriter {
public TagWriter(OutputStream out) {
this.setOutputStream(out);
+ writer.start();
}
public void setOutputStream(OutputStream out) {
- this.writer = new OutputStreamWriter(out);
+ this.outputStream = new OutputStreamWriter(out);
+ if (!writer.isAlive()) writer.start();
}
- public TagWriter beginDocument() throws IOException {
- writer.write("<?xml version='1.0'?>");
+ public TagWriter beginDocument() {
+ writeQueue.add("<?xml version='1.0'?>");
return this;
}
- public TagWriter writeTag(Tag tag) throws IOException {
- writer.write(tag.toString());
+ public TagWriter writeTag(Tag tag) {
+ writeQueue.add(tag.toString());
return this;
}
-
- public void flush() throws IOException {
- writer.flush();
- }
- public void writeString(String string) throws IOException {
- writer.write(string);
+ public void writeString(String string) {
+ writeQueue.add(string);
}
- public void writeElement(Element element) throws IOException {
- writer.write(element.toString());
+ public void writeElement(Element element) {
+ writeQueue.add(element.toString());
}
}
diff --git a/src/de/gultsch/chat/xmpp/OnStatusChanged.java b/src/de/gultsch/chat/xmpp/OnStatusChanged.java
new file mode 100644
index 00000000..f79305e3
--- /dev/null
+++ b/src/de/gultsch/chat/xmpp/OnStatusChanged.java
@@ -0,0 +1,7 @@
+package de.gultsch.chat.xmpp;
+
+import de.gultsch.chat.entities.Account;
+
+public interface OnStatusChanged {
+ public void onStatusChanged(Account account);
+}
diff --git a/src/de/gultsch/chat/xmpp/XmppConnection.java b/src/de/gultsch/chat/xmpp/XmppConnection.java
index 1afe5b0c..e86bb66c 100644
--- a/src/de/gultsch/chat/xmpp/XmppConnection.java
+++ b/src/de/gultsch/chat/xmpp/XmppConnection.java
@@ -39,7 +39,7 @@ public class XmppConnection implements Runnable {
private boolean isTlsEncrypted = false;
private boolean isAuthenticated = false;
//private boolean shouldUseTLS = false;
- private boolean shouldReConnect = true;
+ private boolean shouldConnect = true;
private boolean shouldBind = true;
private boolean shouldAuthenticate = true;
private Element streamFeatures;
@@ -52,8 +52,7 @@ public class XmppConnection implements Runnable {
private OnPresencePacketReceived presenceListener = null;
private OnIqPacketReceived unregisteredIqListener = null;
private OnMessagePacketReceived messageListener = null;
-
- private String resource = null;
+ private OnStatusChanged statusListener = null;
public XmppConnection(Account account, PowerManager pm) {
this.account = account;
@@ -66,7 +65,6 @@ public class XmppConnection implements Runnable {
protected void connect() {
try {
socket = new Socket(account.getServer(), 5222);
- Log.d(LOGTAG, "starting new socket");
OutputStream out = socket.getOutputStream();
tagWriter.setOutputStream(out);
InputStream in = socket.getInputStream();
@@ -77,40 +75,54 @@ public class XmppConnection implements Runnable {
while ((nextTag = tagReader.readTag()) != null) {
if (nextTag.isStart("stream")) {
processStream(nextTag);
+ break;
} else {
Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName());
return;
}
}
+ if (socket.isConnected()) {
+ socket.close();
+ }
} catch (UnknownHostException e) {
- Log.d(LOGTAG,account.getJid()+": error during connect. unknown host");
+ account.setStatus(Account.STATUS_SERVER_NOT_FOUND);
return;
} catch (IOException e) {
- Log.d(LOGTAG, account.getJid()+": error during connect. io exception. falscher port?");
- return;
+ if (shouldConnect) {
+ Log.d(LOGTAG,account.getJid()+": connection lost");
+ account.setStatus(Account.STATUS_OFFLINE);
+ if (statusListener!=null) {
+ statusListener.onStatusChanged(account);
+ }
+ }
} catch (XmlPullParserException e) {
Log.d(LOGTAG,"xml exception "+e.getMessage());
return;
}
+
}
@Override
public void run() {
- while(shouldReConnect) {
+ shouldConnect = true;
+ while(shouldConnect) {
connect();
try {
- Thread.sleep(30000);
+ if (shouldConnect) {
+ Thread.sleep(30000);
+ }
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
+ Log.d(LOGTAG,"end run");
}
private void processStream(Tag currentTag) throws XmlPullParserException,
IOException {
- Tag nextTag;
- while (!(nextTag = tagReader.readTag()).isEnd("stream")) {
+ Tag nextTag = tagReader.readTag();
+ while ((nextTag != null) && (!nextTag.isEnd("stream"))) {
if (nextTag.isStart("error")) {
processStreamError(nextTag);
} else if (nextTag.isStart("features")) {
@@ -124,6 +136,12 @@ public class XmppConnection implements Runnable {
tagReader.reset();
sendStartStream();
processStream(tagReader.readTag());
+ break;
+ } else if(nextTag.isStart("failure")) {
+ Element failure = tagReader.readElement(nextTag);
+ Log.d(LOGTAG,"read failure element"+failure.toString());
+ account.setStatus(Account.STATUS_UNAUTHORIZED);
+ tagWriter.writeTag(Tag.end("stream"));
} else if (nextTag.isStart("iq")) {
processIq(nextTag);
} else if (nextTag.isStart("message")) {
@@ -134,6 +152,13 @@ public class XmppConnection implements Runnable {
Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName()
+ " as child of " + currentTag.getName());
}
+ nextTag = tagReader.readTag();
+ }
+ if (account.getStatus() == Account.STATUS_ONLINE) {
+ account.setStatus(Account.STATUS_OFFLINE);
+ if (statusListener!=null) {
+ statusListener.onStatusChanged(account);
+ }
}
}
@@ -190,11 +215,11 @@ public class XmppConnection implements Runnable {
}
}
- private void sendStartTLS() throws XmlPullParserException, IOException {
+ private void sendStartTLS() {
Tag startTLS = Tag.empty("starttls");
startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls");
Log.d(LOGTAG,account.getJid()+": sending starttls");
- tagWriter.writeTag(startTLS).flush();
+ tagWriter.writeTag(startTLS);
}
private void switchOverToTls(Tag currentTag) throws XmlPullParserException,
@@ -213,6 +238,7 @@ public class XmppConnection implements Runnable {
isTlsEncrypted = true;
sendStartStream();
processStream(tagReader.readTag());
+ sslSocket.close();
} catch (IOException e) {
Log.d(LOGTAG, account.getJid()+": error on ssl '" + e.getMessage()+"'");
}
@@ -227,7 +253,6 @@ public class XmppConnection implements Runnable {
auth.setContent(saslString);
Log.d(LOGTAG,account.getJid()+": sending sasl "+auth.toString());
tagWriter.writeElement(auth);
- tagWriter.flush();
}
private void processStreamFeatures(Tag currentTag)
@@ -249,12 +274,10 @@ public class XmppConnection implements Runnable {
startSession.addChild(session);
sendIqPacket(startSession, null);
tagWriter.writeElement(startSession);
- tagWriter.flush();
}
Element presence = new Element("presence");
tagWriter.writeElement(presence);
- tagWriter.flush();
}
}
@@ -266,8 +289,12 @@ public class XmppConnection implements Runnable {
this.sendIqPacket(iq, new OnIqPacketReceived() {
@Override
public void onIqPacketReceived(Account account, IqPacket packet) {
- resource = packet.findChild("bind").findChild("jid").getContent().split("/")[1];
- Log.d(LOGTAG,account.getJid()+": new resource is "+resource);
+ String resource = packet.findChild("bind").findChild("jid").getContent().split("/")[1];
+ account.setResource(resource);
+ account.setStatus(Account.STATUS_ONLINE);
+ if (statusListener!=null) {
+ statusListener.onStatusChanged(account);
+ }
}
});
}
@@ -276,7 +303,7 @@ public class XmppConnection implements Runnable {
Log.d(LOGTAG, "processStreamError");
}
- private void sendStartStream() throws IOException {
+ private void sendStartStream() {
Tag stream = Tag.start("stream");
stream.setAttribute("from", account.getJid());
stream.setAttribute("to", account.getServer());
@@ -284,32 +311,29 @@ public class XmppConnection implements Runnable {
stream.setAttribute("xml:lang", "en");
stream.setAttribute("xmlns", "jabber:client");
stream.setAttribute("xmlns:stream", "http://etherx.jabber.org/streams");
- tagWriter.writeTag(stream).flush();
+ tagWriter.writeTag(stream);
}
private String nextRandomId() {
return new BigInteger(50, random).toString(32);
}
- public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) throws IOException {
+ public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) {
String id = nextRandomId();
packet.setAttribute("id",id);
tagWriter.writeElement(packet);
if (callback != null) {
iqPacketCallbacks.put(id, callback);
}
- tagWriter.flush();
Log.d(LOGTAG,account.getJid()+": sending: "+packet.toString());
}
- public void sendMessagePacket(MessagePacket packet) throws IOException {
+ public void sendMessagePacket(MessagePacket packet){
tagWriter.writeElement(packet);
- tagWriter.flush();
}
- public void sendPresencePacket(PresencePacket packet) throws IOException {
+ public void sendPresencePacket(PresencePacket packet) {
tagWriter.writeElement(packet);
- tagWriter.flush();
}
public void setOnMessagePacketReceivedListener(OnMessagePacketReceived listener) {
@@ -323,4 +347,13 @@ public class XmppConnection implements Runnable {
public void setOnPresencePacketReceivedListener(OnPresencePacketReceived listener) {
this.presenceListener = listener;
}
+
+ public void setOnStatusChangedListener(OnStatusChanged listener) {
+ this.statusListener = listener;
+ }
+
+ public void disconnect() {
+ shouldConnect = false;
+ tagWriter.writeTag(Tag.end("stream"));
+ }
}