Fix settings page flicker in two ways:
1. On create use UiBlocker as recommended by settings team
2. On resume only update the preferences list if the system setting has
changed.
Bug: 220837804
Test: manual
Change-Id: Ieebd2e7fd74ab05d4fb73aede6868553d7d84af1
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index ab3ed20..ff8b4be 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -20,8 +20,12 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.database.ContentObserver;
import android.location.SettingInjectorService;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
@@ -66,6 +70,7 @@
private LocationSwitchBarController mSwitchBarController;
private LocationEnabler mLocationEnabler;
private RecentLocationAccessPreferenceController mController;
+ private ContentObserver mContentObserver;
@Override
public int getMetricsCategory() {
@@ -82,6 +87,16 @@
mSwitchBarController = new LocationSwitchBarController(activity, switchBar,
getSettingsLifecycle());
mLocationEnabler = new LocationEnabler(getContext(), this, getSettingsLifecycle());
+ mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mController.updateShowSystem();
+ }
+ };
+ getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(
+ Settings.Secure.LOCATION_SHOW_SYSTEM_OPS), /* notifyForDescendants= */
+ false, mContentObserver);
}
@Override
@@ -97,11 +112,9 @@
}
@Override
- public void onPause() {
- super.onPause();
- if (mController != null) {
- mController.clearPreferenceList();
- }
+ public void onDestroy() {
+ super.onDestroy();
+ getContentResolver().unregisterContentObserver(mContentObserver);
}
@Override
diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
index ea3704c..18221d0 100644
--- a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
@@ -28,6 +28,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settingslib.applications.RecentAppOpsAccess;
@@ -40,12 +41,15 @@
/**
* Preference controller that handles the display of apps that access locations.
*/
-public class RecentLocationAccessPreferenceController extends LocationBasePreferenceController {
+public class RecentLocationAccessPreferenceController extends LocationBasePreferenceController
+ implements BasePreferenceController.UiBlocker {
public static final int MAX_APPS = 3;
@VisibleForTesting
RecentAppOpsAccess mRecentLocationApps;
private PreferenceCategory mCategoryRecentLocationRequests;
private int mType = ProfileSelectFragment.ProfileType.ALL;
+ private boolean mShowSystem = false;
+ private boolean mSystemSettingChanged = false;
private static class PackageEntryClickedListener implements
Preference.OnPreferenceClickListener {
@@ -80,23 +84,32 @@
RecentAppOpsAccess recentLocationApps) {
super(context, key);
mRecentLocationApps = recentLocationApps;
+ mShowSystem = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mCategoryRecentLocationRequests = screen.findPreference(getPreferenceKey());
+ loadRecentAccesses();
}
@Override
public void updateState(Preference preference) {
+ // Only reload the recent accesses in updateState if the system setting has changed.
+ if (mSystemSettingChanged) {
+ loadRecentAccesses();
+ mSystemSettingChanged = false;
+ }
+ }
+
+ private void loadRecentAccesses() {
mCategoryRecentLocationRequests.removeAll();
final Context prefContext = mCategoryRecentLocationRequests.getContext();
final List<RecentAppOpsAccess.Access> recentLocationAccesses = new ArrayList<>();
final UserManager userManager = UserManager.get(mContext);
- final boolean showSystem = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1;
- for (RecentAppOpsAccess.Access access : mRecentLocationApps.getAppListSorted(showSystem)) {
+ for (RecentAppOpsAccess.Access access : mRecentLocationApps.getAppListSorted(mShowSystem)) {
if (isRequestMatchesProfileType(userManager, access, mType)) {
recentLocationAccesses.add(access);
if (recentLocationAccesses.size() == MAX_APPS) {
@@ -177,4 +190,14 @@
}
return false;
}
+
+ /**
+ * Update the state of the showSystem setting flag and load the new results.
+ */
+ void updateShowSystem() {
+ mSystemSettingChanged = true;
+ mShowSystem = !mShowSystem;
+ clearPreferenceList();
+ loadRecentAccesses();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/location/LocationSettingsTest.java b/tests/robotests/src/com/android/settings/location/LocationSettingsTest.java
index 3d624c0..aae8cec 100644
--- a/tests/robotests/src/com/android/settings/location/LocationSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationSettingsTest.java
@@ -20,6 +20,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.ContentResolver;
import android.content.Context;
import android.os.Bundle;
@@ -41,6 +42,8 @@
private SettingsActivity mActivity;
@Mock
private SettingsMainSwitchBar mSwitchBar;
+ @Mock
+ private ContentResolver mContentResolver;
private Context mContext;
private LocationSettings mLocationSettings;
@@ -52,6 +55,7 @@
mLocationSettings = spy(new LocationSettings());
doReturn(mActivity).when(mLocationSettings).getActivity();
doReturn(mContext).when(mLocationSettings).getContext();
+ doReturn(mContentResolver).when(mActivity).getContentResolver();
when(mActivity.getSwitchBar()).thenReturn(mSwitchBar);
}