/** * Informs ExchangeService that an account has a new folder list; as a result, any existing folder * might have become invalid. Therefore, we act as if the account has been deleted, and then we * reinitialize it. * * @param acctId */ public static void stopNonAccountMailboxSyncsForAccount(long acctId) { SyncManager exchangeService = INSTANCE; if (exchangeService != null) { exchangeService.stopAccountSyncs(acctId, false); kick("reload folder list"); } }
/** * Start up the ExchangeService service if it's not already running This is a stopgap for cases in * which ExchangeService died (due to a crash somewhere in com.android.email) and hasn't been * restarted. See the comment for onCreate for details */ static void checkExchangeServiceServiceRunning() { SyncManager exchangeService = INSTANCE; if (exchangeService == null) return; if (sServiceThread == null) { log("!!! checkExchangeServiceServiceRunning; starting service..."); exchangeService.startService(new Intent(exchangeService, ExchangeService.class)); } }
/** * This is the remote call from the Email app, currently unused. TODO: remove this when it's * been deleted from IEmailService.aidl. */ @Deprecated @Override public void startSync(long mailboxId, boolean userRequest, int deltaMessageCount) throws RemoteException { SyncManager exchangeService = INSTANCE; if (exchangeService == null) return; checkExchangeServiceServiceRunning(); Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId); if (m == null) return; Account acct = Account.restoreAccountWithId(exchangeService, m.mAccountKey); if (acct == null) return; // If this is a user request and we're being held, release the hold; this allows us to // try again (the hold might have been specific to this account and released already) if (userRequest) { if (onSyncDisabledHold(acct)) { releaseSyncHolds(exchangeService, AbstractSyncService.EXIT_ACCESS_DENIED, acct); log("User requested sync of account in sync disabled hold; releasing"); } else if (onSecurityHold(acct)) { releaseSyncHolds(exchangeService, AbstractSyncService.EXIT_SECURITY_FAILURE, acct); log("User requested sync of account in security hold; releasing"); } if (sConnectivityHold) { return; } } if (m.mType == Mailbox.TYPE_OUTBOX) { // We're using SERVER_ID to indicate an error condition (it has no other use for // sent mail) Upon request to sync the Outbox, we clear this so that all messages // are candidates for sending. ContentValues cv = new ContentValues(); cv.put(SyncColumns.SERVER_ID, 0); exchangeService .getContentResolver() .update( Message.CONTENT_URI, cv, WHERE_MAILBOX_KEY, new String[] {Long.toString(mailboxId)}); // Clear the error state; the Outbox sync will be started from checkMailboxes exchangeService.mSyncErrorMap.remove(mailboxId); kick("start outbox"); // Outbox can't be synced in EAS return; } else if (!isSyncable(m)) { return; } startManualSync( mailboxId, userRequest ? ExchangeService.SYNC_UI_REQUEST : ExchangeService.SYNC_SERVICE_START_SYNC, null); }
@Override public void hostChanged(long accountId) throws RemoteException { SyncManager exchangeService = INSTANCE; if (exchangeService == null) return; ConcurrentHashMap<Long, SyncError> syncErrorMap = exchangeService.mSyncErrorMap; // Go through the various error mailboxes for (long mailboxId : syncErrorMap.keySet()) { SyncError error = syncErrorMap.get(mailboxId); // If it's a login failure, look a little harder Mailbox m = Mailbox.restoreMailboxWithId(exchangeService, mailboxId); // If it's for the account whose host has changed, clear the error // If the mailbox is no longer around, remove the entry in the map if (m == null) { syncErrorMap.remove(mailboxId); } else if (error != null && m.mAccountKey == accountId) { error.fatal = false; error.holdEndTime = 0; } } // Stop any running syncs exchangeService.stopAccountSyncs(accountId, true); // Kick ExchangeService kick("host changed"); }
public static void reloadFolderList(Context context, long accountId, boolean force) { SyncManager exchangeService = INSTANCE; if (exchangeService == null) return; Cursor c = context .getContentResolver() .query( Mailbox.CONTENT_URI, Mailbox.CONTENT_PROJECTION, MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.TYPE + "=?", new String[] { Long.toString(accountId), Long.toString(Mailbox.TYPE_EAS_ACCOUNT_MAILBOX) }, null); try { if (c.moveToFirst()) { synchronized (sSyncLock) { Mailbox mailbox = new Mailbox(); mailbox.restore(c); Account acct = Account.restoreAccountWithId(context, accountId); if (acct == null) { reloadFolderListFailed(accountId); return; } String syncKey = acct.mSyncKey; // No need to reload the list if we don't have one if (!force && (syncKey == null || syncKey.equals("0"))) { reloadFolderListFailed(accountId); return; } // Change all ping/push boxes to push/hold ContentValues cv = new ContentValues(); cv.put(Mailbox.SYNC_INTERVAL, Mailbox.CHECK_INTERVAL_PUSH_HOLD); context .getContentResolver() .update( Mailbox.CONTENT_URI, cv, WHERE_PUSH_OR_PING_NOT_ACCOUNT_MAILBOX, new String[] {Long.toString(accountId)}); log("Set push/ping boxes to push/hold"); long id = mailbox.mId; AbstractSyncService svc = exchangeService.mServiceMap.get(id); // Tell the service we're done if (svc != null) { synchronized (svc.getSynchronizer()) { svc.stop(); // Interrupt the thread so that it can stop Thread thread = svc.mThread; if (thread != null) { thread.setName(thread.getName() + " (Stopped)"); thread.interrupt(); } } // Abandon the service exchangeService.releaseMailbox(id); // And have it start naturally kick("reload folder list"); } } } } finally { c.close(); } }