MailService.java revision cc0185f07c9198008d8dc685ae9979f3e35e8539
1/* 2 * Copyright (C) 2008 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 17package com.android.email.service; 18 19import android.accounts.AccountManager; 20import android.accounts.AccountManagerCallback; 21import android.app.Service; 22import android.content.Context; 23import android.content.Intent; 24import android.database.Cursor; 25import android.os.Bundle; 26import android.os.IBinder; 27 28import com.android.email.SingleRunningTask; 29import com.android.email.provider.AccountReconciler; 30import com.android.email.service.EmailServiceUtils.EmailServiceInfo; 31import com.android.email2.ui.MailActivityEmail; 32import com.android.emailcommon.AccountManagerTypes; 33import com.android.emailcommon.provider.Account; 34import com.android.emailcommon.provider.HostAuth; 35import com.android.emailcommon.utility.EmailAsyncTask; 36import com.google.common.annotations.VisibleForTesting; 37 38import java.util.ArrayList; 39import java.util.List; 40 41/** 42 * Legacy service, now used mainly for account reconciliation 43 */ 44public class MailService extends Service { 45 46 @Override 47 public int onStartCommand(final Intent intent, int flags, final int startId) { 48 super.onStartCommand(intent, flags, startId); 49 50 EmailAsyncTask.runAsyncParallel(new Runnable() { 51 @Override 52 public void run() { 53 reconcilePopImapAccountsSync(MailService.this); 54 } 55 }); 56 57 // Make sure our services are running, if necessary 58 MailActivityEmail.setServicesEnabledAsync(this); 59 60 // Returning START_NOT_STICKY means that if a mail check is killed (e.g. due to memory 61 // pressure, there will be no explicit restart. This is OK; Note that we set a watchdog 62 // alarm before each mailbox check. If the mailbox check never completes, the watchdog 63 // will fire and get things running again. 64 return START_NOT_STICKY; 65 } 66 67 @Override 68 public IBinder onBind(Intent intent) { 69 return null; 70 } 71 72 public static ArrayList<Account> getPopImapAccountList(Context context) { 73 ArrayList<Account> providerAccounts = new ArrayList<Account>(); 74 Cursor c = context.getContentResolver().query(Account.CONTENT_URI, Account.ID_PROJECTION, 75 null, null, null); 76 try { 77 while (c.moveToNext()) { 78 long accountId = c.getLong(Account.CONTENT_ID_COLUMN); 79 String protocol = Account.getProtocol(context, accountId); 80 EmailServiceInfo info = EmailServiceUtils.getServiceInfo(context, protocol); 81 if ((info != null) && info.accountType.equals(AccountManagerTypes.TYPE_POP_IMAP)) { 82 Account account = Account.restoreAccountWithId(context, accountId); 83 if (account != null) { 84 providerAccounts.add(account); 85 } 86 } 87 } 88 } finally { 89 c.close(); 90 } 91 return providerAccounts; 92 } 93 94 private static final SingleRunningTask<Context> sReconcilePopImapAccountsSyncExecutor = 95 new SingleRunningTask<Context>("ReconcilePopImapAccountsSync") { 96 @Override 97 protected void runInternal(Context context) { 98 android.accounts.Account[] accountManagerAccounts = AccountManager.get(context) 99 .getAccountsByType(AccountManagerTypes.TYPE_POP_IMAP); 100 ArrayList<Account> providerAccounts = getPopImapAccountList(context); 101 MailService.reconcileAccountsWithAccountManager(context, providerAccounts, 102 accountManagerAccounts, context); 103 104 } 105 }; 106 107 /** 108 * Reconcile POP/IMAP accounts. 109 */ 110 public static void reconcilePopImapAccountsSync(Context context) { 111 sReconcilePopImapAccountsSyncExecutor.run(context); 112 } 113 114 /** 115 * Determines whether or not POP/IMAP accounts need reconciling or not. This is a safe operation 116 * to perform on the UI thread. 117 */ 118 public static boolean hasMismatchInPopImapAccounts(Context context) { 119 android.accounts.Account[] accountManagerAccounts = AccountManager.get(context) 120 .getAccountsByType(AccountManagerTypes.TYPE_POP_IMAP); 121 ArrayList<Account> providerAccounts = getPopImapAccountList(context); 122 return AccountReconciler.accountsNeedReconciling( 123 context, providerAccounts, accountManagerAccounts); 124 } 125 126 /** 127 * See Utility.reconcileAccounts for details 128 * @param context The context in which to operate 129 * @param emailProviderAccounts the exchange provider accounts to work from 130 * @param accountManagerAccounts The account manager accounts to work from 131 * @param providerContext the provider's context (in unit tests, this may differ from context) 132 */ 133 @VisibleForTesting 134 public static void reconcileAccountsWithAccountManager(Context context, 135 List<Account> emailProviderAccounts, android.accounts.Account[] accountManagerAccounts, 136 Context providerContext) { 137 AccountReconciler.reconcileAccounts(context, emailProviderAccounts, accountManagerAccounts, 138 providerContext); 139 } 140 141 public static void setupAccountManagerAccount(Context context, Account account, 142 boolean email, boolean calendar, boolean contacts, 143 AccountManagerCallback<Bundle> callback) { 144 Bundle options = new Bundle(); 145 HostAuth hostAuthRecv = HostAuth.restoreHostAuthWithId(context, account.mHostAuthKeyRecv); 146 if (hostAuthRecv == null) return; 147 // Set up username/password 148 options.putString(EasAuthenticatorService.OPTIONS_USERNAME, account.mEmailAddress); 149 options.putString(EasAuthenticatorService.OPTIONS_PASSWORD, hostAuthRecv.mPassword); 150 options.putBoolean(EasAuthenticatorService.OPTIONS_CONTACTS_SYNC_ENABLED, contacts); 151 options.putBoolean(EasAuthenticatorService.OPTIONS_CALENDAR_SYNC_ENABLED, calendar); 152 options.putBoolean(EasAuthenticatorService.OPTIONS_EMAIL_SYNC_ENABLED, email); 153 EmailServiceInfo info = EmailServiceUtils.getServiceInfo(context, hostAuthRecv.mProtocol); 154 AccountManager.get(context).addAccount(info.accountType, null, null, options, null, 155 callback, null); 156 } 157} 158