1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.exchange.service; 18 19 import android.content.AbstractThreadedSyncAdapter; 20 import android.content.ContentProviderClient; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.SyncResult; 24 import android.os.Bundle; 25 import android.os.IBinder; 26 import android.os.RemoteException; 27 import android.text.format.DateUtils; 28 import android.util.Log; 29 30 import com.android.emailcommon.provider.Account; 31 import com.android.emailcommon.provider.Mailbox; 32 import com.android.emailcommon.service.EmailServiceStatus; 33 import com.android.emailcommon.service.IEmailService; 34 import com.android.exchange.Eas; 35 import com.android.mail.utils.LogUtils; 36 37 public class EmailSyncAdapterService extends AbstractSyncAdapterService { 38 39 private static final String TAG = Eas.LOG_TAG; 40 41 private static final Object sSyncAdapterLock = new Object(); 42 private static AbstractThreadedSyncAdapter sSyncAdapter = null; 43 EmailSyncAdapterService()44 public EmailSyncAdapterService() { 45 super(); 46 } 47 48 @Override onCreate()49 public void onCreate() { 50 LogUtils.v(TAG, "EmailSyncAdapterService.onCreate()"); 51 super.onCreate(); 52 startService(new Intent(this, EmailSyncAdapterService.class)); 53 } 54 55 @Override onDestroy()56 public void onDestroy() { 57 LogUtils.v(TAG, "EmailSyncAdapterService.onDestroy()"); 58 super.onDestroy(); 59 } 60 61 @Override onBind(Intent intent)62 public IBinder onBind(Intent intent) { 63 return super.onBind(intent); 64 } 65 66 @Override getSyncAdapter()67 protected AbstractThreadedSyncAdapter getSyncAdapter() { 68 synchronized (sSyncAdapterLock) { 69 if (sSyncAdapter == null) { 70 sSyncAdapter = new SyncAdapterImpl(this); 71 } 72 return sSyncAdapter; 73 } 74 } 75 76 // TODO: Handle cancelSync() appropriately. 77 private class SyncAdapterImpl extends AbstractThreadedSyncAdapter { SyncAdapterImpl(Context context)78 public SyncAdapterImpl(Context context) { 79 super(context, true /* autoInitialize */); 80 } 81 82 @Override onPerformSync(final android.accounts.Account acct, final Bundle extras, final String authority, final ContentProviderClient provider, final SyncResult syncResult)83 public void onPerformSync(final android.accounts.Account acct, final Bundle extras, 84 final String authority, final ContentProviderClient provider, 85 final SyncResult syncResult) { 86 if (LogUtils.isLoggable(TAG, Log.DEBUG)) { 87 LogUtils.d(TAG, "onPerformSync email: %s, %s", acct.toString(), extras.toString()); 88 } else { 89 LogUtils.i(TAG, "onPerformSync email: %s", extras.toString()); 90 } 91 if (!waitForService()) { 92 // The service didn't connect, nothing we can do. 93 return; 94 } 95 96 // TODO: Perform any connectivity checks, bail early if we don't have proper network 97 // for this sync operation. 98 // FLAG: Do we actually need to do this? I don't think the sync manager will invoke 99 // a sync if we don't have good network. 100 101 final Account emailAccount = Account.restoreAccountWithAddress( 102 EmailSyncAdapterService.this, acct.name); 103 if (emailAccount == null) { 104 // There could be a timing issue with onPerformSync() being called and 105 // the account being removed from our database. 106 LogUtils.w(TAG, 107 "onPerformSync() - Could not find an Account, skipping email sync."); 108 return; 109 } 110 111 // Push only means this sync request should only refresh the ping (either because 112 // settings changed, or we need to restart it for some reason). 113 final boolean pushOnly = Mailbox.isPushOnlyExtras(extras); 114 115 if (pushOnly) { 116 LogUtils.d(TAG, "onPerformSync: mailbox push only"); 117 try { 118 mEasService.pushModify(emailAccount.mId); 119 return; 120 } catch (final RemoteException re) { 121 LogUtils.e(TAG, re, "While trying to pushModify within onPerformSync"); 122 // TODO: how to handle this? 123 } 124 return; 125 } else { 126 try { 127 final int result = mEasService.sync(emailAccount.mId, extras); 128 writeResultToSyncResult(result, syncResult); 129 if (syncResult.stats.numAuthExceptions > 0 && 130 result != EmailServiceStatus.PROVISIONING_ERROR) { 131 showAuthNotification(emailAccount.mId, emailAccount.mEmailAddress); 132 } 133 } catch (RemoteException e) { 134 LogUtils.e(TAG, e, "While trying to pushModify within onPerformSync"); 135 } 136 } 137 138 LogUtils.d(TAG, "onPerformSync email: finished"); 139 } 140 } 141 } 142