1d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani/*
2d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * Copyright (C) 2012 The Android Open Source Project
3d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani *
4d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
5d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * you may not use this file except in compliance with the License.
6d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * You may obtain a copy of the License at
7d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani *
8d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
9d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani *
10d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * Unless required by applicable law or agreed to in writing, software
11d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
12d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * See the License for the specific language governing permissions and
14d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani * limitations under the License.
15d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani */
16d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
17d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasanipackage com.android.settings.accounts;
18d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
19af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghinaimport com.google.android.collect.Maps;
20af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina
21d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.accounts.Account;
22d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.accounts.AccountManager;
23d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.accounts.AuthenticatorDescription;
243939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghinaimport android.content.BroadcastReceiver;
25af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghinaimport android.content.ContentResolver;
26d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.content.Context;
273939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghinaimport android.content.Intent;
283939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghinaimport android.content.IntentFilter;
29af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghinaimport android.content.SyncAdapterType;
30d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.content.pm.PackageManager;
31d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.content.res.Resources;
32d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.graphics.drawable.Drawable;
332972c0136de098a7721555821bfb7451324b33caAmith Yamasaniimport android.os.AsyncTask;
343939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghinaimport android.os.UserHandle;
353939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghinaimport android.os.UserManager;
36d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.util.Log;
37d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
38d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport java.util.ArrayList;
39d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport java.util.HashMap;
40d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport java.util.Map;
41d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
423939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina/**
433939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina * Helper class for monitoring accounts on the device for a given user.
443939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina *
453939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina * Classes using this helper should implement {@link OnAccountsUpdateListener}.
463939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina * {@link OnAccountsUpdateListener#onAccountsUpdate(UserHandle)} will then be
473939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina * called once accounts get updated. For setting up listening for account
483939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina * updates, {@link #listenToAccountUpdates()} and
493939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina * {@link #stopListeningToAccountUpdates()} should be used.
503939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina */
513939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghinafinal public class AuthenticatorHelper extends BroadcastReceiver {
52c8a9317649d59fb3e2fc7540aedba22a53900895Amith Yamasani    private static final String TAG = "AuthenticatorHelper";
533939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina
54d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private Map<String, AuthenticatorDescription> mTypeToAuthDescription
55d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            = new HashMap<String, AuthenticatorDescription>();
56d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private AuthenticatorDescription[] mAuthDescs;
57d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private ArrayList<String> mEnabledAccountTypes = new ArrayList<String>();
58d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private Map<String, Drawable> mAccTypeIconCache = new HashMap<String, Drawable>();
59af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina    private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = Maps.newHashMap();
60d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
613939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    private final UserHandle mUserHandle;
623939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    private final UserManager mUm;
633939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    private final Context mContext;
643939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    private final OnAccountsUpdateListener mListener;
653939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    private boolean mListeningToAccountUpdates;
663939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina
673939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    public interface OnAccountsUpdateListener {
683939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        void onAccountsUpdate(UserHandle userHandle);
693939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    }
703939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina
713939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    public AuthenticatorHelper(Context context, UserHandle userHandle, UserManager userManager,
723939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            OnAccountsUpdateListener listener) {
733939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        mContext = context;
743939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        mUm = userManager;
753939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        mUserHandle = userHandle;
763939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        mListener = listener;
77af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina        // This guarantees that the helper is ready to use once constructed: the account types and
78af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina        // authorities are initialized
793939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        onAccountsUpdated(null);
80d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    }
81d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
82d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    public String[] getEnabledAccountTypes() {
83d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        return mEnabledAccountTypes.toArray(new String[mEnabledAccountTypes.size()]);
84d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    }
85d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
862972c0136de098a7721555821bfb7451324b33caAmith Yamasani    public void preloadDrawableForType(final Context context, final String accountType) {
872972c0136de098a7721555821bfb7451324b33caAmith Yamasani        new AsyncTask<Void, Void, Void>() {
882972c0136de098a7721555821bfb7451324b33caAmith Yamasani            @Override
892972c0136de098a7721555821bfb7451324b33caAmith Yamasani            protected Void doInBackground(Void... params) {
902972c0136de098a7721555821bfb7451324b33caAmith Yamasani                getDrawableForType(context, accountType);
912972c0136de098a7721555821bfb7451324b33caAmith Yamasani                return null;
922972c0136de098a7721555821bfb7451324b33caAmith Yamasani            }
932972c0136de098a7721555821bfb7451324b33caAmith Yamasani        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
942972c0136de098a7721555821bfb7451324b33caAmith Yamasani    }
952972c0136de098a7721555821bfb7451324b33caAmith Yamasani
96d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    /**
97d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     * Gets an icon associated with a particular account type. If none found, return null.
98d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     * @param accountType the type of account
99d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     * @return a drawable for the icon or null if one cannot be found.
100d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     */
101d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    public Drawable getDrawableForType(Context context, final String accountType) {
102d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        Drawable icon = null;
1032972c0136de098a7721555821bfb7451324b33caAmith Yamasani        synchronized (mAccTypeIconCache) {
1042972c0136de098a7721555821bfb7451324b33caAmith Yamasani            if (mAccTypeIconCache.containsKey(accountType)) {
1052972c0136de098a7721555821bfb7451324b33caAmith Yamasani                return mAccTypeIconCache.get(accountType);
1062972c0136de098a7721555821bfb7451324b33caAmith Yamasani            }
107d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        }
108d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        if (mTypeToAuthDescription.containsKey(accountType)) {
109d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            try {
110d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
111ce0b22cf90cf99377f63b1aa4d4720f69a6edd7bAlexandra Gherghina                Context authContext = context.createPackageContextAsUser(desc.packageName, 0,
112ce0b22cf90cf99377f63b1aa4d4720f69a6edd7bAlexandra Gherghina                        mUserHandle);
11330c50b15d0d716567c71d590aa835dc4a27591d6Amith Yamasani                icon = mContext.getPackageManager().getUserBadgedIcon(
11430c50b15d0d716567c71d590aa835dc4a27591d6Amith Yamasani                        authContext.getResources().getDrawable(desc.iconId), mUserHandle);
1152972c0136de098a7721555821bfb7451324b33caAmith Yamasani                synchronized (mAccTypeIconCache) {
1162972c0136de098a7721555821bfb7451324b33caAmith Yamasani                    mAccTypeIconCache.put(accountType, icon);
1172972c0136de098a7721555821bfb7451324b33caAmith Yamasani                }
118d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            } catch (PackageManager.NameNotFoundException e) {
119d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            } catch (Resources.NotFoundException e) {
120d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            }
121d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        }
122d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        if (icon == null) {
123d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            icon = context.getPackageManager().getDefaultActivityIcon();
124d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        }
125d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        return icon;
126d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    }
127d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
128d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    /**
129d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     * Gets the label associated with a particular account type. If none found, return null.
130d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     * @param accountType the type of account
131d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     * @return a CharSequence for the label or null if one cannot be found.
132d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     */
133d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    public CharSequence getLabelForType(Context context, final String accountType) {
134d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        CharSequence label = null;
135d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        if (mTypeToAuthDescription.containsKey(accountType)) {
136d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            try {
137d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
138ce0b22cf90cf99377f63b1aa4d4720f69a6edd7bAlexandra Gherghina                Context authContext = context.createPackageContextAsUser(desc.packageName, 0,
139ce0b22cf90cf99377f63b1aa4d4720f69a6edd7bAlexandra Gherghina                        mUserHandle);
140d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                label = authContext.getResources().getText(desc.labelId);
141d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            } catch (PackageManager.NameNotFoundException e) {
142d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                Log.w(TAG, "No label name for account type " + accountType);
143d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            } catch (Resources.NotFoundException e) {
144d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                Log.w(TAG, "No label icon for account type " + accountType);
145d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            }
146d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        }
147d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        return label;
148d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    }
149d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
150d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    /**
151d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     * Updates provider icons. Subclasses should call this in onCreate()
152d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     * and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
153d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani     */
154d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    public void updateAuthDescriptions(Context context) {
1553939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        mAuthDescs = AccountManager.get(context)
1563939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina                .getAuthenticatorTypesAsUser(mUserHandle.getIdentifier());
157d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        for (int i = 0; i < mAuthDescs.length; i++) {
158d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
159d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        }
160d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    }
161d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
162d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    public boolean containsAccountType(String accountType) {
163d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        return mTypeToAuthDescription.containsKey(accountType);
164d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    }
165d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
166d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    public AuthenticatorDescription getAccountTypeDescription(String accountType) {
167d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        return mTypeToAuthDescription.get(accountType);
168d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    }
1693882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani
1703882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani    public boolean hasAccountPreferences(final String accountType) {
1713882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani        if (containsAccountType(accountType)) {
1723882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani            AuthenticatorDescription desc = getAccountTypeDescription(accountType);
1733882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani            if (desc != null && desc.accountPreferencesId != 0) {
1743882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani                return true;
1753882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani            }
1763882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani        }
1773882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani        return false;
1783882c2e215169ac021c47538e2058ca8089d426fAmith Yamasani    }
1793939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina
180cfc7f9d9600f7b4514ce9608314874bf1023eb21Alexandra Gherghina    void onAccountsUpdated(Account[] accounts) {
1813939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        updateAuthDescriptions(mContext);
1823939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        if (accounts == null) {
183024ba5e4d9d97afe01677de46a00b8574de509d5Alexandra Gherghina            accounts = AccountManager.get(mContext).getAccountsAsUser(mUserHandle.getIdentifier());
1843939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        }
1853939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        mEnabledAccountTypes.clear();
1863939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        mAccTypeIconCache.clear();
1873939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        for (int i = 0; i < accounts.length; i++) {
1883939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            final Account account = accounts[i];
1893939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            if (!mEnabledAccountTypes.contains(account.type)) {
1903939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina                mEnabledAccountTypes.add(account.type);
1913939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            }
1923939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        }
1937f279cef11f1ae39a4c2386d004c8eef5180ab5bAlexandra Gherghina        buildAccountTypeToAuthoritiesMap();
1943939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        if (mListeningToAccountUpdates) {
1953939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            mListener.onAccountsUpdate(mUserHandle);
1963939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        }
1973939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    }
1983939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina
1993939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    @Override
2003939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    public void onReceive(final Context context, final Intent intent) {
201cfc7f9d9600f7b4514ce9608314874bf1023eb21Alexandra Gherghina        // TODO: watch for package upgrades to invalidate cache; see http://b/7206643
2023939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        final Account[] accounts = AccountManager.get(mContext)
2033939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina                .getAccountsAsUser(mUserHandle.getIdentifier());
2043939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        onAccountsUpdated(accounts);
2053939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    }
2063939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina
2073939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    public void listenToAccountUpdates() {
2083939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        if (!mListeningToAccountUpdates) {
2093939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            IntentFilter intentFilter = new IntentFilter();
2103939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            intentFilter.addAction(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
2113939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            // At disk full, certain actions are blocked (such as writing the accounts to storage).
2123939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            // It is useful to also listen for recovery from disk full to avoid bugs.
2133939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
2143939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            mContext.registerReceiverAsUser(this, mUserHandle, intentFilter, null, null);
2153939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            mListeningToAccountUpdates = true;
2163939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        }
2173939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    }
2183939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina
2193939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    public void stopListeningToAccountUpdates() {
2203939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        if (mListeningToAccountUpdates) {
2213939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            mContext.unregisterReceiver(this);
2223939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina            mListeningToAccountUpdates = false;
2233939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina        }
2243939cd70b1605eff9ac6cfa213b73a49283e134aAlexandra Gherghina    }
225af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina
226af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina    public ArrayList<String> getAuthoritiesForAccountType(String type) {
227af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina        return mAccountTypeToAuthorities.get(type);
228af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina    }
229af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina
230af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina    private void buildAccountTypeToAuthoritiesMap() {
231af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina        mAccountTypeToAuthorities.clear();
232af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina        SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(
233af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina                mUserHandle.getIdentifier());
234af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina        for (int i = 0, n = syncAdapters.length; i < n; i++) {
235af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina            final SyncAdapterType sa = syncAdapters[i];
236af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina            ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType);
237af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina            if (authorities == null) {
238af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina                authorities = new ArrayList<String>();
239af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina                mAccountTypeToAuthorities.put(sa.accountType, authorities);
240af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina            }
241af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina            if (Log.isLoggable(TAG, Log.VERBOSE)) {
242af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina                Log.d(TAG, "Added authority " + sa.authority + " to accountType "
243af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina                        + sa.accountType);
244af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina            }
245af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina            authorities.add(sa.authority);
246af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina        }
247af0d9540c26ee1cf79606dc524dbfd70342d2b06Alexandra Gherghina    }
248d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani}
249