diff options
Diffstat (limited to 'provider_src/com/android/email/service/LegacyImapSyncAdapterService.java')
-rw-r--r-- | provider_src/com/android/email/service/LegacyImapSyncAdapterService.java | 136 |
1 files changed, 135 insertions, 1 deletions
diff --git a/provider_src/com/android/email/service/LegacyImapSyncAdapterService.java b/provider_src/com/android/email/service/LegacyImapSyncAdapterService.java index 1f6b6195e..1b5a36b61 100644 --- a/provider_src/com/android/email/service/LegacyImapSyncAdapterService.java +++ b/provider_src/com/android/email/service/LegacyImapSyncAdapterService.java @@ -16,5 +16,139 @@ package com.android.email.service; +import static com.android.emailcommon.Logging.LOG_TAG; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import android.content.AbstractThreadedSyncAdapter; +import android.content.ComponentName; +import android.content.ContentProviderClient; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.SyncResult; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.IBinder; +import android.os.PowerManager; +import android.text.format.DateUtils; + +import com.android.emailcommon.Logging; +import com.android.emailcommon.provider.Mailbox; +import com.android.emailcommon.service.IEmailService; +import com.android.mail.utils.LogUtils; + public class LegacyImapSyncAdapterService extends PopImapSyncAdapterService { -}
\ No newline at end of file + + // The call to ServiceConnection.onServiceConnected is asynchronous to bindService. It's + // possible for that to be delayed if, in which case, a call to onPerformSync + // could occur before we have a connection to the service. + // In onPerformSync, if we don't yet have our ImapService, we will wait for up to 10 + // seconds for it to appear. If it takes longer than that, we will fail the sync. + private static final long MAX_WAIT_FOR_SERVICE_MS = 10 * DateUtils.SECOND_IN_MILLIS; + + private static final ExecutorService sExecutor = Executors.newCachedThreadPool(); + + private IEmailService mImapService; + + private final ServiceConnection mConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder binder) { + if (Logging.LOGD) { + LogUtils.v(LOG_TAG, "onServiceConnected"); + } + synchronized (mConnection) { + mImapService = IEmailService.Stub.asInterface(binder); + mConnection.notify(); + + // We need to run this task in the background (not in UI-Thread) + sExecutor.execute(new Runnable() { + @Override + public void run() { + final Context context = LegacyImapSyncAdapterService.this; + ImapService.registerAllImapIdleMailboxes(context, mImapService); + } + }); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + mImapService = null; + } + }; + + protected class ImapSyncAdapterImpl extends SyncAdapterImpl { + public ImapSyncAdapterImpl(Context context) { + super(context); + } + + @Override + public void onPerformSync(android.accounts.Account account, Bundle extras, + String authority, ContentProviderClient provider, SyncResult syncResult) { + + final Context context = LegacyImapSyncAdapterService.this; + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + "Imap Sync WakeLock"); + try { + wl.acquire(); + + if (!waitForService()) { + // The service didn't connect, nothing we can do. + return; + } + + if (!Mailbox.isPushOnlyExtras(extras)) { + super.onPerformSync(account, extras, authority, provider, syncResult); + } + + // Check if IMAP push service is necessary + ImapService.stopImapPushServiceIfNecessary(context); + + } finally { + wl.release(); + } + } + } + + public AbstractThreadedSyncAdapter getSyncAdapter() { + return new ImapSyncAdapterImpl(getApplicationContext()); + } + + @Override + public void onCreate() { + super.onCreate(); + bindService(new Intent(this, ImapService.class), mConnection, Context.BIND_AUTO_CREATE); + startService(new Intent(this, LegacyImapSyncAdapterService.class)); + } + + @Override + public void onDestroy() { + unbindService(mConnection); + super.onDestroy(); + } + + private final boolean waitForService() { + synchronized(mConnection) { + if (mImapService == null) { + if (Logging.LOGD) { + LogUtils.v(LOG_TAG, "ImapService not yet connected"); + } + try { + mConnection.wait(MAX_WAIT_FOR_SERVICE_MS); + } catch (InterruptedException e) { + LogUtils.wtf(LOG_TAG, "InterrupedException waiting for ImapService to connect"); + return false; + } + if (mImapService == null) { + LogUtils.wtf(LOG_TAG, "timed out waiting for ImapService to connect"); + return false; + } + } + } + return true; + } + +} |