Feature #259 » reconnection-727.patch
src/com/beem/project/beem/BeemService.java Sun Apr 11 19:34:31 2010 +0200 → src/com/beem/project/beem/BeemService.java Mon Apr 19 23:07:26 2010 +0200 | ||
---|---|---|
43 | 43 |
*/ |
44 | 44 |
package com.beem.project.beem; |
45 | 45 | |
46 |
import org.jivesoftware.smack.ReconnectionManager; |
|
46 | 47 |
import org.jivesoftware.smack.ConnectionConfiguration; |
47 | 48 |
import org.jivesoftware.smack.Roster; |
48 | 49 |
import org.jivesoftware.smack.XMPPConnection; |
... | ... | |
109 | 110 | |
110 | 111 |
private boolean mOnOffReceiverIsRegistered; |
111 | 112 | |
113 |
static { |
|
114 |
try { |
|
115 |
// This is a hack. |
|
116 |
// |
|
117 |
// Force the ReconnectionManager class to be loaded, thereby forcing |
|
118 |
// its static initialization block to execute. |
|
119 |
// |
|
120 |
// ReconnectionManager is responsible for reconnecting broken |
|
121 |
// connections. It works by adding a ConnectionCreationListener in |
|
122 |
// its static initialization block. By loading the class, we force |
|
123 |
// its static initialization block to execute. Simply importing the |
|
124 |
// class is not sufficient. |
|
125 |
Class.forName("org.jivesoftware.smack.ReconnectionManager"); |
|
126 |
} catch (ClassNotFoundException ex) { |
|
127 |
Log.w("Can't load ReconnectionManager", ex); |
|
128 |
} |
|
129 |
} |
|
130 | ||
112 | 131 |
/** |
113 | 132 |
* Constructor. |
114 | 133 |
*/ |
... | ... | |
162 | 181 |
@Override |
163 | 182 |
public boolean onUnbind(Intent intent) { |
164 | 183 |
Log.d(TAG, "ONUNBIND()"); |
165 |
if (!mConnection.getAdaptee().isConnected()) { |
|
166 |
Log.d(TAG, "DESTROYED"); |
|
167 |
this.stopSelf(); |
|
168 |
} |
|
169 | 184 |
return true; |
170 | 185 |
} |
171 | 186 | |
172 | ||
173 | ||
174 | 187 |
/** |
175 | 188 |
* {@inheritDoc} |
176 | 189 |
*/ |
src/com/beem/project/beem/service/LoginAsyncTask.java Sun Apr 11 19:34:31 2010 +0200 → src/com/beem/project/beem/service/LoginAsyncTask.java Mon Apr 19 23:07:26 2010 +0200 | ||
---|---|---|
48 | 48 |
import android.util.Log; |
49 | 49 |
import com.beem.project.beem.service.aidl.IXmppConnection; |
50 | 50 |
import com.beem.project.beem.service.aidl.IXmppFacade; |
51 |
import com.beem.project.beem.service.aidl.IBeemConnectionListener; |
|
51 | 52 | |
52 | 53 |
/** |
53 | 54 |
* This is an asynchronous task that will launch a connection to the XMPP server. |
... | ... | |
85 | 86 |
} |
86 | 87 | |
87 | 88 |
@Override |
88 |
protected Boolean doInBackground(IXmppFacade... params) { |
|
89 |
boolean result = true; |
|
90 |
IXmppFacade facade = params[0]; |
|
91 |
try { |
|
92 |
publishProgress(STATE_CONNECTION_RUNNING); |
|
93 |
mConnection = facade.createConnection(); |
|
94 |
if (!mConnection.connect()) { |
|
95 |
mErrorMessage = mConnection.getErrorMessage(); |
|
96 |
return false; |
|
89 |
protected Boolean doInBackground(IXmppFacade... params) { |
|
90 |
boolean result = true; |
|
91 |
IXmppFacade facade = params[0]; |
|
92 |
try { |
|
93 |
publishProgress(STATE_CONNECTION_RUNNING); |
|
94 |
mConnection = facade.createConnection(); |
|
95 |
if (!mConnection.isReconnecting()) { |
|
96 |
if (!mConnection.connect()) { |
|
97 |
mErrorMessage = mConnection.getErrorMessage(); |
|
98 |
return false; |
|
99 |
} |
|
100 |
publishProgress(STATE_LOGIN_RUNNING); |
|
101 | ||
102 |
if (!mConnection.login()) { |
|
103 |
mErrorMessage = mConnection.getErrorMessage(); |
|
104 |
publishProgress(STATE_LOGIN_FAILED); |
|
105 |
return false; |
|
106 |
} |
|
107 |
} else { |
|
108 |
// snif |
|
109 |
while (mConnection.isReconnecting()) |
|
110 |
Thread.sleep(1000); |
|
111 |
} |
|
112 |
publishProgress(STATE_LOGIN_SUCCESS); |
|
113 |
} catch (RemoteException e) { |
|
114 |
mErrorMessage = "Exception during connection :" + e; |
|
115 |
result = false; |
|
116 |
} catch (InterruptedException e) { |
|
117 |
mErrorMessage = "Exception during connection :" + e; |
|
118 |
result = false; |
|
97 | 119 |
} |
98 |
publishProgress(STATE_LOGIN_RUNNING); |
|
99 | ||
100 |
if (!mConnection.login()) { |
|
101 |
mErrorMessage = mConnection.getErrorMessage(); |
|
102 |
publishProgress(STATE_LOGIN_FAILED); |
|
103 |
return false; |
|
104 |
} |
|
105 |
publishProgress(STATE_LOGIN_SUCCESS); |
|
106 |
} catch (RemoteException e) { |
|
107 |
mErrorMessage = "Exception during connection :" + e; |
|
108 |
result = false; |
|
120 |
return result; |
|
109 | 121 |
} |
110 |
return result; |
|
111 |
} |
|
112 | 122 | |
113 | 123 |
/** |
114 | 124 |
* Make sur to call the parent method when overriding this method. |
... | ... | |
131 | 141 |
public String getErrorMessage() { |
132 | 142 |
return mErrorMessage; |
133 | 143 |
} |
144 | ||
134 | 145 |
} |
src/com/beem/project/beem/service/XmppConnectionAdapter.java Sun Apr 11 19:34:31 2010 +0200 → src/com/beem/project/beem/service/XmppConnectionAdapter.java Mon Apr 19 23:07:26 2010 +0200 | ||
---|---|---|
111 | 111 |
private final SubscribePacketListener mSubscribePacketListener = new SubscribePacketListener(); |
112 | 112 | |
113 | 113 |
private final ConnexionListenerAdapter mConListener = new ConnexionListenerAdapter(); |
114 |
private boolean mIsReconnecting; |
|
114 | 115 | |
115 | 116 |
/** |
116 | 117 |
* Constructor. |
... | ... | |
310 | 311 |
changeStatusAndPriority(status, msg, mPreviousPriority); |
311 | 312 |
} |
312 | 313 | |
314 |
@Override |
|
315 |
public boolean isReconnecting() { |
|
316 |
return mIsReconnecting; |
|
317 |
} |
|
318 | ||
313 | 319 |
/** |
314 | 320 |
* get the previous status. |
315 | 321 |
* @return previous status. |
... | ... | |
468 | 474 |
@Override |
469 | 475 |
public void connectionClosedOnError(Exception exception) { |
470 | 476 |
Log.d(TAG, "connectionClosedOnError"); |
471 |
mRoster = null; |
|
472 | 477 |
Intent intent = new Intent(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED); |
473 | 478 |
intent.putExtra("message", exception.getMessage()); |
474 | 479 |
mService.sendBroadcast(intent); |
475 |
mService.stopSelf(); |
|
476 |
mApplication.setConnected(false); |
|
477 |
} |
|
478 | ||
479 |
/** |
|
480 |
* Connection failed callback. |
|
481 |
* @param errorMsg smack failure message |
|
482 |
*/ |
|
483 |
public void connectionFailed(String errorMsg) { |
|
484 |
Log.d(TAG, "Connection Failed"); |
|
485 |
final int n = mRemoteConnListeners.beginBroadcast(); |
|
486 | ||
487 |
for (int i = 0; i < n; i++) { |
|
488 |
IBeemConnectionListener listener = mRemoteConnListeners.getBroadcastItem(i); |
|
489 |
try { |
|
490 |
if (listener != null) |
|
491 |
listener.connectionFailed(errorMsg); |
|
492 |
} catch (RemoteException e) { |
|
493 |
// The RemoteCallbackList will take care of removing the |
|
494 |
// dead listeners. |
|
495 |
Log.w(TAG, "Error while triggering remote connection listeners", e); |
|
496 |
} |
|
497 |
} |
|
498 |
mRemoteConnListeners.finishBroadcast(); |
|
499 |
mService.stopSelf(); |
|
480 |
// mService.stopSelf(); |
|
500 | 481 |
mApplication.setConnected(false); |
501 | 482 |
} |
502 | 483 | |
... | ... | |
506 | 487 |
@Override |
507 | 488 |
public void reconnectingIn(int arg0) { |
508 | 489 |
Log.d(TAG, "reconnectingIn"); |
490 |
mIsReconnecting = true; |
|
509 | 491 |
final int n = mRemoteConnListeners.beginBroadcast(); |
510 | 492 | |
511 | 493 |
for (int i = 0; i < n; i++) { |
... | ... | |
550 | 532 |
@Override |
551 | 533 |
public void reconnectionSuccessful() { |
552 | 534 |
Log.d(TAG, "reconnectionSuccessful"); |
535 |
mIsReconnecting = false; |
|
553 | 536 |
mApplication.setConnected(true); |
554 |
PacketFilter filter = new PacketFilter() { |
|
555 | ||
556 |
@Override |
|
557 |
public boolean accept(Packet packet) { |
|
558 |
if (packet instanceof Presence) { |
|
559 |
Presence pres = (Presence) packet; |
|
560 |
if (pres.getType() == Presence.Type.subscribe) |
|
561 |
return true; |
|
562 |
} |
|
563 |
return false; |
|
564 |
} |
|
565 |
}; |
|
566 | ||
567 |
mAdaptee.addPacketListener(new PacketListener() { |
|
568 | ||
569 |
@Override |
|
570 |
public void processPacket(Packet packet) { |
|
571 |
String from = packet.getFrom(); |
|
572 |
Notification notif = new Notification(android.R.drawable.stat_notify_more, mService.getString( |
|
573 |
R.string.AcceptContactRequest, from), System.currentTimeMillis()); |
|
574 |
notif.defaults = Notification.DEFAULT_ALL; |
|
575 |
notif.flags = Notification.FLAG_AUTO_CANCEL; |
|
576 |
Intent intent = new Intent(mService, Subscription.class); |
|
577 |
intent.putExtra("from", from); |
|
578 |
notif.setLatestEventInfo(mService, from, mService |
|
579 |
.getString(R.string.AcceptContactRequestFrom, from), PendingIntent.getActivity(mService, 0, |
|
580 |
intent, PendingIntent.FLAG_ONE_SHOT)); |
|
581 |
int id = packet.hashCode(); |
|
582 |
mService.sendNotification(id, notif); |
|
583 |
} |
|
584 |
}, filter); |
|
585 | 537 | |
586 | 538 |
final int n = mRemoteConnListeners.beginBroadcast(); |
587 | 539 |
src/com/beem/project/beem/service/aidl/IBeemConnectionListener.aidl Sun Apr 11 19:34:31 2010 +0200 → src/com/beem/project/beem/service/aidl/IBeemConnectionListener.aidl Mon Apr 19 23:07:26 2010 +0200 | ||
---|---|---|
60 | 60 |
*/ |
61 | 61 |
//void onConnect(); |
62 | 62 | |
63 |
//void connectionClosedOnError(in Exception e); |
|
64 | 63 |
/** |
65 | 64 |
* Callback to call when the connection is closed on error |
66 | 65 |
*/ |
... | ... | |
83 | 82 | |
84 | 83 |
/** |
85 | 84 |
* Callback to call when the connection Failed |
85 |
* @deprecated |
|
86 | 86 |
*/ |
87 |
void connectionFailed(in String errorMsg); |
|
87 |
// void connectionFailed(in String errorMsg);
|
|
88 | 88 |
} |
src/com/beem/project/beem/service/aidl/IXmppConnection.aidl Sun Apr 11 19:34:31 2010 +0200 → src/com/beem/project/beem/service/aidl/IXmppConnection.aidl Mon Apr 19 23:07:26 2010 +0200 | ||
---|---|---|
60 | 60 | |
61 | 61 |
boolean disconnect(); |
62 | 62 | |
63 |
boolean isReconnecting(); |
|
64 | ||
63 | 65 |
IRoster getRoster(); |
64 | 66 | |
65 | 67 |
void addConnectionListener(in IBeemConnectionListener listen); |
src/com/beem/project/beem/utils/BeemBroadcastReceiver.java Sun Apr 11 19:34:31 2010 +0200 → src/com/beem/project/beem/utils/BeemBroadcastReceiver.java Mon Apr 19 23:07:26 2010 +0200 | ||
---|---|---|
86 | 86 |
if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)) { |
87 | 87 |
Toast.makeText(context, context.getString(R.string.BeemBroadcastReceiverDisconnect), |
88 | 88 |
Toast.LENGTH_SHORT).show(); |
89 |
context.stopService(new Intent(context, BeemService.class));
|
|
89 |
//TODO stop the connection and relaunch it when the connectivity comes back
|
|
90 | 90 |
} |
91 | 91 |
} |
92 | 92 |
} |