summaryrefslogtreecommitdiffstats
path: root/src/com/android/email/service/EmailServiceUtils.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/email/service/EmailServiceUtils.java')
-rw-r--r--src/com/android/email/service/EmailServiceUtils.java780
1 files changed, 0 insertions, 780 deletions
diff --git a/src/com/android/email/service/EmailServiceUtils.java b/src/com/android/email/service/EmailServiceUtils.java
deleted file mode 100644
index 3532689c4..000000000
--- a/src/com/android/email/service/EmailServiceUtils.java
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * Copyright (C) 2010 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.email.service;
-
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.provider.CalendarContract;
-import android.provider.CalendarContract.Calendars;
-import android.provider.CalendarContract.SyncState;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.SyncStateContract;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.android.email.R;
-import com.android.emailcommon.VendorPolicyLoader;
-import com.android.emailcommon.provider.Account;
-import com.android.emailcommon.provider.EmailContent;
-import com.android.emailcommon.provider.EmailContent.AccountColumns;
-import com.android.emailcommon.provider.EmailContent.HostAuthColumns;
-import com.android.emailcommon.provider.HostAuth;
-import com.android.emailcommon.service.EmailServiceProxy;
-import com.android.emailcommon.service.EmailServiceStatus;
-import com.android.emailcommon.service.EmailServiceVersion;
-import com.android.emailcommon.service.HostAuthCompat;
-import com.android.emailcommon.service.IEmailService;
-import com.android.emailcommon.service.IEmailServiceCallback;
-import com.android.emailcommon.service.SearchParams;
-import com.android.emailcommon.service.ServiceProxy;
-import com.android.emailcommon.service.SyncWindow;
-import com.android.mail.utils.LogUtils;
-import com.google.common.collect.ImmutableMap;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Utility functions for EmailService support.
- */
-public class EmailServiceUtils {
- /**
- * Ask a service to kill its process. This is used when an account is deleted so that
- * no background thread that happens to be running will continue, possibly hitting an
- * NPE or other error when trying to operate on an account that no longer exists.
- * TODO: This is kind of a hack, it's only needed because we fail so badly if an account
- * is deleted out from under us while a sync or other operation is in progress. It would
- * be a lot cleaner if our background services could handle this without crashing.
- */
- public static void killService(Context context, String protocol) {
- EmailServiceInfo info = getServiceInfo(context, protocol);
- if (info != null && info.intentAction != null) {
- final Intent serviceIntent = getServiceIntent(info);
- serviceIntent.putExtra(ServiceProxy.EXTRA_FORCE_SHUTDOWN, true);
- context.startService(serviceIntent);
- }
- }
-
- /**
- * Starts an EmailService by protocol
- */
- public static void startService(Context context, String protocol) {
- EmailServiceInfo info = getServiceInfo(context, protocol);
- if (info != null && info.intentAction != null) {
- final Intent serviceIntent = getServiceIntent(info);
- context.startService(serviceIntent);
- }
- }
-
- /**
- * Starts all remote services
- */
- public static void startRemoteServices(Context context) {
- for (EmailServiceInfo info: getServiceInfoList(context)) {
- if (info.intentAction != null) {
- final Intent serviceIntent = getServiceIntent(info);
- context.startService(serviceIntent);
- }
- }
- }
-
- /**
- * Returns whether or not remote services are present on device
- */
- public static boolean areRemoteServicesInstalled(Context context) {
- for (EmailServiceInfo info: getServiceInfoList(context)) {
- if (info.intentAction != null) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Starts all remote services
- */
- public static void setRemoteServicesLogging(Context context, int debugBits) {
- for (EmailServiceInfo info: getServiceInfoList(context)) {
- if (info.intentAction != null) {
- EmailServiceProxy service =
- EmailServiceUtils.getService(context, info.protocol);
- if (service != null) {
- try {
- service.setLogging(debugBits);
- } catch (RemoteException e) {
- // Move along, nothing to see
- }
- }
- }
- }
- }
-
- /**
- * Determine if the EmailService is available
- */
- public static boolean isServiceAvailable(Context context, String protocol) {
- EmailServiceInfo info = getServiceInfo(context, protocol);
- if (info == null) return false;
- if (info.klass != null) return true;
- final Intent serviceIntent = getServiceIntent(info);
- return new EmailServiceProxy(context, serviceIntent).test();
- }
-
- private static Intent getServiceIntent(EmailServiceInfo info) {
- final Intent serviceIntent = new Intent(info.intentAction);
- serviceIntent.setPackage(info.intentPackage);
- return serviceIntent;
- }
-
- /**
- * For a given account id, return a service proxy if applicable, or null.
- *
- * @param accountId the message of interest
- * @return service proxy, or null if n/a
- */
- public static EmailServiceProxy getServiceForAccount(Context context, long accountId) {
- return getService(context, Account.getProtocol(context, accountId));
- }
-
- /**
- * Holder of service information (currently just name and class/intent); if there is a class
- * member, this is a (local, i.e. same process) service; otherwise, this is a remote service
- */
- public static class EmailServiceInfo {
- public String protocol;
- public String name;
- public String accountType;
- Class<? extends Service> klass;
- String intentAction;
- String intentPackage;
- public int port;
- public int portSsl;
- public boolean defaultSsl;
- public boolean offerTls;
- public boolean offerCerts;
- public boolean offerOAuth;
- public boolean usesSmtp;
- public boolean offerLocalDeletes;
- public int defaultLocalDeletes;
- public boolean offerPrefix;
- public boolean usesAutodiscover;
- public boolean offerLookback;
- public int defaultLookback;
- public boolean syncChanges;
- public boolean syncContacts;
- public boolean syncCalendar;
- public boolean offerAttachmentPreload;
- public CharSequence[] syncIntervalStrings;
- public CharSequence[] syncIntervals;
- public int defaultSyncInterval;
- public String inferPrefix;
- public boolean offerLoadMore;
- public boolean offerMoveTo;
- public boolean requiresSetup;
- public boolean hide;
- public boolean isGmailStub;
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("Protocol: ");
- sb.append(protocol);
- sb.append(", ");
- sb.append(klass != null ? "Local" : "Remote");
- sb.append(" , Account Type: ");
- sb.append(accountType);
- return sb.toString();
- }
- }
-
- public static EmailServiceProxy getService(Context context, String protocol) {
- EmailServiceInfo info = null;
- // Handle the degenerate case here (account might have been deleted)
- if (protocol != null) {
- info = getServiceInfo(context, protocol);
- }
- if (info == null) {
- LogUtils.w(LogUtils.TAG, "Returning NullService for %s", protocol);
- return new EmailServiceProxy(context, NullService.class);
- } else {
- return getServiceFromInfo(context, info);
- }
- }
-
- public static EmailServiceProxy getServiceFromInfo(Context context, EmailServiceInfo info) {
- if (info.klass != null) {
- return new EmailServiceProxy(context, info.klass);
- } else {
- final Intent serviceIntent = getServiceIntent(info);
- return new EmailServiceProxy(context, serviceIntent);
- }
- }
-
- public static EmailServiceInfo getServiceInfoForAccount(Context context, long accountId) {
- String protocol = Account.getProtocol(context, accountId);
- return getServiceInfo(context, protocol);
- }
-
- public static EmailServiceInfo getServiceInfo(Context context, String protocol) {
- return getServiceMap(context).get(protocol);
- }
-
- public static Collection<EmailServiceInfo> getServiceInfoList(Context context) {
- return getServiceMap(context).values();
- }
-
- private static void finishAccountManagerBlocker(AccountManagerFuture<?> future) {
- try {
- // Note: All of the potential errors are simply logged
- // here, as there is nothing to actually do about them.
- future.getResult();
- } catch (OperationCanceledException e) {
- LogUtils.w(LogUtils.TAG, e, "finishAccountManagerBlocker");
- } catch (AuthenticatorException e) {
- LogUtils.w(LogUtils.TAG, e, "finishAccountManagerBlocker");
- } catch (IOException e) {
- LogUtils.w(LogUtils.TAG, e, "finishAccountManagerBlocker");
- }
- }
-
- /**
- * Add an account to the AccountManager.
- * @param context Our {@link Context}.
- * @param account The {@link Account} we're adding.
- * @param email Whether the user wants to sync email on this account.
- * @param calendar Whether the user wants to sync calendar on this account.
- * @param contacts Whether the user wants to sync contacts on this account.
- * @param callback A callback for when the AccountManager is done.
- * @return The result of {@link AccountManager#addAccount}.
- */
- public static AccountManagerFuture<Bundle> setupAccountManagerAccount(final Context context,
- final Account account, final boolean email, final boolean calendar,
- final boolean contacts, final AccountManagerCallback<Bundle> callback) {
- final HostAuth hostAuthRecv =
- HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv);
- return setupAccountManagerAccount(context, account, email, calendar, contacts,
- hostAuthRecv, callback);
- }
-
- /**
- * Add an account to the AccountManager.
- * @param context Our {@link Context}.
- * @param account The {@link Account} we're adding.
- * @param email Whether the user wants to sync email on this account.
- * @param calendar Whether the user wants to sync calendar on this account.
- * @param contacts Whether the user wants to sync contacts on this account.
- * @param hostAuth HostAuth that identifies the protocol and password for this account.
- * @param callback A callback for when the AccountManager is done.
- * @return The result of {@link AccountManager#addAccount}.
- */
- public static AccountManagerFuture<Bundle> setupAccountManagerAccount(final Context context,
- final Account account, final boolean email, final boolean calendar,
- final boolean contacts, final HostAuth hostAuth,
- final AccountManagerCallback<Bundle> callback) {
- if (hostAuth == null) {
- return null;
- }
- // Set up username/password
- final Bundle options = new Bundle(5);
- options.putString(EasAuthenticatorService.OPTIONS_USERNAME, account.mEmailAddress);
- options.putString(EasAuthenticatorService.OPTIONS_PASSWORD, hostAuth.mPassword);
- options.putBoolean(EasAuthenticatorService.OPTIONS_CONTACTS_SYNC_ENABLED, contacts);
- options.putBoolean(EasAuthenticatorService.OPTIONS_CALENDAR_SYNC_ENABLED, calendar);
- options.putBoolean(EasAuthenticatorService.OPTIONS_EMAIL_SYNC_ENABLED, email);
- final EmailServiceInfo info = getServiceInfo(context, hostAuth.mProtocol);
- return AccountManager.get(context).addAccount(info.accountType, null, null, options, null,
- callback, null);
- }
-
- public static void updateAccountManagerType(Context context,
- android.accounts.Account amAccount, final Map<String, String> protocolMap) {
- final ContentResolver resolver = context.getContentResolver();
- final Cursor c = resolver.query(Account.CONTENT_URI, Account.CONTENT_PROJECTION,
- AccountColumns.EMAIL_ADDRESS + "=?", new String[] { amAccount.name }, null);
- // That's odd, isn't it?
- if (c == null) return;
- try {
- if (c.moveToNext()) {
- // Get the EmailProvider Account/HostAuth
- final Account account = new Account();
- account.restore(c);
- final HostAuth hostAuth =
- HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv);
- if (hostAuth == null) {
- return;
- }
-
- final String newProtocol = protocolMap.get(hostAuth.mProtocol);
- if (newProtocol == null) {
- // This account doesn't need updating.
- return;
- }
-
- LogUtils.w(LogUtils.TAG, "Converting %s to %s", amAccount.name, newProtocol);
-
- final ContentValues accountValues = new ContentValues();
- int oldFlags = account.mFlags;
-
- // Mark the provider account incomplete so it can't get reconciled away
- account.mFlags |= Account.FLAGS_INCOMPLETE;
- accountValues.put(AccountColumns.FLAGS, account.mFlags);
- final Uri accountUri = ContentUris.withAppendedId(Account.CONTENT_URI, account.mId);
- resolver.update(accountUri, accountValues, null, null);
-
- // Change the HostAuth to reference the new protocol; this has to be done before
- // trying to create the AccountManager account (below)
- final ContentValues hostValues = new ContentValues();
- hostValues.put(HostAuthColumns.PROTOCOL, newProtocol);
- resolver.update(ContentUris.withAppendedId(HostAuth.CONTENT_URI, hostAuth.mId),
- hostValues, null, null);
- LogUtils.w(LogUtils.TAG, "Updated HostAuths");
-
- try {
- // Get current settings for the existing AccountManager account
- boolean email = ContentResolver.getSyncAutomatically(amAccount,
- EmailContent.AUTHORITY);
- if (!email) {
- // Try our old provider name
- email = ContentResolver.getSyncAutomatically(amAccount,
- "com.android.email.provider");
- }
- final boolean contacts = ContentResolver.getSyncAutomatically(amAccount,
- ContactsContract.AUTHORITY);
- final boolean calendar = ContentResolver.getSyncAutomatically(amAccount,
- CalendarContract.AUTHORITY);
- LogUtils.w(LogUtils.TAG, "Email: %s, Contacts: %s Calendar: %s",
- email, contacts, calendar);
-
- // Get sync keys for calendar/contacts
- final String amName = amAccount.name;
- final String oldType = amAccount.type;
- ContentProviderClient client = context.getContentResolver()
- .acquireContentProviderClient(CalendarContract.CONTENT_URI);
- byte[] calendarSyncKey = null;
- try {
- calendarSyncKey = SyncStateContract.Helpers.get(client,
- asCalendarSyncAdapter(SyncState.CONTENT_URI, amName, oldType),
- new android.accounts.Account(amName, oldType));
- } catch (RemoteException e) {
- LogUtils.w(LogUtils.TAG, "Get calendar key FAILED");
- } finally {
- client.release();
- }
- client = context.getContentResolver()
- .acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
- byte[] contactsSyncKey = null;
- try {
- contactsSyncKey = SyncStateContract.Helpers.get(client,
- ContactsContract.SyncState.CONTENT_URI,
- new android.accounts.Account(amName, oldType));
- } catch (RemoteException e) {
- LogUtils.w(LogUtils.TAG, "Get contacts key FAILED");
- } finally {
- client.release();
- }
- if (calendarSyncKey != null) {
- LogUtils.w(LogUtils.TAG, "Got calendar key: %s",
- new String(calendarSyncKey));
- }
- if (contactsSyncKey != null) {
- LogUtils.w(LogUtils.TAG, "Got contacts key: %s",
- new String(contactsSyncKey));
- }
-
- // Set up a new AccountManager account with new type and old settings
- AccountManagerFuture<?> amFuture = setupAccountManagerAccount(context, account,
- email, calendar, contacts, null);
- finishAccountManagerBlocker(amFuture);
- LogUtils.w(LogUtils.TAG, "Created new AccountManager account");
-
- // TODO: Clean up how we determine the type.
- final String accountType = protocolMap.get(hostAuth.mProtocol + "_type");
- // Move calendar and contacts data from the old account to the new one.
- // We must do this before deleting the old account or the data is lost.
- moveCalendarData(context.getContentResolver(), amName, oldType, accountType);
- moveContactsData(context.getContentResolver(), amName, oldType, accountType);
-
- // Delete the AccountManager account
- amFuture = AccountManager.get(context)
- .removeAccount(amAccount, null, null);
- finishAccountManagerBlocker(amFuture);
- LogUtils.w(LogUtils.TAG, "Deleted old AccountManager account");
-
- // Restore sync keys for contacts/calendar
-
- if (accountType != null &&
- calendarSyncKey != null && calendarSyncKey.length != 0) {
- client = context.getContentResolver()
- .acquireContentProviderClient(CalendarContract.CONTENT_URI);
- try {
- SyncStateContract.Helpers.set(client,
- asCalendarSyncAdapter(SyncState.CONTENT_URI, amName,
- accountType),
- new android.accounts.Account(amName, accountType),
- calendarSyncKey);
- LogUtils.w(LogUtils.TAG, "Set calendar key...");
- } catch (RemoteException e) {
- LogUtils.w(LogUtils.TAG, "Set calendar key FAILED");
- } finally {
- client.release();
- }
- }
- if (accountType != null &&
- contactsSyncKey != null && contactsSyncKey.length != 0) {
- client = context.getContentResolver()
- .acquireContentProviderClient(ContactsContract.AUTHORITY_URI);
- try {
- SyncStateContract.Helpers.set(client,
- ContactsContract.SyncState.CONTENT_URI,
- new android.accounts.Account(amName, accountType),
- contactsSyncKey);
- LogUtils.w(LogUtils.TAG, "Set contacts key...");
- } catch (RemoteException e) {
- LogUtils.w(LogUtils.TAG, "Set contacts key FAILED");
- }
- }
-
- // That's all folks!
- LogUtils.w(LogUtils.TAG, "Account update completed.");
- } finally {
- // Clear the incomplete flag on the provider account
- accountValues.put(AccountColumns.FLAGS, oldFlags);
- resolver.update(accountUri, accountValues, null, null);
- LogUtils.w(LogUtils.TAG, "[Incomplete flag cleared]");
- }
- }
- } finally {
- c.close();
- }
- }
-
- private static void moveCalendarData(final ContentResolver resolver, final String name,
- final String oldType, final String newType) {
- final Uri oldCalendars = Calendars.CONTENT_URI.buildUpon()
- .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
- .appendQueryParameter(Calendars.ACCOUNT_NAME, name)
- .appendQueryParameter(Calendars.ACCOUNT_TYPE, oldType)
- .build();
-
- // Update this calendar to have the new account type.
- final ContentValues values = new ContentValues();
- values.put(CalendarContract.Calendars.ACCOUNT_TYPE, newType);
- resolver.update(oldCalendars, values,
- Calendars.ACCOUNT_NAME + "=? AND " + Calendars.ACCOUNT_TYPE + "=?",
- new String[] {name, oldType});
- }
-
- private static void moveContactsData(final ContentResolver resolver, final String name,
- final String oldType, final String newType) {
- final Uri oldContacts = RawContacts.CONTENT_URI.buildUpon()
- .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
- .appendQueryParameter(RawContacts.ACCOUNT_NAME, name)
- .appendQueryParameter(RawContacts.ACCOUNT_TYPE, oldType)
- .build();
-
- // Update this calendar to have the new account type.
- final ContentValues values = new ContentValues();
- values.put(CalendarContract.Calendars.ACCOUNT_TYPE, newType);
- resolver.update(oldContacts, values, null, null);
- }
-
- private static final Configuration sOldConfiguration = new Configuration();
- private static Map<String, EmailServiceInfo> sServiceMap = null;
- private static final Object sServiceMapLock = new Object();
-
- /**
- * Parse services.xml file to find our available email services
- */
- private static Map<String, EmailServiceInfo> getServiceMap(final Context context) {
- synchronized (sServiceMapLock) {
- /**
- * We cache localized strings here, so make sure to regenerate the service map if
- * the locale changes
- */
- if (sServiceMap == null) {
- sOldConfiguration.setTo(context.getResources().getConfiguration());
- }
-
- final int delta =
- sOldConfiguration.updateFrom(context.getResources().getConfiguration());
-
- if (sServiceMap != null
- && !Configuration.needNewResources(delta, ActivityInfo.CONFIG_LOCALE)) {
- return sServiceMap;
- }
-
- final ImmutableMap.Builder<String, EmailServiceInfo> builder = ImmutableMap.builder();
- if (!context.getResources().getBoolean(R.bool.enable_services)) {
- // Return an empty map if services have been disabled because this is the Email
- // Tombstone app.
- sServiceMap = builder.build();
- return sServiceMap;
- }
-
- try {
- final Resources res = context.getResources();
- final XmlResourceParser xml = res.getXml(R.xml.services);
- int xmlEventType;
- // walk through senders.xml file.
- while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) {
- if (xmlEventType == XmlResourceParser.START_TAG &&
- "emailservice".equals(xml.getName())) {
- final EmailServiceInfo info = new EmailServiceInfo();
- final TypedArray ta =
- res.obtainAttributes(xml, R.styleable.EmailServiceInfo);
- info.protocol = ta.getString(R.styleable.EmailServiceInfo_protocol);
- info.accountType = ta.getString(R.styleable.EmailServiceInfo_accountType);
- info.name = ta.getString(R.styleable.EmailServiceInfo_name);
- info.hide = ta.getBoolean(R.styleable.EmailServiceInfo_hide, false);
- final String klass =
- ta.getString(R.styleable.EmailServiceInfo_serviceClass);
- info.intentAction = ta.getString(R.styleable.EmailServiceInfo_intent);
- info.intentPackage =
- ta.getString(R.styleable.EmailServiceInfo_intentPackage);
- info.defaultSsl =
- ta.getBoolean(R.styleable.EmailServiceInfo_defaultSsl, false);
- info.port = ta.getInteger(R.styleable.EmailServiceInfo_port, 0);
- info.portSsl = ta.getInteger(R.styleable.EmailServiceInfo_portSsl, 0);
- info.offerTls = ta.getBoolean(R.styleable.EmailServiceInfo_offerTls, false);
- info.offerCerts =
- ta.getBoolean(R.styleable.EmailServiceInfo_offerCerts, false);
- info.offerOAuth =
- ta.getBoolean(R.styleable.EmailServiceInfo_offerOAuth, false);
- info.offerLocalDeletes =
- ta.getBoolean(R.styleable.EmailServiceInfo_offerLocalDeletes, false);
- info.defaultLocalDeletes =
- ta.getInteger(R.styleable.EmailServiceInfo_defaultLocalDeletes,
- Account.DELETE_POLICY_ON_DELETE);
- info.offerPrefix =
- ta.getBoolean(R.styleable.EmailServiceInfo_offerPrefix, false);
- info.usesSmtp = ta.getBoolean(R.styleable.EmailServiceInfo_usesSmtp, false);
- info.usesAutodiscover =
- ta.getBoolean(R.styleable.EmailServiceInfo_usesAutodiscover, false);
- info.offerLookback =
- ta.getBoolean(R.styleable.EmailServiceInfo_offerLookback, false);
- info.defaultLookback =
- ta.getInteger(R.styleable.EmailServiceInfo_defaultLookback,
- SyncWindow.SYNC_WINDOW_3_DAYS);
- info.syncChanges =
- ta.getBoolean(R.styleable.EmailServiceInfo_syncChanges, false);
- info.syncContacts =
- ta.getBoolean(R.styleable.EmailServiceInfo_syncContacts, false);
- info.syncCalendar =
- ta.getBoolean(R.styleable.EmailServiceInfo_syncCalendar, false);
- info.offerAttachmentPreload =
- ta.getBoolean(R.styleable.EmailServiceInfo_offerAttachmentPreload,
- false);
- info.syncIntervalStrings =
- ta.getTextArray(R.styleable.EmailServiceInfo_syncIntervalStrings);
- info.syncIntervals =
- ta.getTextArray(R.styleable.EmailServiceInfo_syncIntervals);
- info.defaultSyncInterval =
- ta.getInteger(R.styleable.EmailServiceInfo_defaultSyncInterval, 15);
- info.inferPrefix = ta.getString(R.styleable.EmailServiceInfo_inferPrefix);
- info.offerLoadMore =
- ta.getBoolean(R.styleable.EmailServiceInfo_offerLoadMore, false);
- info.offerMoveTo =
- ta.getBoolean(R.styleable.EmailServiceInfo_offerMoveTo, false);
- info.requiresSetup =
- ta.getBoolean(R.styleable.EmailServiceInfo_requiresSetup, false);
- info.isGmailStub =
- ta.getBoolean(R.styleable.EmailServiceInfo_isGmailStub, false);
-
- // Must have either "class" (local) or "intent" (remote)
- if (klass != null) {
- try {
- // noinspection unchecked
- info.klass = (Class<? extends Service>) Class.forName(klass);
- } catch (ClassNotFoundException e) {
- throw new IllegalStateException(
- "Class not found in service descriptor: " + klass);
- }
- }
- if (info.klass == null &&
- info.intentAction == null &&
- !info.isGmailStub) {
- throw new IllegalStateException(
- "No class or intent action specified in service descriptor");
- }
- if (info.klass != null && info.intentAction != null) {
- throw new IllegalStateException(
- "Both class and intent action specified in service descriptor");
- }
- builder.put(info.protocol, info);
- }
- }
- } catch (XmlPullParserException e) {
- // ignore
- } catch (IOException e) {
- // ignore
- }
- sServiceMap = builder.build();
- return sServiceMap;
- }
- }
-
- /**
- * Resolves a service name into a protocol name, or null if ambiguous
- * @param context for loading service map
- * @param accountType sync adapter service name
- * @return protocol name or null
- */
- public static @Nullable String getProtocolFromAccountType(final Context context,
- final String accountType) {
- if (TextUtils.isEmpty(accountType)) {
- return null;
- }
- final Map <String, EmailServiceInfo> serviceInfoMap = getServiceMap(context);
- String protocol = null;
- for (final EmailServiceInfo info : serviceInfoMap.values()) {
- if (TextUtils.equals(accountType, info.accountType)) {
- if (!TextUtils.isEmpty(protocol) && !TextUtils.equals(protocol, info.protocol)) {
- // More than one protocol matches
- return null;
- }
- protocol = info.protocol;
- }
- }
- return protocol;
- }
-
- private static Uri asCalendarSyncAdapter(Uri uri, String account, String accountType) {
- return uri.buildUpon().appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
- .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
- .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
- }
-
- /**
- * A no-op service that can be returned for non-existent/null protocols
- */
- class NullService implements IEmailService {
- @Override
- public IBinder asBinder() {
- return null;
- }
-
- @Override
- public Bundle validate(HostAuthCompat hostauth) throws RemoteException {
- return null;
- }
-
- @Override
- public void loadAttachment(final IEmailServiceCallback cb, final long accountId,
- final long attachmentId, final boolean background) throws RemoteException {
- }
-
- @Override
- public void updateFolderList(long accountId) throws RemoteException {}
-
- @Override
- public void setLogging(int flags) throws RemoteException {
- }
-
- @Override
- public Bundle autoDiscover(String userName, String password) throws RemoteException {
- return null;
- }
-
- @Override
- public void sendMeetingResponse(long messageId, int response) throws RemoteException {
- }
-
- @Override
- public void deleteExternalAccountPIMData(final String emailAddress) throws RemoteException {
- }
-
- @Override
- public int searchMessages(long accountId, SearchParams params, long destMailboxId)
- throws RemoteException {
- return 0;
- }
-
- @Override
- public void sendMail(long accountId) throws RemoteException {
- }
-
- @Override
- public void pushModify(long accountId) throws RemoteException {
- }
-
- @Override
- public int sync(final long accountId, final Bundle syncExtras) {
- return EmailServiceStatus.SUCCESS;
- }
-
- public int getApiVersion() {
- return EmailServiceVersion.CURRENT;
- }
- }
-
- public static void setComponentStatus(final Context context, Class<?> clazz, boolean enabled) {
- final ComponentName c = new ComponentName(context, clazz.getName());
- context.getPackageManager().setComponentEnabledSetting(c,
- enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
- : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- }
-
- /**
- * This is a helper function that enables the proper Exchange component and disables
- * the other Exchange component ensuring that only one is enabled at a time.
- */
- public static void enableExchangeComponent(final Context context) {
- if (VendorPolicyLoader.getInstance(context).useAlternateExchangeStrings()) {
- LogUtils.d(LogUtils.TAG, "Enabling alternate EAS authenticator");
- setComponentStatus(context, EasAuthenticatorServiceAlternate.class, true);
- setComponentStatus(context, EasAuthenticatorService.class, false);
- } else {
- LogUtils.d(LogUtils.TAG, "Enabling EAS authenticator");
- setComponentStatus(context, EasAuthenticatorService.class, true);
- setComponentStatus(context,
- EasAuthenticatorServiceAlternate.class, false);
- }
- }
-
- public static void disableExchangeComponents(final Context context) {
- LogUtils.d(LogUtils.TAG, "Disabling EAS authenticators");
- setComponentStatus(context, EasAuthenticatorServiceAlternate.class, false);
- setComponentStatus(context, EasAuthenticatorService.class, false);
- }
-
-}