diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java index a782a7d7de0..6ed2c34e69a 100644 --- a/src/com/android/settings/accounts/AccountPreferenceController.java +++ b/src/com/android/settings/accounts/AccountPreferenceController.java @@ -123,9 +123,9 @@ public class AccountPreferenceController extends PreferenceController */ public boolean pendingRemoval; /** - * The map from account name to account preference + * The map from account key to account preference */ - public ArrayMap accountPreferences = new ArrayMap<>(); + public ArrayMap accountPreferences = new ArrayMap<>(); } public AccountPreferenceController(Context context, SettingsPreferenceFragment parent, @@ -426,7 +426,7 @@ public class AccountPreferenceController extends PreferenceController return; } if (profileData.userInfo.isEnabled()) { - final ArrayMap preferenceToRemove = + final ArrayMap preferenceToRemove = new ArrayMap<>(profileData.accountPreferences); final ArrayList preferences = getAccountTypePreferences( profileData.authenticatorHelper, profileData.userInfo.getUserHandle(), @@ -435,18 +435,19 @@ public class AccountPreferenceController extends PreferenceController for (int i = 0; i < count; i++) { final AccountTypePreference preference = preferences.get(i); preference.setOrder(i); - if (!profileData.accountPreferences.containsValue(preference)) { - profileData.preferenceGroup.addPreference(preferences.get(i)); - profileData.accountPreferences.put(preference.getTitle(), preference); + final String key = preference.getKey(); + if (!profileData.accountPreferences.containsKey(key)) { + profileData.preferenceGroup.addPreference(preference); + profileData.accountPreferences.put(key, preference); } } if (profileData.addAccountPreference != null) { profileData.preferenceGroup.addPreference(profileData.addAccountPreference); } - for (CharSequence name : preferenceToRemove.keySet()) { + for (String key : preferenceToRemove.keySet()) { profileData.preferenceGroup.removePreference( - profileData.accountPreferences.get(name)); - profileData.accountPreferences.remove(name); + profileData.accountPreferences.get(key)); + profileData.accountPreferences.remove(key); } } else { profileData.preferenceGroup.removeAll(); @@ -471,8 +472,7 @@ public class AccountPreferenceController extends PreferenceController } private ArrayList getAccountTypePreferences(AuthenticatorHelper helper, - UserHandle userHandle, - ArrayMap preferenceToRemove) { + UserHandle userHandle, ArrayMap preferenceToRemove) { final String[] accountTypes = helper.getEnabledAccountTypes(); final ArrayList accountTypePreferences = new ArrayList<>(accountTypes.length); @@ -497,7 +497,8 @@ public class AccountPreferenceController extends PreferenceController // Add a preference row for each individual account for (Account account : accounts) { - final AccountTypePreference preference = preferenceToRemove.remove(account.name); + final AccountTypePreference preference = + preferenceToRemove.remove(AccountTypePreference.buildKey(account)); if (preference != null) { accountTypePreferences.add(preference); continue; @@ -521,7 +522,7 @@ public class AccountPreferenceController extends PreferenceController fragmentArguments.putParcelable(EXTRA_USER, userHandle); accountTypePreferences.add(new AccountTypePreference( prefContext, mMetricsFeatureProvider.getMetricsCategory(mParent), - account.name, titleResPackageName, titleResId, label, + account, titleResPackageName, titleResId, label, AccountDetailDashboardFragment.class.getName(), fragmentArguments, icon)); } helper.preloadDrawableForType(mContext, accountType); diff --git a/src/com/android/settings/accounts/AccountTypePreference.java b/src/com/android/settings/accounts/AccountTypePreference.java index 0abfb5003b4..4f9282909ae 100644 --- a/src/com/android/settings/accounts/AccountTypePreference.java +++ b/src/com/android/settings/accounts/AccountTypePreference.java @@ -16,6 +16,7 @@ package com.android.settings.accounts; +import android.accounts.Account; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; @@ -67,18 +68,11 @@ public class AccountTypePreference extends Preference implements OnPreferenceCli private final int mMetricsCategory; - public AccountTypePreference(Context context, int metricsCategory, CharSequence title, - String titleResPackageName, int titleResId, String fragment, Bundle fragmentArguments, - Drawable icon) { - this(context, metricsCategory, title, titleResPackageName, titleResId, null, fragment, - fragmentArguments, icon); - } - - public AccountTypePreference(Context context, int metricsCategory, CharSequence title, + public AccountTypePreference(Context context, int metricsCategory, Account account, String titleResPackageName, int titleResId, CharSequence summary, String fragment, Bundle fragmentArguments, Drawable icon) { super(context); - mTitle = title; + mTitle = account.name; mTitleResPackageName = titleResPackageName; mTitleResId = titleResId; mSummary = summary; @@ -87,7 +81,8 @@ public class AccountTypePreference extends Preference implements OnPreferenceCli mMetricsCategory = metricsCategory; setWidgetLayoutResource(R.layout.account_type_preference); - setTitle(title); + setKey(buildKey(account)); + setTitle(mTitle); setSummary(summary); setIcon(icon); @@ -115,6 +110,13 @@ public class AccountTypePreference extends Preference implements OnPreferenceCli return false; } + /** + * Build a unique preference key based on account. + */ + public static String buildKey(Account account) { + return String.valueOf(account.hashCode()); + } + public CharSequence getTitle() { return mTitle; } @@ -122,5 +124,4 @@ public class AccountTypePreference extends Preference implements OnPreferenceCli public CharSequence getSummary() { return mSummary; } - } diff --git a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java index 8453da5c58c..66f554941db 100644 --- a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java @@ -26,8 +26,8 @@ import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceGroup; import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceScreen; - import android.text.TextUtils; + import com.android.settings.AccessiblePreferenceCategory; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; @@ -92,7 +92,7 @@ public class AccountPreferenceControllerTest { when(mFragment.getPreferenceScreen()).thenReturn(mScreen); when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext); when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn( - new AuthenticatorDescription[0]); + new AuthenticatorDescription[0]); when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]); mController = new AccountPreferenceController(mContext, mFragment, null, mAccountHelper); } @@ -365,6 +365,51 @@ public class AccountPreferenceControllerTest { verify(preferenceGroup, times(3)).addPreference(any(Preference.class)); } + @Test + @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class}) + public void onResume_twoAccountsOfSameName_shouldAddFivePreferences() { + final List infos = new ArrayList<>(); + infos.add(new UserInfo(1, "user 1", 0)); + when(mUserManager.isManagedProfile()).thenReturn(false); + when(mUserManager.isLinkedUser()).thenReturn(false); + when(mUserManager.getProfiles(anyInt())).thenReturn(infos); + + final Account[] accountType1 = new Account[2]; + accountType1[0] = new Account("Account1", "com.acct1"); + accountType1[1] = new Account("Account2", "com.acct1"); + final Account[] accountType2 = new Account[2]; + accountType2[0] = new Account("Account1", "com.acct2"); + accountType2[1] = new Account("Account2", "com.acct2"); + final Account[] allAccounts = new Account[4]; + allAccounts[0] = accountType1[0]; + allAccounts[1] = accountType1[1]; + allAccounts[2] = accountType2[0]; + allAccounts[3] = accountType2[1]; + final AuthenticatorDescription[] authDescs = { + new AuthenticatorDescription("com.acct1", "com.android.settings", + R.string.account_settings_title, 0, 0, 0, false), + new AuthenticatorDescription("com.acct2", "com.android.settings", + R.string.account_settings_title, 0, 0, 0, false) + }; + + when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(allAccounts); + when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct1"), any(UserHandle.class))) + .thenReturn(accountType1); + when(mAccountManager.getAccountsByTypeAsUser(eq("com.acct2"), any(UserHandle.class))) + .thenReturn(accountType2); + when(mAccountManager.getAuthenticatorTypesAsUser(anyInt())).thenReturn(authDescs); + + AccessiblePreferenceCategory preferenceGroup = mock(AccessiblePreferenceCategory.class); + when(preferenceGroup.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); + when(mAccountHelper.createAccessiblePreferenceCategory(any(Context.class))).thenReturn( + preferenceGroup); + + mController.onResume(); + + // should add 4 individual account and the Add account preference + verify(preferenceGroup, times(5)).addPreference(any(Preference.class)); + } + @Test @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class}) public void onResume_noAccountChange_shouldNotAddAccountPreference() {