EmailBroadcastProcessorService.java revision 314a51cb1d5bc538f069b6b13d8dffd575a5cc44
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 17package com.android.email.service; 18 19import com.android.email.Email; 20import com.android.email.ExchangeUtils; 21import com.android.email.Preferences; 22import com.android.email.SecurityPolicy; 23import com.android.email.VendorPolicyLoader; 24import com.android.email.activity.setup.AccountSettingsXL; 25import com.android.email.widget.WidgetManager; 26 27import android.accounts.AccountManager; 28import android.app.IntentService; 29import android.content.ComponentName; 30import android.content.Context; 31import android.content.Intent; 32import android.content.pm.PackageManager; 33import android.util.Log; 34 35/** 36 * The service that really handles broadcast intents on a worker thread. 37 * 38 * We make it a service, because: 39 * <ul> 40 * <li>So that it's less likely for the process to get killed. 41 * <li>Even if it does, the Intent that have started it will be re-delivered by the system, 42 * and we can start the process again. (Using {@link #setIntentRedelivery}). 43 * </ul> 44 * 45 * This also handles the DeviceAdminReceiver in SecurityPolicy, because it is also 46 * a BroadcastReceiver and requires the same processing semantics. 47 */ 48public class EmailBroadcastProcessorService extends IntentService { 49 // Action used for BroadcastReceiver entry point 50 private static final String ACTION_BROADCAST = "broadcast_receiver"; 51 52 // Dialing "*#*#36245#*#*" to open the debug screen. "36245" = "email" 53 private static final String ACTION_SECRET_CODE = "android.provider.Telephony.SECRET_CODE"; 54 private static final String SECRET_CODE_HOST_DEBUG_SCREEN = "36245"; 55 56 // This is a helper used to process DeviceAdminReceiver messages 57 private static final String ACTION_DEVICE_POLICY_ADMIN = "com.android.email.devicepolicy"; 58 private static final String EXTRA_DEVICE_POLICY_ADMIN = "message_code"; 59 60 public EmailBroadcastProcessorService() { 61 // Class name will be the thread name. 62 super(EmailBroadcastProcessorService.class.getName()); 63 64 // Intent should be redelivered if the process gets killed before completing the job. 65 setIntentRedelivery(true); 66 } 67 68 /** 69 * Entry point for {@link EmailBroadcastReceiver}. 70 */ 71 public static void processBroadcastIntent(Context context, Intent broadcastIntent) { 72 Intent i = new Intent(context, EmailBroadcastProcessorService.class); 73 i.setAction(ACTION_BROADCAST); 74 i.putExtra(Intent.EXTRA_INTENT, broadcastIntent); 75 context.startService(i); 76 } 77 78 /** 79 * Entry point for {@link com.android.email.SecurityPolicy.PolicyAdmin}. These will 80 * simply callback to {@link 81 * com.android.email.SecurityPolicy#onDeviceAdminReceiverMessage(Context, int)}. 82 */ 83 public static void processDevicePolicyMessage(Context context, int message) { 84 Intent i = new Intent(context, EmailBroadcastProcessorService.class); 85 i.setAction(ACTION_DEVICE_POLICY_ADMIN); 86 i.putExtra(EXTRA_DEVICE_POLICY_ADMIN, message); 87 context.startService(i); 88 } 89 90 @Override 91 protected void onHandleIntent(Intent intent) { 92 // This method is called on a worker thread. 93 94 // Dispatch from entry point 95 final String action = intent.getAction(); 96 if (ACTION_BROADCAST.equals(action)) { 97 final Intent broadcastIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT); 98 final String broadcastAction = broadcastIntent.getAction(); 99 100 if (Intent.ACTION_BOOT_COMPLETED.equals(broadcastAction)) { 101 onBootCompleted(); 102 103 // TODO: Do a better job when we get ACTION_DEVICE_STORAGE_LOW. 104 // The code below came from very old code.... 105 } else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(broadcastAction)) { 106 // Stop IMAP/POP3 poll. 107 MailService.actionCancel(this); 108 } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(broadcastAction)) { 109 enableComponentsIfNecessary(); 110 } else if (ACTION_SECRET_CODE.equals(broadcastAction) 111 && SECRET_CODE_HOST_DEBUG_SCREEN.equals(broadcastIntent.getData().getHost())) { 112 AccountSettingsXL.actionSettingsWithDebug(this); 113 } else if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(broadcastAction)) { 114 onSystemAccountChanged(); 115 } 116 } else if (ACTION_DEVICE_POLICY_ADMIN.equals(action)) { 117 int message = intent.getIntExtra(EXTRA_DEVICE_POLICY_ADMIN, -1); 118 SecurityPolicy.onDeviceAdminReceiverMessage(this, message); 119 } 120 } 121 122 private void enableComponentsIfNecessary() { 123 if (Email.setServicesEnabledSync(this)) { 124 // At least one account exists. 125 // TODO probably we should check if it's a POP/IMAP account. 126 MailService.actionReschedule(this); 127 } 128 } 129 130 /** 131 * Handles {@link Intent#ACTION_BOOT_COMPLETED}. Called on a worker thread. 132 */ 133 private void onBootCompleted() { 134 performOneTimeInitialization(); 135 136 enableComponentsIfNecessary(); 137 138 // Starts the service for Exchange, if supported. 139 ExchangeUtils.startExchangeService(this); 140 } 141 142 private void performOneTimeInitialization() { 143 final Preferences pref = Preferences.getPreferences(this); 144 int progress = pref.getOneTimeInitializationProgress(); 145 final int initialProgress = progress; 146 147 if (progress < 1) { 148 Log.i(Email.LOG_TAG, "Onetime initialization: 1"); 149 progress = 1; 150 if (VendorPolicyLoader.getInstance(this).useAlternateExchangeStrings()) { 151 setComponentEnabled(EasAuthenticatorServiceAlternate.class, true); 152 setComponentEnabled(EasAuthenticatorService.class, false); 153 } 154 155 ExchangeUtils.enableEasCalendarSync(this); 156 } 157 158 // Add your initialization steps here. 159 // Use "progress" to skip the initializations that's already done before. 160 // Using this preference also makes it safe when a user skips an upgrade. (i.e. upgrading 161 // version N to version N+2) 162 163 if (progress != initialProgress) { 164 pref.setOneTimeInitializationProgress(progress); 165 Log.i(Email.LOG_TAG, "Onetime initialization: completed."); 166 } 167 } 168 169 private void setComponentEnabled(Class<?> clazz, boolean enabled) { 170 final ComponentName c = new ComponentName(this, clazz.getName()); 171 getPackageManager().setComponentEnabledSetting(c, 172 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 173 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 174 PackageManager.DONT_KILL_APP); 175 } 176 177 private void onSystemAccountChanged() { 178 Log.i(Email.LOG_TAG, "System accouns updated."); 179 MailService.reconcilePopImapAccountsSync(this); 180 181 // Let ExchangeService reconcile EAS accouts. 182 // The service will stops itself it there's no EAS accounts. 183 ExchangeUtils.startExchangeService(this); 184 185 // Let all of the widgets update 186 WidgetManager.getInstance().updateAllWidgets(); 187 } 188} 189