1b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki/* 2b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * Copyright (C) 2010 The Android Open Source Project 3b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * 4b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 5b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * you may not use this file except in compliance with the License. 6b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * You may obtain a copy of the License at 7b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * 8b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 9b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * 10b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * Unless required by applicable law or agreed to in writing, software 11b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 12b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * See the License for the specific language governing permissions and 14b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * limitations under the License. 15b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki */ 16b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 17b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukipackage com.android.email; 18b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 19b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport com.android.email.service.EasAuthenticatorService; 20b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport com.android.email.service.EasAuthenticatorServiceAlternate; 21b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 22b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport android.content.BroadcastReceiver; 23b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport android.content.ComponentName; 24b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport android.content.Context; 25b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport android.content.Intent; 26b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport android.content.pm.PackageManager; 27b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport android.util.Config; 28b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukiimport android.util.Log; 29b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 30b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki/** 31b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * A class that performs one-time initialization after installation. 32b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * 33b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * <p>Android doesn't offer any mechanism to trigger an app right after installation, so we use the 34b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * BOOT_COMPLETED broadcast intent instead. This means, when the app is upgraded, the 35b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * initialization code here won't run until the device reboots. 36b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki */ 37b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onukipublic class OneTimeInitializer extends BroadcastReceiver { 38b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 39b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki @Override 40b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki public void onReceive(Context context, Intent intent) { 41b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { 42b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki initialize(context); 43b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki } 44b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki } 45b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 46b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki /** 47b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki * Perform the one-time initialization. 48b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki */ 49b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki private void initialize(Context context) { 50b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki if (Config.LOGD) { 51b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki Log.d(Email.LOG_TAG, "OneTimeInitializer: initializing..."); 52b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki } 53b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki final Preferences pref = Preferences.getPreferences(context); 54b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki int progress = pref.getOneTimeInitializationProgress(); 55b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 56b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki if (progress < 1) { 57b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki progress = 1; 58b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki if (VendorPolicyLoader.getInstance(context).useAlternateExchangeStrings()) { 59b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki setComponentEnabled(context, EasAuthenticatorServiceAlternate.class, true); 60b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki setComponentEnabled(context, EasAuthenticatorService.class, false); 61b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki } 62c18f8f615f134a2b391d06e2d8d49434a8bb94e5Makoto Onuki 63c18f8f615f134a2b391d06e2d8d49434a8bb94e5Makoto Onuki ExchangeUtils.enableEasCalendarSync(context); 64b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki } 65b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 66b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // If we need other initializations in the future... 67b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // - add your initialization code here, and 68b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // - rename this class to something like "OneTimeInitializer2" (and modify AndroidManifest 69b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // accordingly) 70b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // Renaming is necessary because once we disable a component, it won't be automatically 71b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // enabled again even when the app is upgraded. 72b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 73b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // Use "progress" to skip the initializations that's already done before. 74b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // Using this preference also makes it safe when a user skips an upgrade. (i.e. upgrading 75b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // version N to version N+2) 76b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 77b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki // Save progress and disable itself. 78b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki pref.setOneTimeInitializationProgress(progress); 79b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki setComponentEnabled(context, getClass(), false); 80b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki } 81b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki 82b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki private void setComponentEnabled(Context context, Class<?> clazz, boolean enabled) { 83b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki final ComponentName c = new ComponentName(context, clazz.getName()); 84b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki context.getPackageManager().setComponentEnabledSetting(c, 85b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 86b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 87b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki PackageManager.DONT_KILL_APP); 88b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki } 89b854d05a89e1d2be7c3d3465727a90df1d289e30Makoto Onuki} 90