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 17 package com.android.email.service; 18 19 import com.android.email.Email; 20 import com.android.email.ExchangeUtils; 21 import com.android.email.Preferences; 22 import com.android.email.VendorPolicyLoader; 23 24 import android.app.IntentService; 25 import android.content.ComponentName; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.pm.PackageManager; 29 import android.util.Config; 30 import android.util.Log; 31 32 /** 33 * The service that really handles broadcast intents on a worker thread. 34 * 35 * We make it a service, because: 36 * <ul> 37 * <li>So that it's less likely for the process to get killed. 38 * <li>Even if it does, the Intent that have started it will be re-delivered by the system, 39 * and we can start the process again. (Using {@link #setIntentRedelivery}). 40 * </ul> 41 */ 42 public class EmailBroadcastProcessorService extends IntentService { 43 public EmailBroadcastProcessorService() { 44 // Class name will be the thread name. 45 super(EmailBroadcastProcessorService.class.getName()); 46 47 // Intent should be redelivered if the process gets killed before completing the job. 48 setIntentRedelivery(true); 49 } 50 51 /** 52 * Entry point for {@link EmailBroadcastReceiver}. 53 */ 54 public static void processBroadcastIntent(Context context, Intent broadcastIntent) { 55 Intent i = new Intent(context, EmailBroadcastProcessorService.class); 56 i.putExtra(Intent.EXTRA_INTENT, broadcastIntent); 57 context.startService(i); 58 } 59 60 @Override 61 protected void onHandleIntent(Intent intent) { 62 // This method is called on a worker thread. 63 64 final Intent original = intent.getParcelableExtra(Intent.EXTRA_INTENT); 65 final String action = original.getAction(); 66 67 if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { 68 onBootCompleted(); 69 70 // TODO: Do a better job when we get ACTION_DEVICE_STORAGE_LOW. 71 // The code below came from very old code.... 72 } else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) { 73 // Stop IMAP/POP3 poll. 74 MailService.actionCancel(this); 75 } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) { 76 enableComponentsIfNecessary(); 77 } 78 } 79 80 private void enableComponentsIfNecessary() { 81 if (Email.setServicesEnabled(this)) { 82 // At least one account exists. 83 // TODO probably we should check if it's a POP/IMAP account. 84 MailService.actionReschedule(this); 85 } 86 } 87 88 /** 89 * Handles {@link Intent#ACTION_BOOT_COMPLETED}. Called on a worker thread. 90 */ 91 private void onBootCompleted() { 92 if (Config.LOGD) { 93 Log.d(Email.LOG_TAG, "BOOT_COMPLETED"); 94 } 95 performOneTimeInitialization(); 96 97 enableComponentsIfNecessary(); 98 99 // Starts the service for Exchange, if supported. 100 ExchangeUtils.startExchangeService(this); 101 } 102 103 private void performOneTimeInitialization() { 104 final Preferences pref = Preferences.getPreferences(this); 105 int progress = pref.getOneTimeInitializationProgress(); 106 final int initialProgress = progress; 107 108 if (progress < 1) { 109 Log.i(Email.LOG_TAG, "Onetime initialization: 1"); 110 progress = 1; 111 if (VendorPolicyLoader.getInstance(this).useAlternateExchangeStrings()) { 112 setComponentEnabled(EasAuthenticatorServiceAlternate.class, true); 113 setComponentEnabled(EasAuthenticatorService.class, false); 114 } 115 116 ExchangeUtils.enableEasCalendarSync(this); 117 } 118 119 // Add your initialization steps here. 120 // Use "progress" to skip the initializations that's already done before. 121 // Using this preference also makes it safe when a user skips an upgrade. (i.e. upgrading 122 // version N to version N+2) 123 124 if (progress != initialProgress) { 125 pref.setOneTimeInitializationProgress(progress); 126 Log.i(Email.LOG_TAG, "Onetime initialization: completed."); 127 } 128 } 129 130 private void setComponentEnabled(Class<?> clazz, boolean enabled) { 131 final ComponentName c = new ComponentName(this, clazz.getName()); 132 getPackageManager().setComponentEnabledSetting(c, 133 enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 134 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 135 PackageManager.DONT_KILL_APP); 136 } 137 } 138