From 58530bd64b51419a9d6dbd9c13ec80153c4e6b95 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 31 Mar 2021 15:56:11 -0700 Subject: [PATCH] Fixing notification dots settings not updated properly Also avoiding settings cache reset whenever someone registers a new listener Bug: 184200027 Test: Manual Change-Id: I0c8b7084b6b4656102e9041b779b80a98624ddd8 --- .../RecentsAnimationDeviceState.java | 4 +-- .../logging/SettingsChangeLogger.java | 2 +- .../android/launcher3/LauncherAppState.java | 2 +- .../notification/NotificationListener.java | 6 ++-- .../settings/NotificationDotsPreference.java | 34 +++++++++++++++++++ .../launcher3/settings/SettingsActivity.java | 34 +------------------ .../android/launcher3/util/SettingsCache.java | 22 +++++------- 7 files changed, 51 insertions(+), 53 deletions(-) diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java index 458f45a75d..23e35f6307 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -187,7 +187,7 @@ public class RecentsAnimationDeviceState implements SettingsCache.OnChangeListener onChangeListener = enabled -> mIsOneHandedModeEnabled = enabled; settingsCache.register(oneHandedUri, onChangeListener); - settingsCache.dispatchOnChange(oneHandedUri); + mIsOneHandedModeEnabled = settingsCache.getValue(oneHandedUri); runOnDestroy(() -> settingsCache.unregister(oneHandedUri, onChangeListener)); } else { mIsOneHandedModeEnabled = false; @@ -199,7 +199,7 @@ public class RecentsAnimationDeviceState implements SettingsCache.OnChangeListener onChangeListener = enabled -> mIsSwipeToNotificationEnabled = enabled; settingsCache.register(swipeBottomNotificationUri, onChangeListener); - settingsCache.dispatchOnChange(swipeBottomNotificationUri); + mIsSwipeToNotificationEnabled = settingsCache.getValue(swipeBottomNotificationUri); runOnDestroy(() -> settingsCache.unregister(swipeBottomNotificationUri, onChangeListener)); Uri setupCompleteUri = Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE); diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java index f336bf5260..b336d2fcea 100644 --- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java +++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java @@ -80,7 +80,7 @@ public class SettingsChangeLogger implements SettingsCache mSettingsCache = SettingsCache.INSTANCE.get(context); mSettingsCache.register(NOTIFICATION_BADGING_URI, this::onNotificationDotsChanged); - mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI); + onNotificationDotsChanged(mSettingsCache.getValue(NOTIFICATION_BADGING_URI)); } private static ArrayMap loadPrefKeys(Context context) { diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index ccc023ab76..4754558aa1 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -116,7 +116,7 @@ public class LauncherAppState { mNotificationSettingsChangedListener = this::onNotificationSettingsChanged; mSettingsCache.register(NOTIFICATION_BADGING_URI, mNotificationSettingsChangedListener); - mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI); + onNotificationSettingsChanged(mSettingsCache.getValue(NOTIFICATION_BADGING_URI)); } public LauncherAppState(Context context, @Nullable String iconCacheFileName) { diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java index 2905dc322a..e58f5fa2d5 100644 --- a/src/com/android/launcher3/notification/NotificationListener.java +++ b/src/com/android/launcher3/notification/NotificationListener.java @@ -16,9 +16,9 @@ package com.android.launcher3.notification; -import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; +import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI; import android.annotation.TargetApi; import android.app.Notification; @@ -37,8 +37,8 @@ import androidx.annotation.AnyThread; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import com.android.launcher3.util.SettingsCache; import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.util.SettingsCache; import java.util.ArrayList; import java.util.Arrays; @@ -213,7 +213,7 @@ public class NotificationListener extends NotificationListenerService { mNotificationSettingsChangedListener = this::onNotificationSettingsChanged; mSettingsCache.register(NOTIFICATION_BADGING_URI, mNotificationSettingsChangedListener); - mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI); + onNotificationSettingsChanged(mSettingsCache.getValue(NOTIFICATION_BADGING_URI)); onNotificationFullRefresh(); } diff --git a/src/com/android/launcher3/settings/NotificationDotsPreference.java b/src/com/android/launcher3/settings/NotificationDotsPreference.java index a35416915f..afcf882e7d 100644 --- a/src/com/android/launcher3/settings/NotificationDotsPreference.java +++ b/src/com/android/launcher3/settings/NotificationDotsPreference.java @@ -17,6 +17,8 @@ package com.android.launcher3.settings; import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY; import static com.android.launcher3.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGS; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI; import android.app.AlertDialog; import android.app.Dialog; @@ -24,6 +26,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.database.ContentObserver; import android.os.Bundle; import android.provider.Settings; import android.util.AttributeSet; @@ -49,6 +52,14 @@ public class NotificationDotsPreference extends Preference /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */ private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners"; + private final ContentObserver mListenerListObserver = + new ContentObserver(MAIN_EXECUTOR.getHandler()) { + @Override + public void onChange(boolean selfChange) { + updateUI(); + } + }; + public NotificationDotsPreference( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); @@ -66,6 +77,29 @@ public class NotificationDotsPreference extends Preference super(context); } + @Override + public void onAttached() { + super.onAttached(); + SettingsCache.INSTANCE.get(getContext()).register(NOTIFICATION_BADGING_URI, this); + getContext().getContentResolver().registerContentObserver( + Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS), + false, mListenerListObserver); + updateUI(); + } + + private void updateUI() { + onSettingsChanged(SettingsCache.INSTANCE.get(getContext()) + .getValue(NOTIFICATION_BADGING_URI)); + } + + @Override + public void onDetached() { + super.onDetached(); + SettingsCache.INSTANCE.get(getContext()).unregister(NOTIFICATION_BADGING_URI, this); + getContext().getContentResolver().unregisterContentObserver(mListenerListObserver); + + } + private void setWidgetFrameVisible(boolean isVisible) { if (mWidgetFrameVisible != isVisible) { mWidgetFrameVisible = isVisible; diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java index f03065c7f8..5b42ac70eb 100644 --- a/src/com/android/launcher3/settings/SettingsActivity.java +++ b/src/com/android/launcher3/settings/SettingsActivity.java @@ -18,8 +18,6 @@ package com.android.launcher3.settings; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS; -import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI; -import static com.android.launcher3.util.SettingsCache.NOTIFICATION_ENABLED_LISTENERS; import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY; import static com.android.launcher3.states.RotationHelper.getAllowRotationDefaultValue; @@ -45,7 +43,6 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.WidgetsModel; -import com.android.launcher3.util.SettingsCache; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper; /** @@ -124,11 +121,8 @@ public class SettingsActivity extends FragmentActivity */ public static class LauncherSettingsFragment extends PreferenceFragmentCompat { - private SettingsCache mSettingsCache; - private String mHighLightKey; private boolean mPreferenceHighlighted = false; - private NotificationDotsPreference mNotificationSettingsChangedListener; private Preference mDeveloperOptionPref; @Override @@ -172,22 +166,7 @@ public class SettingsActivity extends FragmentActivity protected boolean initPreference(Preference preference) { switch (preference.getKey()) { case NOTIFICATION_DOTS_PREFERENCE_KEY: - if (WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS) { - return false; - } - - // Listen to system notification dot settings while this UI is active. - mSettingsCache = SettingsCache.INSTANCE.get(getActivity()); - mNotificationSettingsChangedListener = - ((NotificationDotsPreference) preference); - mSettingsCache.register(NOTIFICATION_BADGING_URI, - (NotificationDotsPreference) mNotificationSettingsChangedListener); - // Also listen if notification permission changes - mSettingsCache.register(NOTIFICATION_ENABLED_LISTENERS, - mNotificationSettingsChangedListener); - mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI); - mSettingsCache.dispatchOnChange(NOTIFICATION_ENABLED_LISTENERS); - return true; + return !WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS; case ALLOW_ROTATION_PREFERENCE_KEY: if (getResources().getBoolean(R.bool.allow_rotation)) { @@ -269,16 +248,5 @@ public class SettingsActivity extends FragmentActivity } }); } - - @Override - public void onDestroy() { - if (mSettingsCache != null) { - mSettingsCache.unregister(NOTIFICATION_BADGING_URI, - mNotificationSettingsChangedListener); - mSettingsCache.unregister(NOTIFICATION_ENABLED_LISTENERS, - mNotificationSettingsChangedListener); - } - super.onDestroy(); - } } } diff --git a/src/com/android/launcher3/util/SettingsCache.java b/src/com/android/launcher3/util/SettingsCache.java index 22b4d38891..10611c7211 100644 --- a/src/com/android/launcher3/util/SettingsCache.java +++ b/src/com/android/launcher3/util/SettingsCache.java @@ -39,12 +39,11 @@ import java.util.concurrent.CopyOnWriteArrayList; * {@link #unregister(Uri, OnChangeListener)} methods. * * This can be used as a normal cache without any listeners as well via the - * {@link #getValue(Uri, int)} and {@link #dispatchOnChange(Uri)} to update (and subsequently call + * {@link #getValue(Uri, int)} and {@link #onChange)} to update (and subsequently call * get) * * The cache will be invalidated/updated through the normal * {@link ContentObserver#onChange(boolean)} calls - * or can be force updated by calling {@link #dispatchOnChange(Uri)}. * * Cache will also be updated if a key queried is missing (even if it has no listeners registered). */ @@ -58,9 +57,6 @@ public class SettingsCache extends ContentObserver { /** Hidden field Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED */ public static final String ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED = "swipe_bottom_to_notification_enabled"; - /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */ - public static final Uri NOTIFICATION_ENABLED_LISTENERS = - Settings.Secure.getUriFor("enabled_notification_listeners"); public static final Uri ROTATION_SETTING_URI = Settings.System.getUriFor(ACCELEROMETER_ROTATION); @@ -99,6 +95,14 @@ public class SettingsCache extends ContentObserver { } } + /** + * Returns the value for this classes key from the cache. If not in cache, will call + * {@link #updateValue(Uri, int)} to fetch. + */ + public boolean getValue(Uri keySetting) { + return getValue(keySetting, 1); + } + /** * Returns the value for this classes key from the cache. If not in cache, will call * {@link #updateValue(Uri, int)} to fetch. @@ -139,14 +143,6 @@ public class SettingsCache extends ContentObserver { return newVal; } - /** - * Force update a change for a given URI and have all listeners for that URI receive callbacks - * even if the value is unchanged. - */ - public void dispatchOnChange(Uri uri) { - onChange(true, uri); - } - /** * Call to stop receiving updates on the given {@param listener}. * This Uri/Listener pair must correspond to the same pair called with for