From c89755525f419cba43968898df151dab2853eca6 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Wed, 6 Jul 2022 16:53:59 +0800 Subject: [PATCH] Update all preferences when the account preference updates UI When an account is added or removed, the account preference controller just updates the account list, whereas there's no trigger point for the account data sync preferences to refresh. Add an API to update all preferences in DashboardFragment, so we can refresh the account sync preferences whenever the account list is updated. Bug: 185479221 Test: robotest, manual Change-Id: Ide3d972abae09ce0175e3bafbb1f4a5e307d20c8 --- .../accounts/AccountDashboardFragment.java | 3 +-- .../AccountPersonalDashboardFragment.java | 3 +-- .../accounts/AccountPreferenceController.java | 12 ++++++---- .../AccountWorkProfileDashboardFragment.java | 3 +-- .../settings/dashboard/DashboardFragment.java | 24 +++++++++++++++++++ .../AutoSyncWorkDataPreferenceController.java | 4 +++- .../AccountPreferenceControllerTest.java | 4 ++-- .../dashboard/DashboardFragmentTest.java | 8 +++++++ 8 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/com/android/settings/accounts/AccountDashboardFragment.java b/src/com/android/settings/accounts/AccountDashboardFragment.java index a2b6182a715..5456f0ac694 100644 --- a/src/com/android/settings/accounts/AccountDashboardFragment.java +++ b/src/com/android/settings/accounts/AccountDashboardFragment.java @@ -26,7 +26,6 @@ import android.os.UserHandle; import android.os.UserManager; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.autofill.PasswordsPreferenceController; import com.android.settings.applications.defaultapps.DefaultAutofillPreferenceController; import com.android.settings.applications.defaultapps.DefaultWorkAutofillPreferenceController; @@ -96,7 +95,7 @@ public class AccountDashboardFragment extends DashboardFragment { } private static void buildAccountPreferenceControllers( - Context context, SettingsPreferenceFragment parent, String[] authorities, + Context context, DashboardFragment parent, String[] authorities, List controllers) { final AccountPreferenceController accountPrefController = new AccountPreferenceController(context, parent, authorities, diff --git a/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java b/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java index 9ad12067233..4661c6416e7 100644 --- a/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java +++ b/src/com/android/settings/accounts/AccountPersonalDashboardFragment.java @@ -24,7 +24,6 @@ import android.app.settings.SettingsEnums; import android.content.Context; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.autofill.PasswordsPreferenceController; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; @@ -78,7 +77,7 @@ public class AccountPersonalDashboardFragment extends DashboardFragment { } private static void buildAccountPreferenceControllers( - Context context, SettingsPreferenceFragment parent, String[] authorities, + Context context, DashboardFragment parent, String[] authorities, List controllers) { final AccountPreferenceController accountPrefController = new AccountPreferenceController(context, parent, authorities, diff --git a/src/com/android/settings/accounts/AccountPreferenceController.java b/src/com/android/settings/accounts/AccountPreferenceController.java index 145898869fb..8c717f03e77 100644 --- a/src/com/android/settings/accounts/AccountPreferenceController.java +++ b/src/com/android/settings/accounts/AccountPreferenceController.java @@ -58,10 +58,10 @@ import androidx.preference.PreferenceScreen; import com.android.settings.AccessiblePreferenceCategory; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.RestrictedPreference; @@ -101,7 +101,7 @@ public class AccountPreferenceController extends AbstractPreferenceController private Preference mProfileNotAvailablePreference; private String[] mAuthorities; private int mAuthoritiesCount = 0; - private SettingsPreferenceFragment mFragment; + private DashboardFragment mFragment; private int mAccountProfileOrder = ORDER_ACCOUNT_PROFILES; private AccountRestrictionHelper mHelper; private MetricsFeatureProvider mMetricsFeatureProvider; @@ -145,13 +145,13 @@ public class AccountPreferenceController extends AbstractPreferenceController public ArrayMap accountPreferences = new ArrayMap<>(); } - public AccountPreferenceController(Context context, SettingsPreferenceFragment parent, + public AccountPreferenceController(Context context, DashboardFragment parent, String[] authorities, @ProfileSelectFragment.ProfileType int type) { this(context, parent, authorities, new AccountRestrictionHelper(context), type); } @VisibleForTesting - AccountPreferenceController(Context context, SettingsPreferenceFragment parent, + AccountPreferenceController(Context context, DashboardFragment parent, String[] authorities, AccountRestrictionHelper helper, @ProfileSelectFragment.ProfileType int type) { super(context); @@ -314,6 +314,9 @@ public class AccountPreferenceController extends AbstractPreferenceController for (int i = 0; i < profilesCount; i++) { updateAccountTypes(mProfiles.valueAt(i)); } + + // Refresh for the auto-sync preferences + mFragment.forceUpdatePreferences(); } private void updateProfileUi(final UserInfo userInfo) { @@ -409,7 +412,6 @@ public class AccountPreferenceController extends AbstractPreferenceController return preference; } - private Preference newManagedProfileSettings() { Preference preference = new Preference(mFragment.getPreferenceManager().getContext()); preference.setKey(PREF_KEY_WORK_PROFILE_SETTING); diff --git a/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java b/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java index 1fdd3f6c428..f64e0416163 100644 --- a/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java +++ b/src/com/android/settings/accounts/AccountWorkProfileDashboardFragment.java @@ -24,7 +24,6 @@ import android.app.settings.SettingsEnums; import android.content.Context; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.autofill.PasswordsPreferenceController; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; @@ -78,7 +77,7 @@ public class AccountWorkProfileDashboardFragment extends DashboardFragment { } private static void buildAccountPreferenceControllers( - Context context, SettingsPreferenceFragment parent, String[] authorities, + Context context, DashboardFragment parent, String[] authorities, List controllers) { final AccountPreferenceController accountPrefController = new AccountPreferenceController(context, parent, authorities, diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java index fb0a09d47a7..9d1ed7c6bea 100644 --- a/src/com/android/settings/dashboard/DashboardFragment.java +++ b/src/com/android/settings/dashboard/DashboardFragment.java @@ -415,6 +415,30 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment updatePreferenceVisibility(mPreferenceControllers); } + /** + * Force update all the preferences in this fragment. + */ + public void forceUpdatePreferences() { + final PreferenceScreen screen = getPreferenceScreen(); + if (screen == null || mPreferenceControllers == null) { + return; + } + for (List controllerList : mPreferenceControllers.values()) { + for (AbstractPreferenceController controller : controllerList) { + final String key = controller.getPreferenceKey(); + final Preference preference = findPreference(key); + if (preference == null) { + continue; + } + final boolean available = controller.isAvailable(); + if (available) { + controller.updateState(preference); + } + preference.setVisible(available); + } + } + } + @VisibleForTesting void updatePreferenceVisibility( Map> preferenceControllers) { diff --git a/src/com/android/settings/users/AutoSyncWorkDataPreferenceController.java b/src/com/android/settings/users/AutoSyncWorkDataPreferenceController.java index fb571734331..9ac1b87112b 100644 --- a/src/com/android/settings/users/AutoSyncWorkDataPreferenceController.java +++ b/src/com/android/settings/users/AutoSyncWorkDataPreferenceController.java @@ -22,7 +22,8 @@ import androidx.preference.PreferenceFragmentCompat; import com.android.settings.Utils; -public class AutoSyncWorkDataPreferenceController extends AutoSyncPersonalDataPreferenceController { +/** An account sync data preference controller for work */ +public class AutoSyncWorkDataPreferenceController extends AutoSyncDataPreferenceController { private static final String KEY_AUTO_SYNC_WORK_ACCOUNT = "auto_sync_work_account_data"; @@ -38,6 +39,7 @@ public class AutoSyncWorkDataPreferenceController extends AutoSyncPersonalDataPr @Override public boolean isAvailable() { + mUserHandle = Utils.getManagedProfileWithDisabled(mUserManager); return mUserHandle != null && !mUserManager.isManagedProfile() && !mUserManager.isLinkedUser() && mUserManager.getProfiles(UserHandle.myUserId()).size() > 1; } diff --git a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java index b22b1562be2..89e00e12c7d 100644 --- a/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accounts/AccountPreferenceControllerTest.java @@ -45,7 +45,7 @@ import androidx.preference.PreferenceScreen; import com.android.settings.AccessiblePreferenceCategory; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; import com.android.settings.testutils.shadow.ShadowAccountManager; import com.android.settings.testutils.shadow.ShadowContentResolver; @@ -77,7 +77,7 @@ public class AccountPreferenceControllerTest { @Mock(answer = RETURNS_DEEP_STUBS) private UserManager mUserManager; @Mock(answer = RETURNS_DEEP_STUBS) - private SettingsPreferenceFragment mFragment; + private DashboardFragment mFragment; @Mock(answer = RETURNS_DEEP_STUBS) private AccountManager mAccountManager; @Mock(answer = RETURNS_DEEP_STUBS) diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java index 894a6c557df..fd6689a50a1 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java @@ -297,6 +297,14 @@ public class DashboardFragmentTest { mTestFragment.updatePreferenceVisibility(prefControllers); } + @Test + public void forceUpdatePreferences_prefKeyNull_shouldNotCrash() { + mTestFragment.addPreferenceController(new TestPreferenceController(mContext)); + + // Should not crash + mTestFragment.forceUpdatePreferences(); + } + @Test public void checkUiBlocker_noUiBlocker_controllerIsNull() { mTestFragment.mBlockerController = null;