Use AlarmManager to schedule an IDLE connection restart.
We also want to restart it during sleep. Change-Id: Ib2c26e06fb923487b10d94edc1bbd743ebb39fb1
This commit is contained in:
parent
739281a727
commit
a7bc7d8572
@ -113,6 +113,10 @@ public class ImapService extends Service {
|
|||||||
private static final int KICK_IDLE_CONNECTION_MAX_DELAY = 3 * 60 * 1000;
|
private static final int KICK_IDLE_CONNECTION_MAX_DELAY = 3 * 60 * 1000;
|
||||||
private static final int ALARM_REQUEST_KICK_IDLE_CODE = 1000;
|
private static final int ALARM_REQUEST_KICK_IDLE_CODE = 1000;
|
||||||
|
|
||||||
|
// Restart idle connection between 30 seconds and 1 minute after re-gaining connectivity
|
||||||
|
private static final int RESTART_IDLE_DELAY_MIN = 30 * 1000;
|
||||||
|
private static final int RESTART_IDLE_DELAY_MAX = 60 * 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple cache for last search result mailbox by account and serverId, since the most common
|
* Simple cache for last search result mailbox by account and serverId, since the most common
|
||||||
* case will be repeated use of the same mailbox
|
* case will be repeated use of the same mailbox
|
||||||
@ -149,6 +153,8 @@ public class ImapService extends Service {
|
|||||||
private static final String EXTRA_MESSAGE_ID = "org.codeaurora.email.intent.extra.MESSAGE_ID";
|
private static final String EXTRA_MESSAGE_ID = "org.codeaurora.email.intent.extra.MESSAGE_ID";
|
||||||
private static final String EXTRA_MESSAGE_INFO =
|
private static final String EXTRA_MESSAGE_INFO =
|
||||||
"org.codeaurora.email.intent.extra.MESSAGE_INFO";
|
"org.codeaurora.email.intent.extra.MESSAGE_INFO";
|
||||||
|
private static final String ACTION_RESTART_IDLE_CONNECTION =
|
||||||
|
"com.android.email.intent.action.RESTART_IDLE_CONNECTION";
|
||||||
private static final String ACTION_KICK_IDLE_CONNECTION =
|
private static final String ACTION_KICK_IDLE_CONNECTION =
|
||||||
"com.android.email.intent.action.KICK_IDLE_CONNECTION";
|
"com.android.email.intent.action.KICK_IDLE_CONNECTION";
|
||||||
private static final String EXTRA_MAILBOX = "com.android.email.intent.extra.MAILBOX";
|
private static final String EXTRA_MAILBOX = "com.android.email.intent.extra.MAILBOX";
|
||||||
@ -539,85 +545,50 @@ public class ImapService extends Service {
|
|||||||
|
|
||||||
private static class ImapEmailConnectivityManager extends EmailConnectivityManager {
|
private static class ImapEmailConnectivityManager extends EmailConnectivityManager {
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final Handler mHandler;
|
|
||||||
private final IEmailService mService;
|
|
||||||
|
|
||||||
private final Runnable mRegisterIdledFolderRunnable = new Runnable() {
|
public ImapEmailConnectivityManager(Context context) {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
sExecutor.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Initiate a sync for all IDLEd accounts, since there might have
|
|
||||||
// been changes while we lost connectivity. At the end of the sync
|
|
||||||
// the IDLE connection will be re-established.
|
|
||||||
ContentResolver cr = mContext.getContentResolver();
|
|
||||||
Cursor c = cr.query(Account.CONTENT_URI,
|
|
||||||
Account.CONTENT_PROJECTION, null, null, null);
|
|
||||||
if (c != null) {
|
|
||||||
try {
|
|
||||||
while (c.moveToNext()) {
|
|
||||||
final Account account = new Account();
|
|
||||||
account.restore(c);
|
|
||||||
|
|
||||||
// Only imap push accounts
|
|
||||||
if (account.getSyncInterval() != Account.CHECK_INTERVAL_PUSH) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!isLegacyImapProtocol(mContext, account)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request a "recents" sync
|
|
||||||
ImapService.requestSync(mContext,
|
|
||||||
account, Mailbox.NO_MAILBOX, false);
|
|
||||||
LogUtils.d(LOG_TAG, "requestSync after restarting IDLE "
|
|
||||||
+ "for account %s", account.toString());
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public ImapEmailConnectivityManager(Context context, IEmailService service) {
|
|
||||||
super(context, LOG_TAG);
|
super(context, LOG_TAG);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mHandler = new Handler();
|
|
||||||
mService = service;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectivityRestored(int networkType) {
|
public void onConnectivityRestored(int networkType) {
|
||||||
// Restore idled folders. Execute in background
|
|
||||||
if (Logging.LOGD) {
|
if (Logging.LOGD) {
|
||||||
LogUtils.d(Logging.LOG_TAG, "onConnectivityRestored ("
|
LogUtils.d(Logging.LOG_TAG, "onConnectivityRestored ("
|
||||||
+ "networkType=" + networkType + ")");
|
+ "networkType=" + networkType + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hold the register a bit to trying to avoid unstable networking
|
scheduleIdleConnectionRestart();
|
||||||
mHandler.removeCallbacks(mRegisterIdledFolderRunnable);
|
|
||||||
mHandler.postDelayed(mRegisterIdledFolderRunnable, 10000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectivityLost(int networkType) {
|
public void onConnectivityLost(int networkType) {
|
||||||
// Unlink idled folders. Execute in background
|
|
||||||
if (Logging.LOGD) {
|
if (Logging.LOGD) {
|
||||||
LogUtils.d(Logging.LOG_TAG, "onConnectivityLost ("
|
LogUtils.d(Logging.LOG_TAG, "onConnectivityLost ("
|
||||||
+ "networkType=" + networkType + ")");
|
+ "networkType=" + networkType + ")");
|
||||||
}
|
}
|
||||||
sExecutor.execute(new Runnable() {
|
// Only remove references. We have no network to kill idled connections
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Only remove references. We have no network to kill idled
|
|
||||||
// connections
|
|
||||||
ImapIdleFolderHolder.getInstance().unregisterAllIdledMailboxes(false);
|
ImapIdleFolderHolder.getInstance().unregisterAllIdledMailboxes(false);
|
||||||
|
cancelIdleConnectionRestart();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
private void scheduleIdleConnectionRestart() {
|
||||||
|
PendingIntent pi = getIdleConnectionRestartIntent();
|
||||||
|
long due = SystemClock.elapsedRealtime() + RESTART_IDLE_DELAY_MIN;
|
||||||
|
long windowLength = RESTART_IDLE_DELAY_MAX - RESTART_IDLE_DELAY_MIN;
|
||||||
|
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
am.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, due, windowLength, pi);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelIdleConnectionRestart() {
|
||||||
|
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
am.cancel(getIdleConnectionRestartIntent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingIntent getIdleConnectionRestartIntent() {
|
||||||
|
Intent i = new Intent(mContext, ImapService.class);
|
||||||
|
i.setAction(ACTION_RESTART_IDLE_CONNECTION);
|
||||||
|
return PendingIntent.getService(mContext, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,7 +755,7 @@ public class ImapService extends Service {
|
|||||||
|
|
||||||
// Initialize the email provider and the listeners/observers
|
// Initialize the email provider and the listeners/observers
|
||||||
EmailContent.init(this);
|
EmailContent.init(this);
|
||||||
mConnectivityManager = new ImapEmailConnectivityManager(this, mBinder);
|
mConnectivityManager = new ImapEmailConnectivityManager(this);
|
||||||
mLocalChangesObserver = new LocalChangesContentObserver(this, mServiceHandler);
|
mLocalChangesObserver = new LocalChangesContentObserver(this, mServiceHandler);
|
||||||
|
|
||||||
// Initialize wake locks
|
// Initialize wake locks
|
||||||
@ -927,6 +898,45 @@ public class ImapService extends Service {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtils.e(Logging.LOG_TAG, "RemoteException " + e);
|
LogUtils.e(Logging.LOG_TAG, "RemoteException " + e);
|
||||||
}
|
}
|
||||||
|
} else if (ACTION_RESTART_IDLE_CONNECTION.equals(action)) {
|
||||||
|
// Initiate a sync for all IDLEd accounts, since there might have
|
||||||
|
// been changes while we lost connectivity. At the end of the sync
|
||||||
|
// the IDLE connection will be re-established.
|
||||||
|
|
||||||
|
mIdleRefreshWakeLock.acquire();
|
||||||
|
|
||||||
|
sExecutor.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ContentResolver cr = context.getContentResolver();
|
||||||
|
Cursor c = null;
|
||||||
|
try {
|
||||||
|
c = cr.query(Account.CONTENT_URI, Account.CONTENT_PROJECTION,
|
||||||
|
null, null, null);
|
||||||
|
if (c == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
final Account account = new Account();
|
||||||
|
account.restore(c);
|
||||||
|
|
||||||
|
// Only imap push accounts
|
||||||
|
if (account.getSyncInterval() == Account.CHECK_INTERVAL_PUSH
|
||||||
|
&& isLegacyImapProtocol(context, account)) {
|
||||||
|
// Request a "recents" sync
|
||||||
|
requestSync(context, account, Mailbox.NO_MAILBOX, false);
|
||||||
|
LogUtils.d(LOG_TAG, "requestSync after restarting IDLE "
|
||||||
|
+ "for account %s", account.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (c != null) {
|
||||||
|
c.close();
|
||||||
|
}
|
||||||
|
mIdleRefreshWakeLock.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
} else if (ACTION_KICK_IDLE_CONNECTION.equals(action)) {
|
} else if (ACTION_KICK_IDLE_CONNECTION.equals(action)) {
|
||||||
if (Logging.LOGD) {
|
if (Logging.LOGD) {
|
||||||
LogUtils.d(Logging.LOG_TAG, "action: Send Pending Mail "+accountId);
|
LogUtils.d(Logging.LOG_TAG, "action: Send Pending Mail "+accountId);
|
||||||
|
Loading…
Reference in New Issue
Block a user