diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a21a23d45..e982ec684 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -216,26 +216,18 @@
-
-
-
-
-
-
-
+
+
-
+
-
-
-
-
+
-
-
-
-
-
-
Android doesn't offer any mechanism to trigger an app right after installation, so we use the
- * BOOT_COMPLETED broadcast intent instead. This means, when the app is upgraded, the
- * initialization code here won't run until the device reboots.
- */
-public class OneTimeInitializer extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
- initialize(context);
- }
- }
-
- /**
- * Perform the one-time initialization.
- */
- private void initialize(Context context) {
- if (Config.LOGD) {
- Log.d(Email.LOG_TAG, "OneTimeInitializer: initializing...");
- }
- final Preferences pref = Preferences.getPreferences(context);
- int progress = pref.getOneTimeInitializationProgress();
-
- if (progress < 1) {
- progress = 1;
- if (VendorPolicyLoader.getInstance(context).useAlternateExchangeStrings()) {
- setComponentEnabled(context, EasAuthenticatorServiceAlternate.class, true);
- setComponentEnabled(context, EasAuthenticatorService.class, false);
- }
-
- ExchangeUtils.enableEasCalendarSync(context);
- }
-
- // If we need other initializations in the future...
- // - add your initialization code here, and
- // - rename this class to something like "OneTimeInitializer2" (and modify AndroidManifest
- // accordingly)
- // Renaming is necessary because once we disable a component, it won't be automatically
- // enabled again even when the app is upgraded.
-
- // Use "progress" to skip the initializations that's already done before.
- // Using this preference also makes it safe when a user skips an upgrade. (i.e. upgrading
- // version N to version N+2)
-
- // Save progress and disable itself.
- pref.setOneTimeInitializationProgress(progress);
- setComponentEnabled(context, getClass(), false);
- }
-
- private void setComponentEnabled(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);
- }
-}
diff --git a/src/com/android/email/service/BootReceiver.java b/src/com/android/email/service/BootReceiver.java
deleted file mode 100644
index 880773c2b..000000000
--- a/src/com/android/email/service/BootReceiver.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.android.email.AccountBackupRestore;
-import com.android.email.Email;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-public class BootReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // Restore accounts, if it has not happened already
- AccountBackupRestore.restoreAccountsIfNeeded(context);
-
- if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
- // Returns true if there are any accounts
- if (Email.setServicesEnabled(context)) {
- MailService.actionReschedule(context);
- }
- }
- else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(intent.getAction())) {
- MailService.actionCancel(context);
- }
- else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(intent.getAction())) {
- MailService.actionReschedule(context);
- }
- }
-}
diff --git a/src/com/android/email/service/EmailBroadcastProcessorService.java b/src/com/android/email/service/EmailBroadcastProcessorService.java
new file mode 100644
index 000000000..d1a9b98cf
--- /dev/null
+++ b/src/com/android/email/service/EmailBroadcastProcessorService.java
@@ -0,0 +1,137 @@
+/*
+ * 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 com.android.email.Email;
+import com.android.email.ExchangeUtils;
+import com.android.email.Preferences;
+import com.android.email.VendorPolicyLoader;
+
+import android.app.IntentService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.util.Config;
+import android.util.Log;
+
+/**
+ * The service that really handles broadcast intents on a worker thread.
+ *
+ * We make it a service, because:
+ *
+ * - So that it's less likely for the process to get killed.
+ *
- Even if it does, the Intent that have started it will be re-delivered by the system,
+ * and we can start the process again. (Using {@link #setIntentRedelivery}).
+ *
+ */
+public class EmailBroadcastProcessorService extends IntentService {
+ public EmailBroadcastProcessorService() {
+ // Class name will be the thread name.
+ super(EmailBroadcastProcessorService.class.getName());
+
+ // Intent should be redelivered if the process gets killed before completing the job.
+ setIntentRedelivery(true);
+ }
+
+ /**
+ * Entry point for {@link EmailBroadcastReceiver}.
+ */
+ public static void processBroadcastIntent(Context context, Intent broadcastIntent) {
+ Intent i = new Intent(context, EmailBroadcastProcessorService.class);
+ i.putExtra(Intent.EXTRA_INTENT, broadcastIntent);
+ context.startService(i);
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ // This method is called on a worker thread.
+
+ final Intent original = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+ final String action = original.getAction();
+
+ if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+ onBootCompleted();
+
+ // TODO: Do a better job when we get ACTION_DEVICE_STORAGE_LOW.
+ // The code below came from very old code....
+ } else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
+ // Stop IMAP/POP3 poll.
+ MailService.actionCancel(this);
+ } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
+ enableComponentsIfNecessary();
+ }
+ }
+
+ private void enableComponentsIfNecessary() {
+ if (Email.setServicesEnabled(this)) {
+ // At least one account exists.
+ // TODO probably we should check if it's a POP/IMAP account.
+ MailService.actionReschedule(this);
+ }
+ }
+
+ /**
+ * Handles {@link Intent#ACTION_BOOT_COMPLETED}. Called on a worker thread.
+ */
+ private void onBootCompleted() {
+ if (Config.LOGD) {
+ Log.d(Email.LOG_TAG, "BOOT_COMPLETED");
+ }
+ performOneTimeInitialization();
+
+ enableComponentsIfNecessary();
+
+ // Starts the service for Exchange, if supported.
+ ExchangeUtils.startExchangeService(this);
+ }
+
+ private void performOneTimeInitialization() {
+ final Preferences pref = Preferences.getPreferences(this);
+ int progress = pref.getOneTimeInitializationProgress();
+ final int initialProgress = progress;
+
+ if (progress < 1) {
+ Log.i(Email.LOG_TAG, "Onetime initialization: 1");
+ progress = 1;
+ if (VendorPolicyLoader.getInstance(this).useAlternateExchangeStrings()) {
+ setComponentEnabled(EasAuthenticatorServiceAlternate.class, true);
+ setComponentEnabled(EasAuthenticatorService.class, false);
+ }
+
+ ExchangeUtils.enableEasCalendarSync(this);
+ }
+
+ // Add your initialization steps here.
+ // Use "progress" to skip the initializations that's already done before.
+ // Using this preference also makes it safe when a user skips an upgrade. (i.e. upgrading
+ // version N to version N+2)
+
+ if (progress != initialProgress) {
+ pref.setOneTimeInitializationProgress(progress);
+ Log.i(Email.LOG_TAG, "Onetime initialization: completed.");
+ }
+ }
+
+ private void setComponentEnabled(Class> clazz, boolean enabled) {
+ final ComponentName c = new ComponentName(this, clazz.getName());
+ getPackageManager().setComponentEnabledSetting(c,
+ enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ }
+}
diff --git a/src/com/android/exchange/BootReceiver.java b/src/com/android/email/service/EmailBroadcastReceiver.java
similarity index 69%
rename from src/com/android/exchange/BootReceiver.java
rename to src/com/android/email/service/EmailBroadcastReceiver.java
index 1ebfa7bf1..ce7221043 100644
--- a/src/com/android/exchange/BootReceiver.java
+++ b/src/com/android/email/service/EmailBroadcastReceiver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * 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.
@@ -14,19 +14,18 @@
* limitations under the License.
*/
-package com.android.exchange;
-
-import com.android.email.ExchangeUtils;
+package com.android.email.service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.util.Log;
-public class BootReceiver extends BroadcastReceiver {
+/**
+ * The broadcast receiver. The actual job is done in EmailBroadcastProcessor on a worker thread.
+ */
+public class EmailBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- Log.d("Exchange", "BootReceiver onReceive");
- ExchangeUtils.startExchangeService(context);
+ EmailBroadcastProcessorService.processBroadcastIntent(context, intent);
}
}