Fix accessibility settings page did not update the preference state

Root Cause: Keys in ContentObserver registered after the keys change

Solution: Keys in ContentObserver need to be observed during the whole lifecycle to update the preferences including summary text

Fix: 183157677
Fix: 172469017
Fix: 183459237
Fix: 183459376
Test: atest AccessibilitySettingsTest
Change-Id: I3b22773965f1878c499a0f9cbd8bd0f3c9c6fae9
This commit is contained in:
jasonwshsu
2021-01-11 22:16:17 +08:00
parent 818c5396ce
commit 15df635dd6
2 changed files with 194 additions and 47 deletions

View File

@@ -111,7 +111,7 @@ public class AccessibilitySettings extends DashboardFragment {
@Override
public void run() {
if (getActivity() != null) {
updateServicePreferences();
onContentChanged();
}
}
};
@@ -142,7 +142,8 @@ public class AccessibilitySettings extends DashboardFragment {
}
};
private final SettingsContentObserver mSettingsContentObserver;
@VisibleForTesting
final SettingsContentObserver mSettingsContentObserver;
private final Map<String, PreferenceCategory> mCategoryToPrefCategoryMap =
new ArrayMap<>();
@@ -151,6 +152,9 @@ public class AccessibilitySettings extends DashboardFragment {
private final Map<ComponentName, PreferenceCategory> mPreBundledServiceComponentToCategoryMap =
new ArrayMap<>();
private boolean mNeedPreferencesUpdate = false;
private boolean mIsForeground = true;
public AccessibilitySettings() {
// Observe changes to anything that the shortcut can toggle, so we can reflect updates
final Collection<AccessibilityShortcutController.ToggleableFrameworkFeatureInfo> features =
@@ -166,7 +170,7 @@ public class AccessibilitySettings extends DashboardFragment {
mSettingsContentObserver = new SettingsContentObserver(mHandler, shortcutFeatureKeys) {
@Override
public void onChange(boolean selfChange, Uri uri) {
updateAllPreferences();
onContentChanged();
}
};
}
@@ -181,13 +185,6 @@ public class AccessibilitySettings extends DashboardFragment {
return R.string.help_uri_accessibility;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
initializeAllPreferences();
updateAllPreferences();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
@@ -196,20 +193,35 @@ public class AccessibilitySettings extends DashboardFragment {
}
@Override
public void onStart() {
super.onStart();
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
initializeAllPreferences();
updateAllPreferences();
registerContentMonitors();
}
mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
mSettingsContentObserver.register(getContentResolver());
@Override
public void onStart() {
if (mNeedPreferencesUpdate) {
updateAllPreferences();
mNeedPreferencesUpdate = false;
}
mIsForeground = true;
super.onStart();
}
@Override
public void onStop() {
mSettingsPackageMonitor.unregister();
mSettingsContentObserver.unregister(getContentResolver());
mIsForeground = false;
super.onStop();
}
@Override
public void onDestroy() {
unregisterContentMonitors();
super.onDestroy();
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.accessibility_settings;
@@ -283,6 +295,17 @@ public class AccessibilitySettings extends DashboardFragment {
context.getContentResolver(), Settings.Global.APPLY_RAMPING_RINGER, 0) == 1;
}
@VisibleForTesting
void onContentChanged() {
// If the fragment is visible then update preferences immediately, else set the flag then
// wait for the fragment to show up to update preferences.
if (mIsForeground) {
updateAllPreferences();
} else {
mNeedPreferencesUpdate = true;
}
}
private void initializeAllPreferences() {
for (int i = 0; i < CATEGORIES.length; i++) {
PreferenceCategory prefCategory = findPreference(CATEGORIES[i]);
@@ -290,11 +313,25 @@ public class AccessibilitySettings extends DashboardFragment {
}
}
private void updateAllPreferences() {
@VisibleForTesting
void updateAllPreferences() {
updateSystemPreferences();
updateServicePreferences();
}
private void registerContentMonitors() {
final Context context = getActivity();
mSettingsPackageMonitor.register(context, context.getMainLooper(), /* externalStorage= */
false);
mSettingsContentObserver.register(getContentResolver());
}
private void unregisterContentMonitors() {
mSettingsPackageMonitor.unregister();
mSettingsContentObserver.unregister(getContentResolver());
}
protected void updateServicePreferences() {
// Since services category is auto generated we have to do a pass
// to generate it since services can come and go and then based on