Add work account settings.
Bug: 15467756
Change-Id: I13b5a0bb3967611d0d24b575bfc15d9bfaad4cfa
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index a5bc8bb..da7cb98 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -127,7 +127,8 @@
PreferenceFragment.OnPreferenceStartFragmentCallback,
ButtonBarHandler, OnAccountsUpdateListener, FragmentManager.OnBackStackChangedListener,
SearchView.OnQueryTextListener, SearchView.OnCloseListener,
- MenuItem.OnActionExpandListener {
+ MenuItem.OnActionExpandListener,
+ AuthenticatorHelper.OnAccountsUpdateListener {
private static final String LOG_TAG = "Settings";
@@ -466,10 +467,13 @@
if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
}
-
- mAuthenticatorHelper = new AuthenticatorHelper();
+ // TODO: Delete accounts tile once we have the new screen working
+ // See: http://b/15815948
+ final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
+ mAuthenticatorHelper = new AuthenticatorHelper(
+ this, UserHandle.getCallingUserHandle(), um, this);
mAuthenticatorHelper.updateAuthDescriptions(this);
- mAuthenticatorHelper.onAccountsUpdated(this, null);
+ mAuthenticatorHelper.onAccountsUpdated(null);
mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
Context.MODE_PRIVATE);
@@ -1263,7 +1267,11 @@
public void onAccountsUpdated(Account[] accounts) {
// TODO: watch for package upgrades to invalidate cache; see 7206643
mAuthenticatorHelper.updateAuthDescriptions(this);
- mAuthenticatorHelper.onAccountsUpdated(this, accounts);
+ invalidateCategories();
+ }
+
+ @Override
+ public void onAccountsUpdate(UserHandle userHandle) {
invalidateCategories();
}
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 5f90442..26750e7 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -56,12 +56,14 @@
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TabWidget;
+
import com.android.settings.dashboard.DashboardCategory;
import com.android.settings.dashboard.DashboardTile;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -579,4 +581,31 @@
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, isShortcut);
return intent;
}
+
+ /**
+ * Returns the managed profile of the current user or null if none found.
+ */
+ public static UserHandle getManagedProfile(UserManager userManager) {
+ List<UserHandle> userProfiles = userManager.getUserProfiles();
+ final int count = userProfiles.size();
+ for (int i = 0; i < count; i++) {
+ final UserHandle profile = userProfiles.get(i);
+ if (profile.getIdentifier() == userManager.getUserHandle()) {
+ continue;
+ }
+ final UserInfo userInfo = userManager.getUserInfo(profile.getIdentifier());
+ if (userInfo.isManagedProfile()) {
+ return profile;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the current profile is a managed one.
+ */
+ public static boolean isManagedProfile(UserManager userManager) {
+ UserInfo currentUser = userManager.getUserInfo(userManager.getUserHandle());
+ return currentUser.isManagedProfile();
+ }
}
diff --git a/src/com/android/settings/accounts/AccountPreferenceBase.java b/src/com/android/settings/accounts/AccountPreferenceBase.java
index 37dffca..c25831d 100644
--- a/src/com/android/settings/accounts/AccountPreferenceBase.java
+++ b/src/com/android/settings/accounts/AccountPreferenceBase.java
@@ -16,19 +16,9 @@
package com.android.settings.accounts;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.android.settings.SettingsPreferenceFragment;
-
import com.google.android.collect.Maps;
-import android.accounts.Account;
-import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
-import android.accounts.OnAccountsUpdateListener;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
@@ -40,28 +30,47 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.preference.PreferenceScreen;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.ContextThemeWrapper;
+import com.android.settings.SettingsPreferenceFragment;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+
class AccountPreferenceBase extends SettingsPreferenceFragment
- implements OnAccountsUpdateListener {
+ implements AuthenticatorHelper.OnAccountsUpdateListener {
protected static final String TAG = "AccountSettings";
public static final String AUTHORITIES_FILTER_KEY = "authorities";
public static final String ACCOUNT_TYPES_FILTER_KEY = "account_types";
private final Handler mHandler = new Handler();
+ private UserManager mUm;
private Object mStatusChangeListenerHandle;
private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null;
- private AuthenticatorHelper mAuthenticatorHelper = new AuthenticatorHelper();
+ protected AuthenticatorHelper mAuthenticatorHelper;
private java.text.DateFormat mDateFormat;
private java.text.DateFormat mTimeFormat;
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ // TODO: This needs to handle different users, get the user id from the intent
+ mUm = (UserManager) getSystemService(Context.USER_SERVICE);
+ mAuthenticatorHelper = new AuthenticatorHelper(
+ getActivity(), UserHandle.getCallingUserHandle(), mUm, this);
+ }
+
/**
* Overload to handle account updates.
*/
- public void onAccountsUpdated(Account[] accounts) {
+ @Override
+ public void onAccountsUpdate(UserHandle userHandle) {
}
diff --git a/src/com/android/settings/accounts/AccountSettings.java b/src/com/android/settings/accounts/AccountSettings.java
index bb06b2f..e60bed9 100644
--- a/src/com/android/settings/accounts/AccountSettings.java
+++ b/src/com/android/settings/accounts/AccountSettings.java
@@ -19,11 +19,17 @@
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.OnAccountsUpdateListener;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.UserHandle;
import android.os.UserManager;
+import android.util.Log;
+import android.util.SparseArray;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceGroup;
@@ -33,16 +39,17 @@
import com.android.settings.Utils;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
-import java.util.List;
/**
* Settings screen for the account types on the device.
* This shows all account types available for personal and work profiles.
*/
public class AccountSettings extends SettingsPreferenceFragment
- implements OnAccountsUpdateListener, OnPreferenceClickListener {
+ implements AuthenticatorHelper.OnAccountsUpdateListener,
+ OnPreferenceClickListener {
public static final String TAG = "AccountSettings";
private static final String KEY_ACCOUNT = "account";
@@ -51,128 +58,183 @@
private static final String KEY_CATEGORY_PERSONAL = "account_personal";
private static final String KEY_ADD_ACCOUNT_PERSONAL = "add_account_personal";
private static final String KEY_CATEGORY_WORK = "account_work";
+ private static final String KEY_ADD_ACCOUNT_WORK = "add_account_work";
- private AuthenticatorHelper mAuthenticatorHelper;
- private boolean mListeningToAccountUpdates;
-
- private PreferenceGroup mAccountTypesForUser;
- private Preference mAddAccountForUser;
+ private static final String ADD_ACCOUNT_ACTION = "android.settings.ADD_ACCOUNT_SETTINGS";
private UserManager mUm;
+ private SparseArray<ProfileData> mProfiles;
+ private ManagedProfileBroadcastReceiver mManagedProfileBroadcastReceiver;
+
+ /**
+ * Holds data related to the accounts belonging to one profile.
+ */
+ private static class ProfileData {
+ /**
+ * The preference that displays the accounts.
+ */
+ public PreferenceGroup preferenceGroup;
+ /**
+ * The preference that displays the add account button.
+ */
+ public Preference addAccountPreference;
+ /**
+ * The user handle of the user that these accounts belong to.
+ */
+ public UserHandle userHandle;
+ /**
+ * The {@link AuthenticatorHelper} that holds accounts data for this profile.
+ */
+ public AuthenticatorHelper authenticatorHelper;
+ }
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUm = (UserManager) getSystemService(Context.USER_SERVICE);
+ mProfiles = new SparseArray<ProfileData>(2);
+ updateUi();
+ }
- mAuthenticatorHelper = new AuthenticatorHelper();
- mAuthenticatorHelper.updateAuthDescriptions(getActivity());
- mAuthenticatorHelper.onAccountsUpdated(getActivity(), null);
-
+ void updateUi() {
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.account_settings);
if(mUm.isLinkedUser()) {
// Restricted user or similar
- // TODO: Do we disallow modifying accounts for restricted profiles?
- mAccountTypesForUser = (PreferenceGroup) findPreference(KEY_ACCOUNT);
- if (mUm.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
- removePreference(KEY_ADD_ACCOUNT);
- } else {
- mAddAccountForUser = findPreference(KEY_ADD_ACCOUNT);
- mAddAccountForUser.setOnPreferenceClickListener(this);
- }
- removePreference(KEY_CATEGORY_PERSONAL);
- removePreference(KEY_CATEGORY_WORK);
+ updateSingleProfileUi();
} else {
- mAccountTypesForUser = (PreferenceGroup) findPreference(KEY_CATEGORY_PERSONAL);
- mAddAccountForUser = findPreference(KEY_ADD_ACCOUNT_PERSONAL);
- mAddAccountForUser.setOnPreferenceClickListener(this);
-
- // TODO: Show the work accounts also
- // TODO: Handle the case where there is only one account
- removePreference(KEY_CATEGORY_WORK);
- removePreference(KEY_ADD_ACCOUNT);
+ if (Utils.isManagedProfile(mUm)) {
+ // This should not happen
+ Log.w(TAG, "We should not be showing settings for a managed profile");
+ updateSingleProfileUi();
+ }
+ final UserHandle currentProfile = UserHandle.getCallingUserHandle();
+ final UserHandle managedProfile = Utils.getManagedProfile(mUm);
+ if (managedProfile == null) {
+ updateSingleProfileUi();
+ } else {
+ updateProfileUi(currentProfile,
+ KEY_CATEGORY_PERSONAL, KEY_ADD_ACCOUNT_PERSONAL, new ArrayList<String>());
+ final ArrayList<String> unusedPreferences = new ArrayList<String>(1);
+ unusedPreferences.add(KEY_ADD_ACCOUNT);
+ updateProfileUi(managedProfile,
+ KEY_CATEGORY_WORK, KEY_ADD_ACCOUNT_WORK, unusedPreferences);
+ mManagedProfileBroadcastReceiver = new ManagedProfileBroadcastReceiver();
+ mManagedProfileBroadcastReceiver.register(getActivity());
+ }
}
- updateAccountTypes(mAccountTypesForUser);
+ final int count = mProfiles.size();
+ for (int i = 0; i < count; i++) {
+ updateAccountTypes(mProfiles.valueAt(i));
+ }
+ }
+
+ private void updateSingleProfileUi() {
+ final ArrayList<String> unusedPreferences = new ArrayList<String>(2);
+ unusedPreferences.add(KEY_CATEGORY_PERSONAL);
+ unusedPreferences.add(KEY_CATEGORY_WORK);
+ updateProfileUi(UserHandle.getCallingUserHandle(), KEY_ACCOUNT, KEY_ADD_ACCOUNT,
+ unusedPreferences);
+ }
+
+ private void updateProfileUi(UserHandle userHandle, String categoryKey, String addAccountKey,
+ ArrayList<String> unusedPreferences) {
+ final int count = unusedPreferences.size();
+ for (int i = 0; i < count; i++) {
+ removePreference(unusedPreferences.get(i));
+ }
+ final ProfileData profileData = new ProfileData();
+ profileData.preferenceGroup = (PreferenceGroup) findPreference(categoryKey);
+ if (mUm.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
+ removePreference(addAccountKey);
+ } else {
+ profileData.addAccountPreference = findPreference(addAccountKey);
+ profileData.addAccountPreference.setOnPreferenceClickListener(this);
+ }
+ profileData.userHandle = userHandle;
+ profileData.authenticatorHelper = new AuthenticatorHelper(
+ getActivity(), userHandle, mUm, this);
+ mProfiles.put(userHandle.getIdentifier(), profileData);
+
+ profileData.authenticatorHelper.listenToAccountUpdates();
}
@Override
public void onDestroy() {
super.onDestroy();
- stopListeningToAccountUpdates();
+ cleanUp();
+ }
+
+ void cleanUp() {
+ if (mManagedProfileBroadcastReceiver != null) {
+ mManagedProfileBroadcastReceiver.unregister(getActivity());
+ }
+ final int count = mProfiles.size();
+ for (int i = 0; i < count; i++) {
+ mProfiles.valueAt(i).authenticatorHelper.stopListeningToAccountUpdates();
+ }
}
@Override
- public void onAccountsUpdated(Account[] accounts) {
- // TODO: watch for package upgrades to invalidate cache; see 7206643
- mAuthenticatorHelper.updateAuthDescriptions(getActivity());
- mAuthenticatorHelper.onAccountsUpdated(getActivity(), accounts);
- listenToAccountUpdates();
- updateAccountTypes(mAccountTypesForUser);
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- // Check the preference
- if (preference == mAddAccountForUser) {
- Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
- startActivity(intent);
- return true;
- }
- return false;
- }
-
- private void updateAccountTypes(PreferenceGroup preferenceGroup) {
- preferenceGroup.removeAll();
- preferenceGroup.setOrderingAsAdded(true);
- for (AccountPreference preference : getAccountTypePreferences()) {
- preferenceGroup.addPreference(preference);
- }
- if (mAddAccountForUser != null) {
- preferenceGroup.addPreference(mAddAccountForUser);
+ public void onAccountsUpdate(UserHandle userHandle) {
+ final ProfileData profileData = mProfiles.get(userHandle.getIdentifier());
+ if (profileData != null) {
+ updateAccountTypes(profileData);
+ } else {
+ Log.w(TAG, "Missing Settings screen for: " + userHandle.getIdentifier());
}
}
- private List<AccountPreference> getAccountTypePreferences() {
- String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes();
- List<AccountPreference> accountTypePreferences =
+ private void updateAccountTypes(ProfileData profileData) {
+ profileData.preferenceGroup.removeAll();
+ final ArrayList<AccountPreference> preferences = getAccountTypePreferences(
+ profileData.authenticatorHelper);
+ final int count = preferences.size();
+ for (int i = 0; i < count; i++) {
+ profileData.preferenceGroup.addPreference(preferences.get(i));
+ }
+ if (profileData.addAccountPreference != null) {
+ profileData.preferenceGroup.addPreference(profileData.addAccountPreference);
+ }
+ }
+
+ private ArrayList<AccountPreference> getAccountTypePreferences(AuthenticatorHelper helper) {
+ final String[] accountTypes = helper.getEnabledAccountTypes();
+ final ArrayList<AccountPreference> accountTypePreferences =
new ArrayList<AccountPreference>(accountTypes.length);
- for (String accountType : accountTypes) {
- CharSequence label = mAuthenticatorHelper.getLabelForType(getActivity(), accountType);
+
+ for (int i = 0; i < accountTypes.length; i++) {
+ final String accountType = accountTypes[i];
+ final CharSequence label = helper.getLabelForType(getActivity(), accountType);
if (label == null) {
continue;
}
- Account[] accounts = AccountManager.get(getActivity()).getAccountsByType(accountType);
- boolean skipToAccount = accounts.length == 1
- && !mAuthenticatorHelper.hasAccountPreferences(accountType);
+ final Account[] accounts = AccountManager.get(getActivity())
+ .getAccountsByType(accountType);
+ final boolean skipToAccount = accounts.length == 1
+ && !helper.hasAccountPreferences(accountType);
if (skipToAccount) {
- Bundle fragmentArguments = new Bundle();
+ final Bundle fragmentArguments = new Bundle();
fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
accounts[0]);
- accountTypePreferences.add(new AccountPreference(
- getActivity(),
- label,
- accountType,
- AccountSyncSettings.class.getName(),
- fragmentArguments));
+ accountTypePreferences.add(new AccountPreference(getActivity(), label,
+ AccountSyncSettings.class.getName(), fragmentArguments,
+ helper.getDrawableForType(getActivity(), accountType)));
} else {
- Bundle fragmentArguments = new Bundle();
+ final Bundle fragmentArguments = new Bundle();
fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL,
label.toString());
- accountTypePreferences.add(new AccountPreference(
- getActivity(),
- label,
- accountType,
- ManageAccountsSettings.class.getName(),
- fragmentArguments));
+ accountTypePreferences.add(new AccountPreference(getActivity(), label,
+ ManageAccountsSettings.class.getName(), fragmentArguments,
+ helper.getDrawableForType(getActivity(), accountType)));
}
- mAuthenticatorHelper.preloadDrawableForType(getActivity(), accountType);
+ helper.preloadDrawableForType(getActivity(), accountType);
}
// Sort by label
Collections.sort(accountTypePreferences, new Comparator<AccountPreference>() {
@@ -184,18 +246,20 @@
return accountTypePreferences;
}
- private void listenToAccountUpdates() {
- if (!mListeningToAccountUpdates) {
- AccountManager.get(getActivity()).addOnAccountsUpdatedListener(this, null, true);
- mListeningToAccountUpdates = true;
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ // Check the preference
+ final int count = mProfiles.size();
+ for (int i = 0; i < count; i++) {
+ ProfileData profileData = mProfiles.valueAt(i);
+ if (preference == profileData.addAccountPreference) {
+ Intent intent = new Intent(ADD_ACCOUNT_ACTION);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, profileData.userHandle);
+ startActivity(intent);
+ return true;
+ }
}
- }
-
- private void stopListeningToAccountUpdates() {
- if (mListeningToAccountUpdates) {
- AccountManager.get(getActivity()).removeOnAccountsUpdatedListener(this);
- mListeningToAccountUpdates = false;
- }
+ return false;
}
private class AccountPreference extends Preference implements OnPreferenceClickListener {
@@ -218,18 +282,16 @@
*/
private final Bundle mFragmentArguments;
-
- public AccountPreference(Context context, CharSequence title,
- String accountType, String fragment, Bundle fragmentArguments) {
+ public AccountPreference(Context context, CharSequence title, String fragment,
+ Bundle fragmentArguments, Drawable icon) {
super(context);
mTitle = title;
mFragment = fragment;
mFragmentArguments = fragmentArguments;
setWidgetLayoutResource(R.layout.account_type_preference);
- Drawable drawable = mAuthenticatorHelper.getDrawableForType(context, accountType);
setTitle(title);
- setIcon(drawable);
+ setIcon(icon);
setOnPreferenceClickListener(this);
}
@@ -244,6 +306,39 @@
return false;
}
}
+
+ private class ManagedProfileBroadcastReceiver extends BroadcastReceiver {
+ private boolean listeningToManagedProfileEvents;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)
+ || intent.getAction().equals(Intent.ACTION_MANAGED_PROFILE_ADDED)) {
+ Log.v(TAG, "Received broadcast: " + intent.getAction());
+ cleanUp();
+ updateUi();
+ return;
+ }
+ Log.w(TAG, "Cannot handle received broadcast: " + intent.getAction());
+ }
+
+ public void register(Context context) {
+ if (!listeningToManagedProfileEvents) {
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
+ intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
+ context.registerReceiver(this, intentFilter);
+ listeningToManagedProfileEvents = true;
+ }
+ }
+
+ public void unregister(Context context) {
+ if (listeningToManagedProfileEvents) {
+ context.unregisterReceiver(this);
+ listeningToManagedProfileEvents = false;
+ }
+ }
+ }
// TODO Implement a {@link SearchIndexProvider} to allow Indexing and Search of account types
// See http://b/15403806
}
diff --git a/src/com/android/settings/accounts/AccountSyncSettings.java b/src/com/android/settings/accounts/AccountSyncSettings.java
index c14dbbe..e33e37a 100644
--- a/src/com/android/settings/accounts/AccountSyncSettings.java
+++ b/src/com/android/settings/accounts/AccountSyncSettings.java
@@ -16,13 +16,15 @@
package com.android.settings.accounts;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
-import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentResolver;
@@ -34,6 +36,7 @@
import android.content.pm.ProviderInfo;
import android.net.ConnectivityManager;
import android.os.Bundle;
+import android.os.UserHandle;
import android.os.UserManager;
import android.preference.Preference;
import android.preference.PreferenceScreen;
@@ -51,8 +54,6 @@
import com.android.settings.R;
import com.android.settings.Utils;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
import java.io.IOException;
import java.util.ArrayList;
@@ -193,10 +194,9 @@
@Override
public void onResume() {
- final Activity activity = getActivity();
- AccountManager.get(activity).addOnAccountsUpdatedListener(this, null, false);
+ mAuthenticatorHelper.listenToAccountUpdates();
updateAuthDescriptions();
- onAccountsUpdated(AccountManager.get(activity).getAccounts());
+ onAccountsUpdate(UserHandle.getCallingUserHandle());
super.onResume();
}
@@ -204,7 +204,7 @@
@Override
public void onPause() {
super.onPause();
- AccountManager.get(getActivity()).removeOnAccountsUpdatedListener(this);
+ mAuthenticatorHelper.stopListeningToAccountUpdates();
}
private void addSyncStateCheckBox(Account account, String authority) {
@@ -436,10 +436,10 @@
}
@Override
- public void onAccountsUpdated(Account[] accounts) {
- super.onAccountsUpdated(accounts);
- mAccounts = accounts;
- updateAccountCheckboxes(accounts);
+ public void onAccountsUpdate(final UserHandle userHandle) {
+ super.onAccountsUpdate(userHandle);
+ mAccounts = AccountManager.get(getActivity()).getAccounts();
+ updateAccountCheckboxes(mAccounts);
onSyncStateUpdated();
}
diff --git a/src/com/android/settings/accounts/AuthenticatorHelper.java b/src/com/android/settings/accounts/AuthenticatorHelper.java
index a164b8b..0ecf438 100644
--- a/src/com/android/settings/accounts/AuthenticatorHelper.java
+++ b/src/com/android/settings/accounts/AuthenticatorHelper.java
@@ -19,27 +19,58 @@
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
-public class AuthenticatorHelper {
-
+/**
+ * Helper class for monitoring accounts on the device for a given user.
+ *
+ * Classes using this helper should implement {@link OnAccountsUpdateListener}.
+ * {@link OnAccountsUpdateListener#onAccountsUpdate(UserHandle)} will then be
+ * called once accounts get updated. For setting up listening for account
+ * updates, {@link #listenToAccountUpdates()} and
+ * {@link #stopListeningToAccountUpdates()} should be used.
+ */
+final public class AuthenticatorHelper extends BroadcastReceiver {
private static final String TAG = "AuthenticatorHelper";
+
private Map<String, AuthenticatorDescription> mTypeToAuthDescription
= new HashMap<String, AuthenticatorDescription>();
private AuthenticatorDescription[] mAuthDescs;
private ArrayList<String> mEnabledAccountTypes = new ArrayList<String>();
private Map<String, Drawable> mAccTypeIconCache = new HashMap<String, Drawable>();
- public AuthenticatorHelper() {
+ private final UserHandle mUserHandle;
+ private final UserManager mUm;
+ private final Context mContext;
+ private final OnAccountsUpdateListener mListener;
+ private boolean mListeningToAccountUpdates;
+
+ public interface OnAccountsUpdateListener {
+ void onAccountsUpdate(UserHandle userHandle);
+ }
+
+ public AuthenticatorHelper(Context context, UserHandle userHandle, UserManager userManager,
+ OnAccountsUpdateListener listener) {
+ mContext = context;
+ mUm = userManager;
+ mUserHandle = userHandle;
+ mListener = listener;
+ // This guarantees that the helper is ready to use once constructed
+ onAccountsUpdated(null);
}
public String[] getEnabledAccountTypes() {
@@ -72,7 +103,8 @@
try {
AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
Context authContext = context.createPackageContext(desc.packageName, 0);
- icon = authContext.getResources().getDrawable(desc.iconId);
+ icon = mUm.getBadgedDrawableForUser(
+ authContext.getResources().getDrawable(desc.iconId), mUserHandle);
synchronized (mAccTypeIconCache) {
mAccTypeIconCache.put(accountType, icon);
}
@@ -112,25 +144,13 @@
* and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
*/
public void updateAuthDescriptions(Context context) {
- mAuthDescs = AccountManager.get(context).getAuthenticatorTypes();
+ mAuthDescs = AccountManager.get(context)
+ .getAuthenticatorTypesAsUser(mUserHandle.getIdentifier());
for (int i = 0; i < mAuthDescs.length; i++) {
mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
}
}
- public void onAccountsUpdated(Context context, Account[] accounts) {
- if (accounts == null) {
- accounts = AccountManager.get(context).getAccounts();
- }
- mEnabledAccountTypes.clear();
- mAccTypeIconCache.clear();
- for (Account account: accounts) {
- if (!mEnabledAccountTypes.contains(account.type)) {
- mEnabledAccountTypes.add(account.type);
- }
- }
- }
-
public boolean containsAccountType(String accountType) {
return mTypeToAuthDescription.containsKey(accountType);
}
@@ -148,4 +168,50 @@
}
return false;
}
+
+ public void onAccountsUpdated(Account[] accounts) {
+ // TODO: Revert to non-public once no longer needed in SettingsActivity
+ // See http://b/15819268
+ updateAuthDescriptions(mContext);
+ if (accounts == null) {
+ accounts = AccountManager.get(mContext).getAccounts();
+ }
+ mEnabledAccountTypes.clear();
+ mAccTypeIconCache.clear();
+ for (int i = 0; i < accounts.length; i++) {
+ final Account account = accounts[i];
+ if (!mEnabledAccountTypes.contains(account.type)) {
+ mEnabledAccountTypes.add(account.type);
+ }
+ }
+ if (mListeningToAccountUpdates) {
+ mListener.onAccountsUpdate(mUserHandle);
+ }
+ }
+
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ final Account[] accounts = AccountManager.get(mContext)
+ .getAccountsAsUser(mUserHandle.getIdentifier());
+ onAccountsUpdated(accounts);
+ }
+
+ public void listenToAccountUpdates() {
+ if (!mListeningToAccountUpdates) {
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
+ // At disk full, certain actions are blocked (such as writing the accounts to storage).
+ // It is useful to also listen for recovery from disk full to avoid bugs.
+ intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
+ mContext.registerReceiverAsUser(this, mUserHandle, intentFilter, null, null);
+ mListeningToAccountUpdates = true;
+ }
+ }
+
+ public void stopListeningToAccountUpdates() {
+ if (mListeningToAccountUpdates) {
+ mContext.unregisterReceiver(this);
+ mListeningToAccountUpdates = false;
+ }
+ }
}