EmailBroadcastProcessorService.java revision f53490dc86f5a61ab09024dc4938ce8419c61fc5
1898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki/*
2898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * Copyright (C) 2010 The Android Open Source Project
3898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki *
4898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License");
5898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * you may not use this file except in compliance with the License.
6898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * You may obtain a copy of the License at
7898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki *
8898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki *      http://www.apache.org/licenses/LICENSE-2.0
9898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki *
10898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * Unless required by applicable law or agreed to in writing, software
11898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS,
12898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * See the License for the specific language governing permissions and
14898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * limitations under the License.
15898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki */
16898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
17898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onukipackage com.android.email.service;
18898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
19c50b6f685ba26a38b8110f6ca0115b12f84d643cMakoto Onukiimport android.accounts.AccountManager;
20898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onukiimport android.app.IntentService;
21898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onukiimport android.content.ComponentName;
228c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedyimport android.content.ContentResolver;
238c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedyimport android.content.ContentUris;
248c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedyimport android.content.ContentValues;
25898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onukiimport android.content.Context;
26898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onukiimport android.content.Intent;
27898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onukiimport android.content.pm.PackageManager;
288c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedyimport android.database.Cursor;
298c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedyimport android.net.Uri;
30898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onukiimport android.util.Log;
31898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
32f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.email.NotificationController;
3366a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.email.Preferences;
3466a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.email.SecurityPolicy;
3566a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.email.activity.setup.AccountSettings;
36f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blankimport com.android.email.service.EmailServiceUtils.EmailServiceInfo;
3766a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.emailcommon.Logging;
38c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport com.android.emailcommon.VendorPolicyLoader;
3966a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.emailcommon.provider.Account;
4066a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.emailcommon.provider.EmailContent.AccountColumns;
4166a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blankimport com.android.emailcommon.provider.HostAuth;
4266a47b8dac5e97e37c30b928bc5a227d74baada9Marc Blank
43f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blankimport java.util.List;
44f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blank
45898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki/**
46898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * The service that really handles broadcast intents on a worker thread.
47898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki *
48898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * We make it a service, because:
49898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * <ul>
50898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki *   <li>So that it's less likely for the process to get killed.
51898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki *   <li>Even if it does, the Intent that have started it will be re-delivered by the system,
52898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki *   and we can start the process again.  (Using {@link #setIntentRedelivery}).
53898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki * </ul>
54a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler *
55a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler * This also handles the DeviceAdminReceiver in SecurityPolicy, because it is also
56a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler * a BroadcastReceiver and requires the same processing semantics.
57898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki */
58898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onukipublic class EmailBroadcastProcessorService extends IntentService {
59a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    // Action used for BroadcastReceiver entry point
60a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    private static final String ACTION_BROADCAST = "broadcast_receiver";
61a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler
6242e3f10a9575e277ba6f121e6cac56ddb02fda12Makoto Onuki    // Dialing "*#*#36245#*#*" to open the debug screen.   "36245" = "email"
63a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    private static final String ACTION_SECRET_CODE = "android.provider.Telephony.SECRET_CODE";
6442e3f10a9575e277ba6f121e6cac56ddb02fda12Makoto Onuki    private static final String SECRET_CODE_HOST_DEBUG_SCREEN = "36245";
6542e3f10a9575e277ba6f121e6cac56ddb02fda12Makoto Onuki
66a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    // This is a helper used to process DeviceAdminReceiver messages
67a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    private static final String ACTION_DEVICE_POLICY_ADMIN = "com.android.email.devicepolicy";
68a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    private static final String EXTRA_DEVICE_POLICY_ADMIN = "message_code";
69a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler
70f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    // Broadcast received to initiate new message notification updates
71f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    public static final String ACTION_NOTIFY_NEW_MAIL =
72f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            "com.android.mail.action.update_notification";
73f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
74898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    public EmailBroadcastProcessorService() {
75898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        // Class name will be the thread name.
76898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        super(EmailBroadcastProcessorService.class.getName());
77898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
78898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        // Intent should be redelivered if the process gets killed before completing the job.
79898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        setIntentRedelivery(true);
80898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    }
81898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
82898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    /**
83898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki     * Entry point for {@link EmailBroadcastReceiver}.
84898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki     */
85898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    public static void processBroadcastIntent(Context context, Intent broadcastIntent) {
86898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        Intent i = new Intent(context, EmailBroadcastProcessorService.class);
87a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        i.setAction(ACTION_BROADCAST);
88898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        i.putExtra(Intent.EXTRA_INTENT, broadcastIntent);
89898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        context.startService(i);
90898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    }
91898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
92a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    /**
93a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler     * Entry point for {@link com.android.email.SecurityPolicy.PolicyAdmin}.  These will
94a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler     * simply callback to {@link
95a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler     * com.android.email.SecurityPolicy#onDeviceAdminReceiverMessage(Context, int)}.
96a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler     */
97a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    public static void processDevicePolicyMessage(Context context, int message) {
98a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        Intent i = new Intent(context, EmailBroadcastProcessorService.class);
99a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        i.setAction(ACTION_DEVICE_POLICY_ADMIN);
100a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        i.putExtra(EXTRA_DEVICE_POLICY_ADMIN, message);
101a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        context.startService(i);
102a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler    }
103a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler
104898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    @Override
105898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    protected void onHandleIntent(Intent intent) {
106898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        // This method is called on a worker thread.
107898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
108a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        // Dispatch from entry point
109a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        final String action = intent.getAction();
110a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        if (ACTION_BROADCAST.equals(action)) {
111a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler            final Intent broadcastIntent = intent.getParcelableExtra(Intent.EXTRA_INTENT);
112a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler            final String broadcastAction = broadcastIntent.getAction();
113898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
114a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler            if (Intent.ACTION_BOOT_COMPLETED.equals(broadcastAction)) {
115a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler                onBootCompleted();
11603cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank            } else if (ACTION_SECRET_CODE.equals(broadcastAction)
117a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler                    && SECRET_CODE_HOST_DEBUG_SCREEN.equals(broadcastIntent.getData().getHost())) {
1182866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo                AccountSettings.actionSettingsWithDebug(this);
119c50b6f685ba26a38b8110f6ca0115b12f84d643cMakoto Onuki            } else if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(broadcastAction)) {
120c50b6f685ba26a38b8110f6ca0115b12f84d643cMakoto Onuki                onSystemAccountChanged();
121f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            } else if (ACTION_NOTIFY_NEW_MAIL.equals(broadcastAction)) {
122f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                NotificationController.notifyNewMail(this, broadcastIntent);
123a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler            }
124a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler        } else if (ACTION_DEVICE_POLICY_ADMIN.equals(action)) {
125a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler            int message = intent.getIntExtra(EXTRA_DEVICE_POLICY_ADMIN, -1);
126a2269e84c6134bfd3506e5489c7ccfd60c32d41fAndy Stadler            SecurityPolicy.onDeviceAdminReceiverMessage(this, message);
127898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        }
128898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    }
129898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
130898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    /**
131898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki     * Handles {@link Intent#ACTION_BOOT_COMPLETED}.  Called on a worker thread.
132898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki     */
133898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    private void onBootCompleted() {
134898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        performOneTimeInitialization();
135f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blank        reconcileAndStartServices();
136f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blank    }
137898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
138f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blank    private void reconcileAndStartServices() {
139f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blank        // Reconcile accounts
140f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blank        MailService.reconcileLocalAccountsSync(this);
141f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // Starts remote services, if any
142f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        EmailServiceUtils.startRemoteServices(this);
143898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    }
144898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
145898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    private void performOneTimeInitialization() {
146898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        final Preferences pref = Preferences.getPreferences(this);
147898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        int progress = pref.getOneTimeInitializationProgress();
148898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        final int initialProgress = progress;
149898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
150898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        if (progress < 1) {
15131d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blank            Log.i(Logging.LOG_TAG, "Onetime initialization: 1");
152898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki            progress = 1;
153898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki            if (VendorPolicyLoader.getInstance(this).useAlternateExchangeStrings()) {
154898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki                setComponentEnabled(EasAuthenticatorServiceAlternate.class, true);
155898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki                setComponentEnabled(EasAuthenticatorService.class, false);
156898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki            }
157898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        }
158898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
1598c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy        if (progress < 2) {
1608c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy            Log.i(Logging.LOG_TAG, "Onetime initialization: 2");
1618c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy            progress = 2;
1628c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy            setImapDeletePolicy(this);
1638c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy        }
1648c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy
165898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        // Add your initialization steps here.
166898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        // Use "progress" to skip the initializations that's already done before.
167898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        // Using this preference also makes it safe when a user skips an upgrade.  (i.e. upgrading
168898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        // version N to version N+2)
169898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
170898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        if (progress != initialProgress) {
171898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki            pref.setOneTimeInitializationProgress(progress);
17231d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blank            Log.i(Logging.LOG_TAG, "Onetime initialization: completed.");
173898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        }
174898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    }
175898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki
1768c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy    /**
1778c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy     * Sets the delete policy to the correct value for all IMAP accounts. This will have no
1788c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy     * effect on either EAS or POP3 accounts.
1798c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy     */
1808c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy    /*package*/ static void setImapDeletePolicy(Context context) {
1818c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy        ContentResolver resolver = context.getContentResolver();
1828c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy        Cursor c = resolver.query(Account.CONTENT_URI, Account.CONTENT_PROJECTION,
1838c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                null, null, null);
1848c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy        try {
1858c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy            while (c.moveToNext()) {
1868c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                long recvAuthKey = c.getLong(Account.CONTENT_HOST_AUTH_KEY_RECV_COLUMN);
1878c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                HostAuth recvAuth = HostAuth.restoreHostAuthWithId(context, recvAuthKey);
188f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                if (HostAuth.LEGACY_SCHEME_IMAP.equals(recvAuth.mProtocol)) {
1898c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                    int flags = c.getInt(Account.CONTENT_FLAGS_COLUMN);
1908c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                    flags &= ~Account.FLAGS_DELETE_POLICY_MASK;
1918c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                    flags |= Account.DELETE_POLICY_ON_DELETE << Account.FLAGS_DELETE_POLICY_SHIFT;
1928c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                    ContentValues cv = new ContentValues();
1938c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                    cv.put(AccountColumns.FLAGS, flags);
1948c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                    long accountId = c.getLong(Account.CONTENT_ID_COLUMN);
1958c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                    Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, accountId);
1968c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                    resolver.update(uri, cv, null, null);
1978c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy                }
1988c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy            }
1998c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy        } finally {
2008c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy            c.close();
2018c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy        }
2028c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy    }
2038c89674b64f6669fa94bf593abad0f1e2255a812Todd Kennedy
204898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    private void setComponentEnabled(Class<?> clazz, boolean enabled) {
205898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        final ComponentName c = new ComponentName(this, clazz.getName());
206898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki        getPackageManager().setComponentEnabledSetting(c,
207898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki                enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
208898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki                        : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
209898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki                PackageManager.DONT_KILL_APP);
210898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki    }
211c50b6f685ba26a38b8110f6ca0115b12f84d643cMakoto Onuki
212c50b6f685ba26a38b8110f6ca0115b12f84d643cMakoto Onuki    private void onSystemAccountChanged() {
21325ab2df296d524671616831122f9a3c59132ae51Marc Blank        Log.i(Logging.LOG_TAG, "System accounts updated.");
214f53490dc86f5a61ab09024dc4938ce8419c61fc5Marc Blank        reconcileAndStartServices();
215c50b6f685ba26a38b8110f6ca0115b12f84d643cMakoto Onuki    }
216898283b6fa4f141d5c2a0831b96b19de11d587b3Makoto Onuki}
217