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 |
} |