Email split, part trois: AccountService
* Create AccountService.aidl and AccountServiceProxy in emailcommon
* Implement AccountService in email
* Use AccountServiceProxy in Exchange for account reconciliation,
notifications, etc.
* Move sync window constants into emailcommon
* Split attachment provider utilities and constants into emailcommon
Bug: 3442973
Change-Id: I89dce28b799b193243c07774dab65d830ae62775
diff --git a/Android.mk b/Android.mk
index 451c39b..3dd43e7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -21,7 +21,8 @@
LOCAL_SRC_FILES += \
src/com/android/emailcommon/service/IEmailService.aidl \
src/com/android/emailcommon/service/IEmailServiceCallback.aidl \
- src/com/android/emailcommon/service/IPolicyService.aidl
+ src/com/android/emailcommon/service/IPolicyService.aidl \
+ src/com/android/emailcommon/service/IAccountService.aidl
LOCAL_STATIC_JAVA_LIBRARIES := android-common
# Revive this when the app is unbundled.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f8b4b56..3a949df 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -370,6 +370,17 @@
</intent-filter>
</service>
+ <service
+ android:name=".service.AccountService"
+ android:enabled="true"
+ android:permission="com.android.email.permission.ACCESS_PROVIDER"
+ >
+ <intent-filter>
+ <action
+ android:name="com.android.email.ACCOUNT_INTENT" />
+ </intent-filter>
+ </service>
+
<!--EXCHANGE-REMOVE-SECTION-START-->
<!--Required stanza to register the EAS EmailSyncAdapterService with SyncManager -->
<service
diff --git a/src/com/android/exchange/ExchangeService.java b/src/com/android/exchange/ExchangeService.java
index 19bc226..6afcbb8 100644
--- a/src/com/android/exchange/ExchangeService.java
+++ b/src/com/android/exchange/ExchangeService.java
@@ -17,9 +17,7 @@
package com.android.exchange;
-import com.android.email.AccountBackupRestore;
import com.android.email.Email;
-import com.android.email.NotificationController;
import com.android.email.Utility;
import com.android.email.mail.transport.SSLUtils;
import com.android.email.provider.EmailContent;
@@ -32,11 +30,12 @@
import com.android.email.provider.EmailContent.MailboxColumns;
import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.SyncColumns;
-import com.android.email.service.MailService;
import com.android.emailcommon.Api;
+import com.android.emailcommon.service.AccountServiceProxy;
import com.android.emailcommon.service.EmailServiceStatus;
import com.android.emailcommon.service.IEmailService;
import com.android.emailcommon.service.IEmailServiceCallback;
+import com.android.emailcommon.utility.AccountReconciler;
import com.android.exchange.adapter.CalendarSyncAdapter;
import com.android.exchange.adapter.ContactsSyncAdapter;
import com.android.exchange.utility.FileLogger;
@@ -1046,8 +1045,15 @@
// list, which would cause the deletion of all of our accounts
AccountList accountList = collectEasAccounts(context, new AccountList());
alwaysLog("Reconciling accounts...");
- MailService.reconcileAccountsWithAccountManager(context, accountList, accountMgrList,
- false, context.getContentResolver());
+ boolean accountsDeleted = AccountReconciler.reconcileAccounts(context, accountList,
+ accountMgrList, context.getContentResolver());
+ if (accountsDeleted) {
+ try {
+ new AccountServiceProxy(context).accountDeleted();
+ } catch (RemoteException e) {
+ // ?
+ }
+ }
}
public static void log(String str) {
@@ -1749,13 +1755,22 @@
@Override
public void run() {
synchronized (sSyncLock) {
+ // ExchangeService cannot start unless we can connect to AccountService
+ if (!new AccountServiceProxy(ExchangeService.this).test()) {
+ log("!!! Email application not found; stopping self");
+ stopSelf();
+ }
// Restore accounts, if it has not happened already
- AccountBackupRestore.restoreAccountsIfNeeded(ExchangeService.this);
+ try {
+ new AccountServiceProxy(ExchangeService.this).restoreAccountsIfNeeded();
+ } catch (RemoteException e) {
+ // If we can't restore accounts, don't run
+ return;
+ }
// Run the reconciler and clean up any mismatched accounts - if we weren't
// running when accounts were deleted, it won't have been called.
runAccountReconcilerSync(ExchangeService.this);
// Update other services depending on final account configuration
- Email.setServicesEnabledSync(ExchangeService.this);
maybeStartExchangeServiceThread();
if (sServiceThread == null) {
log("!!! EAS ExchangeService, stopping self");
@@ -2385,8 +2400,12 @@
if (account == null) return;
if (exchangeService.releaseSyncHolds(exchangeService,
AbstractSyncService.EXIT_LOGIN_FAILURE, account)) {
- NotificationController.getInstance(exchangeService)
- .cancelLoginFailedNotification(accountId);
+ try {
+ new AccountServiceProxy(exchangeService).notifyLoginSucceeded(
+ accountId);
+ } catch (RemoteException e) {
+ // No harm if the notification fails
+ }
}
}
@@ -2413,8 +2432,11 @@
break;
// These errors are not retried automatically
case AbstractSyncService.EXIT_LOGIN_FAILURE:
- NotificationController.getInstance(exchangeService)
- .showLoginFailedNotification(m.mAccountKey);
+ try {
+ new AccountServiceProxy(exchangeService).notifyLoginFailed(m.mAccountKey);
+ } catch (RemoteException e) {
+ // ? Anything to do?
+ }
// Fall through
case AbstractSyncService.EXIT_SECURITY_FAILURE:
case AbstractSyncService.EXIT_EXCEPTION:
diff --git a/src/com/android/exchange/PolicyServiceDelegate.java b/src/com/android/exchange/PolicyServiceDelegate.java
new file mode 100644
index 0000000..d712c55
--- /dev/null
+++ b/src/com/android/exchange/PolicyServiceDelegate.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.exchange;
+
+import com.android.email.provider.EmailContent.Account;
+import com.android.emailcommon.service.PolicyServiceProxy;
+import com.android.emailcommon.service.PolicySet;
+
+import android.content.Context;
+import android.os.RemoteException;
+
+public class PolicyServiceDelegate {
+
+ public static boolean isActive(Context context, PolicySet policies) {
+ try {
+ return new PolicyServiceProxy(context).isActive(policies);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ public static void policiesRequired(Context context, long accountId) {
+ try {
+ new PolicyServiceProxy(context).policiesRequired(accountId);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("PolicyService transaction failed");
+ }
+ }
+
+ public static void updatePolicies(Context context, long accountId) {
+ try {
+ new PolicyServiceProxy(context).updatePolicies(accountId);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("PolicyService transaction failed");
+ }
+ }
+
+ public static void setAccountHoldFlag(Context context, Account account, boolean newState) {
+ try {
+ new PolicyServiceProxy(context).setAccountHoldFlag(account.mId, newState);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("PolicyService transaction failed");
+ }
+ }
+
+ public static boolean isActiveAdmin(Context context) {
+ try {
+ return new PolicyServiceProxy(context).isActiveAdmin();
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ public static void remoteWipe(Context context) {
+ try {
+ new PolicyServiceProxy(context).remoteWipe();
+ } catch (RemoteException e) {
+ throw new IllegalStateException("PolicyService transaction failed");
+ }
+ }
+
+ public static boolean isSupported(Context context, PolicySet policies) {
+ try {
+ return new PolicyServiceProxy(context).isSupported(policies);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ public static PolicySet clearUnsupportedPolicies(Context context, PolicySet policies) {
+ try {
+ return new PolicyServiceProxy(context).clearUnsupportedPolicies(policies);
+ } catch (RemoteException e) {
+ }
+ throw new IllegalStateException("PolicyService transaction failed");
+ }
+}
diff --git a/src/com/android/exchange/adapter/EmailSyncAdapter.java b/src/com/android/exchange/adapter/EmailSyncAdapter.java
index d4a27ff..b9666c1 100644
--- a/src/com/android/exchange/adapter/EmailSyncAdapter.java
+++ b/src/com/android/exchange/adapter/EmailSyncAdapter.java
@@ -17,7 +17,6 @@
package com.android.exchange.adapter;
-import com.android.email.LegacyConversions;
import com.android.email.Utility;
import com.android.email.mail.Address;
import com.android.email.mail.MeetingInfo;
@@ -26,8 +25,8 @@
import com.android.email.mail.Part;
import com.android.email.mail.internet.MimeMessage;
import com.android.email.mail.internet.MimeUtility;
-import com.android.email.provider.AttachmentProvider;
import com.android.email.provider.EmailContent;
+import com.android.email.provider.EmailProvider;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.AccountColumns;
import com.android.email.provider.EmailContent.Attachment;
@@ -36,8 +35,10 @@
import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.MessageColumns;
import com.android.email.provider.EmailContent.SyncColumns;
-import com.android.email.provider.EmailProvider;
-import com.android.email.service.MailService;
+import com.android.emailcommon.service.AccountServiceProxy;
+import com.android.emailcommon.service.SyncWindow;
+import com.android.emailcommon.utility.AttachmentUtilities;
+import com.android.emailcommon.utility.ConversionUtilities;
import com.android.exchange.Eas;
import com.android.exchange.EasSyncService;
import com.android.exchange.MessageMoveRequest;
@@ -117,22 +118,23 @@
mService.clearRequests();
mFetchRequestList.clear();
// Delete attachments...
- AttachmentProvider.deleteAllMailboxAttachmentFiles(mContext, mAccount.mId, mMailbox.mId);
+ AttachmentUtilities.deleteAllMailboxAttachmentFiles(mContext, mAccount.mId,
+ mMailbox.mId);
}
private String getEmailFilter() {
switch (mAccount.mSyncLookback) {
- case com.android.email.Account.SYNC_WINDOW_1_DAY:
+ case SyncWindow.SYNC_WINDOW_1_DAY:
return Eas.FILTER_1_DAY;
- case com.android.email.Account.SYNC_WINDOW_3_DAYS:
+ case SyncWindow.SYNC_WINDOW_3_DAYS:
return Eas.FILTER_3_DAYS;
- case com.android.email.Account.SYNC_WINDOW_1_WEEK:
+ case SyncWindow.SYNC_WINDOW_1_WEEK:
return Eas.FILTER_1_WEEK;
- case com.android.email.Account.SYNC_WINDOW_2_WEEKS:
+ case SyncWindow.SYNC_WINDOW_2_WEEKS:
return Eas.FILTER_2_WEEKS;
- case com.android.email.Account.SYNC_WINDOW_1_MONTH:
+ case SyncWindow.SYNC_WINDOW_1_MONTH:
return Eas.FILTER_1_MONTH;
- case com.android.email.Account.SYNC_WINDOW_ALL:
+ case SyncWindow.SYNC_WINDOW_ALL:
return Eas.FILTER_ALL;
default:
return Eas.FILTER_1_WEEK;
@@ -496,7 +498,7 @@
MimeUtility.collectParts(mimeMessage, viewables, attachments);
Body tempBody = new Body();
// updateBodyFields fills in the content fields of the Body
- LegacyConversions.updateBodyFields(tempBody, msg, viewables);
+ ConversionUtilities.updateBodyFields(tempBody, msg, viewables);
// But we need them in the message itself for handling during commit()
msg.mHtml = tempBody.mHtmlContent;
msg.mText = tempBody.mTextContent;
@@ -770,7 +772,7 @@
for (Long id : deletedEmails) {
ops.add(ContentProviderOperation.newDelete(
ContentUris.withAppendedId(Message.CONTENT_URI, id)).build());
- AttachmentProvider.deleteAllAttachmentFiles(mContext, mAccount.mId, id);
+ AttachmentUtilities.deleteAllAttachmentFiles(mContext, mAccount.mId, id);
}
if (!changedEmails.isEmpty()) {
@@ -822,7 +824,11 @@
cv.put(EmailContent.ADD_COLUMN_NAME, notifyCount);
Uri uri = ContentUris.withAppendedId(Account.ADD_TO_FIELD_URI, mAccount.mId);
mContentResolver.update(uri, cv, null, null);
- MailService.actionNotifyNewMessages(mContext, mAccount.mId);
+ try {
+ new AccountServiceProxy(mService.mContext).notifyNewMessages(mAccount.mId);
+ } catch (RemoteException e) {
+ // ? Anything to do here?
+ }
}
}
}
diff --git a/src/com/android/exchange/adapter/FolderSyncParser.java b/src/com/android/exchange/adapter/FolderSyncParser.java
index 7d6229b..5013337 100644
--- a/src/com/android/exchange/adapter/FolderSyncParser.java
+++ b/src/com/android/exchange/adapter/FolderSyncParser.java
@@ -18,13 +18,13 @@
package com.android.exchange.adapter;
import com.android.email.Utility;
-import com.android.email.provider.AttachmentProvider;
import com.android.email.provider.EmailContent;
+import com.android.email.provider.EmailProvider;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.AccountColumns;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.MailboxColumns;
-import com.android.email.provider.EmailProvider;
+import com.android.emailcommon.utility.AttachmentUtilities;
import com.android.exchange.Eas;
import com.android.exchange.ExchangeService;
import com.android.exchange.MockParserStream;
@@ -187,7 +187,7 @@
ops.add(ContentProviderOperation.newDelete(
ContentUris.withAppendedId(Mailbox.CONTENT_URI,
c.getLong(0))).build());
- AttachmentProvider.deleteAllMailboxAttachmentFiles(mContext,
+ AttachmentUtilities.deleteAllMailboxAttachmentFiles(mContext,
mAccountId, mMailbox.mId);
}
} finally {
diff --git a/src/com/android/exchange/utility/CalendarUtilities.java b/src/com/android/exchange/utility/CalendarUtilities.java
index e1879f6..27452eb 100644
--- a/src/com/android/exchange/utility/CalendarUtilities.java
+++ b/src/com/android/exchange/utility/CalendarUtilities.java
@@ -18,7 +18,6 @@
import com.android.email.Email;
import com.android.email.R;
-import com.android.email.ResourceHelper;
import com.android.email.Utility;
import com.android.email.mail.Address;
import com.android.email.provider.EmailContent;
@@ -26,6 +25,7 @@
import com.android.email.provider.EmailContent.Attachment;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.Message;
+import com.android.emailcommon.service.AccountServiceProxy;
import com.android.exchange.Eas;
import com.android.exchange.EasSyncService;
import com.android.exchange.ExchangeService;
@@ -1215,8 +1215,12 @@
cv.put(Calendars.ORGANIZER_CAN_RESPOND, 0);
// TODO Coordinate account colors w/ Calendar, if possible
- // Make Email account color opaque
- int color = ResourceHelper.getInstance(service.mContext).getAccountColor(account.mId);
+ int color = AccountServiceProxy.DEFAULT_ACCOUNT_COLOR;
+ try {
+ color = new AccountServiceProxy(service.mContext).getAccountColor(account.mId);
+ } catch (RemoteException e) {
+ // Use the default
+ }
cv.put(Calendars.COLOR, color);
cv.put(Calendars.TIMEZONE, Time.getCurrentTimezone());
cv.put(Calendars.ACCESS_LEVEL, Calendars.OWNER_ACCESS);