1d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler/* 2d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Copyright (C) 2015 The Android Open Source Project 3d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * 4d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Licensed under the Apache License, Version 2.0 (the "License"); 5d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * you may not use this file except in compliance with the License. 6d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * You may obtain a copy of the License at 7d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * 8d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * http://www.apache.org/licenses/LICENSE-2.0 9d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * 10d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Unless required by applicable law or agreed to in writing, software 11d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * distributed under the License is distributed on an "AS IS" BASIS, 12d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * See the License for the specific language governing permissions and 14d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * limitations under the License 15d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler */ 16d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 17d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerpackage com.android.settingslib.accounts; 18d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 19d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.accounts.Account; 20d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.accounts.AccountManager; 21d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.accounts.AuthenticatorDescription; 22d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.content.BroadcastReceiver; 23d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.content.ContentResolver; 24d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.content.Context; 25d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.content.Intent; 26d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.content.IntentFilter; 27d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.content.SyncAdapterType; 28d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.content.pm.PackageManager; 29d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.content.res.Resources; 30d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.graphics.drawable.Drawable; 31d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.os.AsyncTask; 32d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.os.UserHandle; 33d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport android.util.Log; 34d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 35d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport java.util.ArrayList; 36d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport java.util.HashMap; 37d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerimport java.util.Map; 38d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 39d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler/** 40d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Helper class for monitoring accounts on the device for a given user. 41d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * 42d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Classes using this helper should implement {@link OnAccountsUpdateListener}. 43d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * {@link OnAccountsUpdateListener#onAccountsUpdate(UserHandle)} will then be 44d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * called once accounts get updated. For setting up listening for account 45d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * updates, {@link #listenToAccountUpdates()} and 46d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * {@link #stopListeningToAccountUpdates()} should be used. 47d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler */ 48d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantlerfinal public class AuthenticatorHelper extends BroadcastReceiver { 49d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private static final String TAG = "AuthenticatorHelper"; 50d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 51d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private final Map<String, AuthenticatorDescription> mTypeToAuthDescription = new HashMap<>(); 52d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private final ArrayList<String> mEnabledAccountTypes = new ArrayList<>(); 53d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private final Map<String, Drawable> mAccTypeIconCache = new HashMap<>(); 54d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private final HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = new HashMap<>(); 55d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 56d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private final UserHandle mUserHandle; 57d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private final Context mContext; 58d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private final OnAccountsUpdateListener mListener; 59d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private boolean mListeningToAccountUpdates; 60d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 61d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public interface OnAccountsUpdateListener { 62d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler void onAccountsUpdate(UserHandle userHandle); 63d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 64d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 65d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public AuthenticatorHelper(Context context, UserHandle userHandle, 66d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler OnAccountsUpdateListener listener) { 67d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mContext = context; 68d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mUserHandle = userHandle; 69d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mListener = listener; 70d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler // This guarantees that the helper is ready to use once constructed: the account types and 71d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler // authorities are initialized 72d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler onAccountsUpdated(null); 73d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 74d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 75d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public String[] getEnabledAccountTypes() { 76d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return mEnabledAccountTypes.toArray(new String[mEnabledAccountTypes.size()]); 77d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 78d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 79d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public void preloadDrawableForType(final Context context, final String accountType) { 80d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler new AsyncTask<Void, Void, Void>() { 81d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler @Override 82d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler protected Void doInBackground(Void... params) { 83d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler getDrawableForType(context, accountType); 84d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return null; 85d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 86d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 87d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 88d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 89d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler /** 90d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Gets an icon associated with a particular account type. If none found, return null. 91d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * @param accountType the type of account 92d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * @return a drawable for the icon or a default icon returned by 93d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * {@link PackageManager#getDefaultActivityIcon} if one cannot be found. 94d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler */ 95d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public Drawable getDrawableForType(Context context, final String accountType) { 96d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler Drawable icon = null; 97d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler synchronized (mAccTypeIconCache) { 98d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (mAccTypeIconCache.containsKey(accountType)) { 99d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return mAccTypeIconCache.get(accountType); 100d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 101d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 102d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (mTypeToAuthDescription.containsKey(accountType)) { 103d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler try { 104d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); 105d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler Context authContext = context.createPackageContextAsUser(desc.packageName, 0, 106d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mUserHandle); 107d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler icon = mContext.getPackageManager().getUserBadgedIcon( 108d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler authContext.getDrawable(desc.iconId), mUserHandle); 109d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler synchronized (mAccTypeIconCache) { 110d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mAccTypeIconCache.put(accountType, icon); 111d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 112d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } catch (PackageManager.NameNotFoundException|Resources.NotFoundException e) { 113d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler // Ignore 114d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 115d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 116d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (icon == null) { 117d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler icon = context.getPackageManager().getDefaultActivityIcon(); 118d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 119d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return icon; 120d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 121d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 122d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler /** 123d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Gets the label associated with a particular account type. If none found, return null. 124d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * @param accountType the type of account 125d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * @return a CharSequence for the label or null if one cannot be found. 126d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler */ 127d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public CharSequence getLabelForType(Context context, final String accountType) { 128d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler CharSequence label = null; 129d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (mTypeToAuthDescription.containsKey(accountType)) { 130d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler try { 131d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); 132d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler Context authContext = context.createPackageContextAsUser(desc.packageName, 0, 133d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mUserHandle); 134d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler label = authContext.getResources().getText(desc.labelId); 135d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } catch (PackageManager.NameNotFoundException e) { 136d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler Log.w(TAG, "No label name for account type " + accountType); 137d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } catch (Resources.NotFoundException e) { 138d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler Log.w(TAG, "No label icon for account type " + accountType); 139d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 140d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 141d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return label; 142d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 143d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 144d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler /** 145d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Gets the package associated with a particular account type. If none found, return null. 146d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * @param accountType the type of account 147d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * @return the package name or null if one cannot be found. 148d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler */ 149d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public String getPackageForType(final String accountType) { 150d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (mTypeToAuthDescription.containsKey(accountType)) { 151d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); 152d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return desc.packageName; 153d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 154d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return null; 155d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 156d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 157d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler /** 158d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Gets the resource id of the label associated with a particular account type. If none found, 159d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * return -1. 160d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * @param accountType the type of account 161d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * @return a resource id for the label or -1 if none found; 162d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler */ 163d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public int getLabelIdForType(final String accountType) { 164d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (mTypeToAuthDescription.containsKey(accountType)) { 165d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); 166d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return desc.labelId; 167d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 168d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return -1; 169d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 170d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 171d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler /** 172d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * Updates provider icons. Subclasses should call this in onCreate() 173d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler * and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated(). 174d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler */ 175d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public void updateAuthDescriptions(Context context) { 176d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler AuthenticatorDescription[] authDescs = AccountManager.get(context) 177d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler .getAuthenticatorTypesAsUser(mUserHandle.getIdentifier()); 178d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler for (int i = 0; i < authDescs.length; i++) { 179d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mTypeToAuthDescription.put(authDescs[i].type, authDescs[i]); 180d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 181d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 182d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 183d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public boolean containsAccountType(String accountType) { 184d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return mTypeToAuthDescription.containsKey(accountType); 185d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 186d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 187d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public AuthenticatorDescription getAccountTypeDescription(String accountType) { 188d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return mTypeToAuthDescription.get(accountType); 189d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 190d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 191d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public boolean hasAccountPreferences(final String accountType) { 192d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (containsAccountType(accountType)) { 193d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler AuthenticatorDescription desc = getAccountTypeDescription(accountType); 194d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (desc != null && desc.accountPreferencesId != 0) { 195d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return true; 196d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 197d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 198d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return false; 199d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 200d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 201d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler void onAccountsUpdated(Account[] accounts) { 202d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler updateAuthDescriptions(mContext); 203d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (accounts == null) { 204d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler accounts = AccountManager.get(mContext).getAccountsAsUser(mUserHandle.getIdentifier()); 205d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 206d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mEnabledAccountTypes.clear(); 207d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mAccTypeIconCache.clear(); 208d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler for (int i = 0; i < accounts.length; i++) { 209d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler final Account account = accounts[i]; 210d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (!mEnabledAccountTypes.contains(account.type)) { 211d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mEnabledAccountTypes.add(account.type); 212d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 213d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 214d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler buildAccountTypeToAuthoritiesMap(); 215d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (mListeningToAccountUpdates) { 216d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mListener.onAccountsUpdate(mUserHandle); 217d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 218d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 219d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 220d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler @Override 221d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public void onReceive(final Context context, final Intent intent) { 222d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler // TODO: watch for package upgrades to invalidate cache; see http://b/7206643 223d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler final Account[] accounts = AccountManager.get(mContext) 224d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler .getAccountsAsUser(mUserHandle.getIdentifier()); 225d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler onAccountsUpdated(accounts); 226d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 227d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 228d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public void listenToAccountUpdates() { 229d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (!mListeningToAccountUpdates) { 230d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler IntentFilter intentFilter = new IntentFilter(); 231d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler intentFilter.addAction(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION); 232d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler // At disk full, certain actions are blocked (such as writing the accounts to storage). 233d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler // It is useful to also listen for recovery from disk full to avoid bugs. 234d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); 235d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mContext.registerReceiverAsUser(this, mUserHandle, intentFilter, null, null); 236d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mListeningToAccountUpdates = true; 237d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 238d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 239d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 240d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public void stopListeningToAccountUpdates() { 241d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (mListeningToAccountUpdates) { 242d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mContext.unregisterReceiver(this); 243d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mListeningToAccountUpdates = false; 244d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 245d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 246d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 247d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler public ArrayList<String> getAuthoritiesForAccountType(String type) { 248d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler return mAccountTypeToAuthorities.get(type); 249d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 250d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler 251d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler private void buildAccountTypeToAuthoritiesMap() { 252d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mAccountTypeToAuthorities.clear(); 253d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser( 254d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mUserHandle.getIdentifier()); 255d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler for (int i = 0, n = syncAdapters.length; i < n; i++) { 256d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler final SyncAdapterType sa = syncAdapters[i]; 257d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType); 258d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (authorities == null) { 259d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler authorities = new ArrayList<String>(); 260d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler mAccountTypeToAuthorities.put(sa.accountType, authorities); 261d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 262d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler if (Log.isLoggable(TAG, Log.VERBOSE)) { 263d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler Log.v(TAG, "Added authority " + sa.authority + " to accountType " 264d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler + sa.accountType); 265d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 266d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler authorities.add(sa.authority); 267d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 268d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler } 269d1e32720441dd28a2ceed6a0d058f367e71421ecTony Mantler} 270