From 66a47b8dac5e97e37c30b928bc5a227d74baada9 Mon Sep 17 00:00:00 2001 From: Marc Blank Date: Mon, 27 Jun 2011 12:12:41 -0700 Subject: [PATCH] Clean up/simplify ExchangeUtils/ExchangeStore * Rename ExchangeUtils to EmailServiceUtils * Create calls for Exchange to use (eventually remove these) * Get rid of lots of nonsense in ExchangeStore Change-Id: Ic538cfe1de57eca24088ee1f590264283d12f511 --- src/com/android/email/Controller.java | 5 +- src/com/android/email/activity/Welcome.java | 4 +- .../setup/AccountSetupAccountType.java | 4 +- .../setup/AccountSetupExchangeFragment.java | 4 +- .../activity/setup/AccountSetupOptions.java | 4 +- .../email/activity/setup/DebugFragment.java | 4 +- src/com/android/email/mail/Store.java | 8 +- .../email/mail/store/ExchangeStore.java | 149 +++--------------- .../android/email/service/AccountService.java | 3 +- .../EmailBroadcastProcessorService.java | 30 ++-- .../EmailServiceUtils.java} | 64 ++++---- .../AttachmentDownloadServiceTests.java | 2 +- 12 files changed, 92 insertions(+), 189 deletions(-) rename src/com/android/email/{ExchangeUtils.java => service/EmailServiceUtils.java} (79%) diff --git a/src/com/android/email/Controller.java b/src/com/android/email/Controller.java index 1b5b2d198..d8fde03f2 100644 --- a/src/com/android/email/Controller.java +++ b/src/com/android/email/Controller.java @@ -34,6 +34,7 @@ import android.util.Log; import com.android.email.mail.Store; import com.android.email.mail.store.Pop3Store.Pop3Message; import com.android.email.provider.AccountBackupRestore; +import com.android.email.service.EmailServiceUtils; import com.android.emailcommon.Api; import com.android.emailcommon.Logging; import com.android.emailcommon.mail.AuthenticationFailedException; @@ -317,7 +318,7 @@ public class Controller { * Generally this should be called by anybody who changes Email.DEBUG */ public void serviceLogging(int debugFlags) { - IEmailService service = ExchangeUtils.getExchangeService(mContext, mServiceCallback); + IEmailService service = EmailServiceUtils.getExchangeService(mContext, mServiceCallback); try { service.setLogging(debugFlags); } catch (RemoteException e) { @@ -1041,7 +1042,7 @@ public class Controller { } private IEmailService getExchangeEmailService() { - return ExchangeUtils.getExchangeService(mContext, mServiceCallback); + return EmailServiceUtils.getExchangeService(mContext, mServiceCallback); } /** diff --git a/src/com/android/email/activity/Welcome.java b/src/com/android/email/activity/Welcome.java index 76ca54b80..46a11dac7 100644 --- a/src/com/android/email/activity/Welcome.java +++ b/src/com/android/email/activity/Welcome.java @@ -17,9 +17,9 @@ package com.android.email.activity; import com.android.email.Email; -import com.android.email.ExchangeUtils; import com.android.email.R; import com.android.email.activity.setup.AccountSetupBasics; +import com.android.email.service.EmailServiceUtils; import com.android.email.service.MailService; import com.android.emailcommon.Logging; import com.android.emailcommon.provider.Account; @@ -185,7 +185,7 @@ public class Welcome extends Activity { // already been started // When the service starts, it reconciles EAS accounts. // TODO More completely separate ExchangeService from Email app - ExchangeUtils.startExchangeService(this); + EmailServiceUtils.startExchangeService(this); // Extract parameters from the intent. final Intent intent = getIntent(); diff --git a/src/com/android/email/activity/setup/AccountSetupAccountType.java b/src/com/android/email/activity/setup/AccountSetupAccountType.java index 27b0864d7..bb6109c7a 100644 --- a/src/com/android/email/activity/setup/AccountSetupAccountType.java +++ b/src/com/android/email/activity/setup/AccountSetupAccountType.java @@ -23,11 +23,11 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; -import com.android.email.ExchangeUtils; import com.android.email.R; import com.android.email.VendorPolicyLoader; import com.android.email.activity.ActivityHelper; import com.android.email.activity.UiUtilities; +import com.android.email.service.EmailServiceUtils; import com.android.emailcommon.provider.Account; import com.android.emailcommon.provider.HostAuth; @@ -66,7 +66,7 @@ public class AccountSetupAccountType extends AccountSetupActivity implements OnC // TODO If we decide to exclude the Exchange option in POP_IMAP mode, use the following line // instead of the line that follows it //if (ExchangeUtils.isExchangeAvailable(this) && flowMode != SetupData.FLOW_MODE_POP_IMAP) { - if (ExchangeUtils.isExchangeAvailable(this)) { + if (EmailServiceUtils.isExchangeAvailable(this)) { exchangeButton.setOnClickListener(this); exchangeButton.setVisibility(View.VISIBLE); if (VendorPolicyLoader.getInstance(this).useAlternateExchangeStrings()) { diff --git a/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java b/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java index 7076dda4c..ad77d2610 100644 --- a/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java +++ b/src/com/android/email/activity/setup/AccountSetupExchangeFragment.java @@ -17,11 +17,11 @@ package com.android.email.activity.setup; import com.android.email.Email; -import com.android.email.ExchangeUtils; import com.android.email.R; import com.android.email.activity.UiUtilities; import com.android.email.mail.Store; import com.android.email.provider.AccountBackupRestore; +import com.android.email.service.EmailServiceUtils; import com.android.email.view.CertificateSelector; import com.android.emailcommon.Device; import com.android.emailcommon.Logging; @@ -336,7 +336,7 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment account.mHostAuthSend.update(mContext, account.mHostAuthSend.toContentValues()); // For EAS, notify ExchangeService that the password has changed try { - ExchangeUtils.getExchangeService(mContext, null).hostChanged(account.mId); + EmailServiceUtils.getExchangeService(mContext, null).hostChanged(account.mId); } catch (RemoteException e) { // Nothing to be done if this fails } diff --git a/src/com/android/email/activity/setup/AccountSetupOptions.java b/src/com/android/email/activity/setup/AccountSetupOptions.java index ad110d50d..c91615f46 100644 --- a/src/com/android/email/activity/setup/AccountSetupOptions.java +++ b/src/com/android/email/activity/setup/AccountSetupOptions.java @@ -36,10 +36,10 @@ import android.widget.CheckBox; import android.widget.Spinner; import com.android.email.Email; -import com.android.email.ExchangeUtils; import com.android.email.R; import com.android.email.activity.ActivityHelper; import com.android.email.activity.UiUtilities; +import com.android.email.service.EmailServiceUtils; import com.android.email.service.MailService; import com.android.emailcommon.Logging; import com.android.emailcommon.provider.Account; @@ -364,7 +364,7 @@ public class AccountSetupOptions extends AccountSetupActivity implements OnClick AccountSettingsUtils.commitSettings(context, account); // Start up services based on new account(s) Email.setServicesEnabledSync(context); - ExchangeUtils.startExchangeService(context); + EmailServiceUtils.startExchangeService(context); // Move to final setup screen AccountSetupNames.actionSetNames(context); finish(); diff --git a/src/com/android/email/activity/setup/DebugFragment.java b/src/com/android/email/activity/setup/DebugFragment.java index 744c45f8c..f7cd8d31c 100644 --- a/src/com/android/email/activity/setup/DebugFragment.java +++ b/src/com/android/email/activity/setup/DebugFragment.java @@ -17,10 +17,10 @@ package com.android.email.activity.setup; import com.android.email.Email; -import com.android.email.ExchangeUtils; import com.android.email.Preferences; import com.android.email.R; import com.android.email.activity.UiUtilities; +import com.android.email.service.EmailServiceUtils; import com.android.email.service.MailService; import com.android.emailcommon.Logging; @@ -74,7 +74,7 @@ public class DebugFragment extends Fragment implements OnCheckedChangeListener, // Note: To prevent recursion while presetting checkboxes, assign all listeners last mEnableDebugLoggingView.setOnCheckedChangeListener(this); - boolean exchangeAvailable = ExchangeUtils.isExchangeAvailable(context); + boolean exchangeAvailable = EmailServiceUtils.isExchangeAvailable(context); if (exchangeAvailable) { mEnableExchangeLoggingView.setChecked(Email.DEBUG_EXCHANGE_VERBOSE); mEnableExchangeFileLoggingView.setChecked(Email.DEBUG_EXCHANGE_FILE); diff --git a/src/com/android/email/mail/Store.java b/src/com/android/email/mail/Store.java index ef865ac3c..dc3d3e720 100644 --- a/src/com/android/email/mail/Store.java +++ b/src/com/android/email/mail/Store.java @@ -236,7 +236,9 @@ public abstract class Store { return true; } - public abstract Folder getFolder(String name) throws MessagingException; + public Folder getFolder(String name) throws MessagingException { + return null; + } /** * Updates the local list of mailboxes according to what is located on the remote server. @@ -245,7 +247,9 @@ public abstract class Store { * @return The set of remote folders * @throws MessagingException If there was a problem connecting to the remote server */ - public abstract Folder[] updateFolders() throws MessagingException; + public Folder[] updateFolders() throws MessagingException { + return null; + } public abstract Bundle checkSettings() throws MessagingException; diff --git a/src/com/android/email/mail/store/ExchangeStore.java b/src/com/android/email/mail/store/ExchangeStore.java index 6f0c3a835..049359e34 100644 --- a/src/com/android/email/mail/store/ExchangeStore.java +++ b/src/com/android/email/mail/store/ExchangeStore.java @@ -16,32 +16,23 @@ package com.android.email.mail.store; -import com.android.email.ExchangeUtils; +import android.content.Context; +import android.os.Bundle; +import android.os.RemoteException; + import com.android.email.mail.Store; -import com.android.emailcommon.mail.Folder; +import com.android.email.service.EmailServiceUtils; import com.android.emailcommon.mail.MessagingException; import com.android.emailcommon.provider.Account; -import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.HostAuth; import com.android.emailcommon.service.EmailServiceProxy; import com.android.emailcommon.service.IEmailService; -import android.content.Context; -import android.os.Bundle; -import android.os.RemoteException; -import android.text.TextUtils; - -import java.util.HashMap; - /** - * Our Exchange service does not use the sender/store model. This class exists for exactly two - * purposes, (1) to provide a hook for checking account connections, and (2) to return - * "AccountSetupExchange.class" for getSettingActivityClass(). + * Our Exchange service does not use the sender/store model. */ public class ExchangeStore extends Store { - public static final String LOG_TAG = "ExchangeStore"; - @SuppressWarnings("hiding") - private final ExchangeTransport mTransport; + private final HostAuth mHostAuth; /** * Static named constructor. @@ -56,122 +47,26 @@ public class ExchangeStore extends Store { */ private ExchangeStore(Account account, Context context, PersistentDataCallbacks callbacks) throws MessagingException { - mTransport = ExchangeTransport.getInstance(account, context); + mContext = context; + mHostAuth = account.getOrCreateHostAuthRecv(mContext); } @Override public Bundle checkSettings() throws MessagingException { - return mTransport.checkSettings(); - } - - @Override - public Folder getFolder(String name) { - return null; - } - - @Override - public Folder[] updateFolders() { - return null; - } - - /** - * Get class of SettingActivity for this Store class. - * @return Activity class that has class method actionEditIncomingSettings() - */ - @Override - public Class getSettingActivityClass() { - return com.android.email.activity.setup.AccountSetupExchange.class; - } - - /** - * Inform MessagingController that messages sent via EAS will be placed in the Sent folder - * automatically (server-side) and don't need to be uploaded. - * @return always false for EAS (assuming server-side copy is supported) - */ - @Override - public boolean requireCopyMessageToSentFolder() { - return false; - } - - public static class ExchangeTransport { - private final Context mContext; - private HostAuth mHostAuth; - - private static final HashMap sHostAuthToInstanceMap = - new HashMap(); - - /** - * Public factory. The transport should be a singleton - */ - public synchronized static ExchangeTransport getInstance(Account account, Context context) - throws MessagingException { - HostAuth hostAuth = HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv); - if (hostAuth == null) { - hostAuth = new HostAuth(); - } - final long storeKey = hostAuth.mId; - ExchangeTransport transport = sHostAuthToInstanceMap.get(storeKey); - if (transport == null) { - transport = new ExchangeTransport(account, context); - // Only cache a saved HostAuth key - if (storeKey != EmailContent.NOT_SAVED) { - sHostAuthToInstanceMap.put(storeKey, transport); - } - } - return transport; - } - - /** - * Private constructor - use public factory. - */ - private ExchangeTransport(Account account, Context context) throws MessagingException { - mContext = context.getApplicationContext(); - setAccount(account); - } - - private void setAccount(final Account account) throws MessagingException { - HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext); - if (recvAuth == null || !STORE_SCHEME_EAS.equalsIgnoreCase(recvAuth.mProtocol)) { - throw new MessagingException("Unsupported protocol"); - } - if (recvAuth.mAddress == null) { - throw new MessagingException("host not specified"); - } - if (!TextUtils.isEmpty(recvAuth.mDomain)) { - recvAuth.mDomain = recvAuth.mDomain.substring(1); - } - recvAuth.mPort = 80; - if ((recvAuth.mFlags & HostAuth.FLAG_SSL) != 0) { - recvAuth.mPort = 443; - } - - String[] userInfoParts = recvAuth.getLogin(); - if (userInfoParts != null) { - if (TextUtils.isEmpty(userInfoParts[0]) || TextUtils.isEmpty(userInfoParts[1])) { - throw new MessagingException("user name and password not specified"); - } - } else { - throw new MessagingException("user information not specifed"); - } - mHostAuth = recvAuth; - } - /** * Here's where we check the settings for EAS. * @throws MessagingException if we can't authenticate the account */ - public Bundle checkSettings() throws MessagingException { - try { - IEmailService svc = ExchangeUtils.getExchangeService(mContext, null); - // Use a longer timeout for the validate command. Note that the instanceof check - // shouldn't be necessary; we'll do it anyway, just to be safe - if (svc instanceof EmailServiceProxy) { - ((EmailServiceProxy)svc).setTimeout(90); - } - return svc.validate(mHostAuth); - } catch (RemoteException e) { - throw new MessagingException("Call to validate generated an exception", e); + try { + IEmailService svc = EmailServiceUtils.getExchangeService(mContext, null); + // Use a longer timeout for the validate command. Note that the instanceof check + // shouldn't be necessary; we'll do it anyway, just to be safe + if (svc instanceof EmailServiceProxy) { + ((EmailServiceProxy)svc).setTimeout(90); } + return svc.validate(mHostAuth); + } catch (RemoteException e) { + throw new MessagingException("Call to validate generated an exception", e); } } @@ -182,9 +77,15 @@ public class ExchangeStore extends Store { @Override public Bundle autoDiscover(Context context, String username, String password) { try { - return ExchangeUtils.getExchangeService(context, null).autoDiscover(username, password); + return EmailServiceUtils.getExchangeService(context, null).autoDiscover( + username, password); } catch (RemoteException e) { return null; } } + + @Override + public Class getSettingActivityClass() { + return com.android.email.activity.setup.AccountSetupExchange.class; + } } diff --git a/src/com/android/email/service/AccountService.java b/src/com/android/email/service/AccountService.java index 57f8a6e94..e28ec422b 100644 --- a/src/com/android/email/service/AccountService.java +++ b/src/com/android/email/service/AccountService.java @@ -17,7 +17,6 @@ package com.android.email.service; import com.android.email.Email; -import com.android.email.ExchangeUtils; import com.android.email.NotificationController; import com.android.email.ResourceHelper; import com.android.email.VendorPolicyLoader; @@ -83,7 +82,7 @@ public class AccountService extends Service { @Override public void run() { // Make sure the service is properly running (re: lifecycle) - ExchangeUtils.startExchangeService(mContext); + EmailServiceUtils.startExchangeService(mContext); // Send current logging flags Email.updateLoggingFlags(mContext); }}); diff --git a/src/com/android/email/service/EmailBroadcastProcessorService.java b/src/com/android/email/service/EmailBroadcastProcessorService.java index b86c43d6d..90f6cd9c9 100644 --- a/src/com/android/email/service/EmailBroadcastProcessorService.java +++ b/src/com/android/email/service/EmailBroadcastProcessorService.java @@ -16,19 +16,6 @@ package com.android.email.service; -import com.android.email.Email; -import com.android.email.ExchangeUtils; -import com.android.email.Preferences; -import com.android.email.SecurityPolicy; -import com.android.email.VendorPolicyLoader; -import com.android.email.activity.setup.AccountSettings; -import com.android.email.mail.Store; -import com.android.email.widget.WidgetManager; -import com.android.emailcommon.Logging; -import com.android.emailcommon.provider.Account; -import com.android.emailcommon.provider.EmailContent.AccountColumns; -import com.android.emailcommon.provider.HostAuth; - import android.accounts.AccountManager; import android.app.IntentService; import android.content.ComponentName; @@ -42,6 +29,17 @@ import android.database.Cursor; import android.net.Uri; import android.util.Log; +import com.android.email.Email; +import com.android.email.Preferences; +import com.android.email.SecurityPolicy; +import com.android.email.VendorPolicyLoader; +import com.android.email.activity.setup.AccountSettings; +import com.android.email.mail.Store; +import com.android.emailcommon.Logging; +import com.android.emailcommon.provider.Account; +import com.android.emailcommon.provider.EmailContent.AccountColumns; +import com.android.emailcommon.provider.HostAuth; + /** * The service that really handles broadcast intents on a worker thread. * @@ -146,7 +144,7 @@ public class EmailBroadcastProcessorService extends IntentService { enableComponentsIfNecessary(); // Starts the service for Exchange, if supported. - ExchangeUtils.startExchangeService(this); + EmailServiceUtils.startExchangeService(this); } private void performOneTimeInitialization() { @@ -161,8 +159,6 @@ public class EmailBroadcastProcessorService extends IntentService { setComponentEnabled(EasAuthenticatorServiceAlternate.class, true); setComponentEnabled(EasAuthenticatorService.class, false); } - - ExchangeUtils.enableEasCalendarSync(this); } if (progress < 2) { @@ -224,6 +220,6 @@ public class EmailBroadcastProcessorService extends IntentService { // If the exchange service wasn't already running, starting it will cause exchange account // reconciliation to be performed. The service stops itself it there are no EAS accounts. - ExchangeUtils.startExchangeService(this); + EmailServiceUtils.startExchangeService(this); } } diff --git a/src/com/android/email/ExchangeUtils.java b/src/com/android/email/service/EmailServiceUtils.java similarity index 79% rename from src/com/android/email/ExchangeUtils.java rename to src/com/android/email/service/EmailServiceUtils.java index e5494d888..38e35195d 100644 --- a/src/com/android/email/ExchangeUtils.java +++ b/src/com/android/email/service/EmailServiceUtils.java @@ -14,14 +14,7 @@ * limitations under the License. */ -package com.android.email; - -import com.android.emailcommon.Api; -import com.android.emailcommon.provider.HostAuth; -import com.android.emailcommon.service.EmailServiceProxy; -import com.android.emailcommon.service.IEmailService; -import com.android.emailcommon.service.IEmailServiceCallback; -import com.android.emailcommon.service.SearchParams; +package com.android.email.service; import android.app.Service; import android.content.Context; @@ -30,45 +23,54 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import com.android.emailcommon.Api; +import com.android.emailcommon.provider.HostAuth; +import com.android.emailcommon.service.EmailServiceProxy; +import com.android.emailcommon.service.IEmailService; +import com.android.emailcommon.service.IEmailServiceCallback; +import com.android.emailcommon.service.SearchParams; + /** - * Utility functions for Exchange support. + * Utility functions for EmailService support. */ -public class ExchangeUtils { +public class EmailServiceUtils { /** - * Starts the service for Exchange, if supported. + * Starts an EmailService by name */ - public static void startExchangeService(Context context) { - context.startService(new Intent(EmailServiceProxy.EXCHANGE_INTENT)); + public static void startService(Context context, String intentAction) { + context.startService(new Intent(intentAction)); } /** - * Returns an {@link IEmailService} for the Exchange service, if supported. Otherwise it'll - * return an empty {@link IEmailService} implementation. + * Returns an {@link IEmailService} for the service; otherwise returns an empty + * {@link IEmailService} implementation. * * @param context * @param callback Object to get callback, or can be null */ + public static IEmailService getService(Context context, String intentAction, + IEmailServiceCallback callback) { + return new EmailServiceProxy(context, intentAction, callback); + } + + /** + * Determine if the EmailService is available + */ + public static boolean isServiceAvailable(Context context, String intentAction) { + return new EmailServiceProxy(context, intentAction, null).test(); + } + + public static void startExchangeService(Context context) { + startService(context, EmailServiceProxy.EXCHANGE_INTENT); + } + public static IEmailService getExchangeService(Context context, IEmailServiceCallback callback) { - return new EmailServiceProxy(context, EmailServiceProxy.EXCHANGE_INTENT, callback); + return getService(context, EmailServiceProxy.EXCHANGE_INTENT, callback); } - /** - * Determine if the Exchange package is loaded - * - * TODO: This should be dynamic and data-driven for all account types, not just hardcoded - * like this. - */ public static boolean isExchangeAvailable(Context context) { - return new EmailServiceProxy(context, EmailServiceProxy.EXCHANGE_INTENT, null).test(); - } - - /** - * Enable calendar sync for all the existing exchange accounts, and post a notification if any. - */ - public static void enableEasCalendarSync(Context context) { - // *** TODO: Is this still necessary? - //new CalendarSyncEnabler(context).enableEasCalendarSync(); + return isServiceAvailable(context, EmailServiceProxy.EXCHANGE_INTENT); } /** diff --git a/tests/src/com/android/email/service/AttachmentDownloadServiceTests.java b/tests/src/com/android/email/service/AttachmentDownloadServiceTests.java index 712cced2e..c3398cd20 100644 --- a/tests/src/com/android/email/service/AttachmentDownloadServiceTests.java +++ b/tests/src/com/android/email/service/AttachmentDownloadServiceTests.java @@ -18,10 +18,10 @@ package com.android.email.service; import com.android.email.AccountTestCase; import com.android.email.EmailConnectivityManager; -import com.android.email.ExchangeUtils.NullEmailService; import com.android.email.provider.ProviderTestUtils; import com.android.email.service.AttachmentDownloadService.DownloadRequest; import com.android.email.service.AttachmentDownloadService.DownloadSet; +import com.android.email.service.EmailServiceUtils.NullEmailService; import com.android.emailcommon.provider.Account; import com.android.emailcommon.provider.EmailContent.Attachment; import com.android.emailcommon.provider.EmailContent.Message;