Merge "Using a common class for observing secure settings" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index d71c08a..27f1399 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -15,23 +15,21 @@
  */
 package com.android.quickstep;
 
+import static com.android.quickstep.SwipeUpSetting.newSwipeUpSettingsObserver;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
-import static com.android.systemui.shared.system.SettingsCompat.SWIPE_UP_SETTING_NAME;
 
-import android.content.ContentResolver;
 import android.content.Context;
-import android.database.ContentObserver;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
-import android.provider.Settings;
 import android.util.Log;
 
 import com.android.launcher3.Utilities;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.SecureSettingsObserver;
 import com.android.launcher3.util.UiThreadHelper;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 
@@ -60,7 +58,7 @@
     private static final int MSG_SET_BACK_BUTTON_ALPHA = 201;
     private static final int MSG_SET_SWIPE_UP_ENABLED = 202;
 
-    private final SwipeUpGestureEnabledSettingObserver mSwipeUpSettingObserver;
+    private final SecureSettingsObserver mSwipeUpSettingObserver;
 
     private final Context mContext;
     private final Handler mUiHandler;
@@ -85,9 +83,11 @@
         mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
 
         if (SwipeUpSetting.isSwipeUpSettingAvailable()) {
-            mSwipeUpSettingObserver = new SwipeUpGestureEnabledSettingObserver(mUiHandler,
-                    context.getContentResolver());
+            mSwipeUpSettingObserver =
+                    newSwipeUpSettingsObserver(context, this::notifySwipeUpSettingChanged);
             mSwipeUpSettingObserver.register();
+            mSwipeUpEnabled = mSwipeUpSettingObserver.getValue();
+            resetHomeBounceSeenOnQuickstepEnabledFirstTime();
         } else {
             mSwipeUpSettingObserver = null;
             mSwipeUpEnabled = SwipeUpSetting.isSwipeUpEnabledDefaultValue();
@@ -192,34 +192,6 @@
                 sendToTarget();
     }
 
-    private class SwipeUpGestureEnabledSettingObserver extends ContentObserver {
-        private ContentResolver mResolver;
-        private final int defaultValue;
-
-        SwipeUpGestureEnabledSettingObserver(Handler handler, ContentResolver resolver) {
-            super(handler);
-            mResolver = resolver;
-            defaultValue = SwipeUpSetting.isSwipeUpEnabledDefaultValue() ? 1 : 0;
-        }
-
-        public void register() {
-            mResolver.registerContentObserver(Settings.Secure.getUriFor(SWIPE_UP_SETTING_NAME),
-                    false, this);
-            mSwipeUpEnabled = getValue();
-            resetHomeBounceSeenOnQuickstepEnabledFirstTime();
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            super.onChange(selfChange);
-            notifySwipeUpSettingChanged(getValue());
-        }
-
-        private boolean getValue() {
-            return Settings.Secure.getInt(mResolver, SWIPE_UP_SETTING_NAME, defaultValue) == 1;
-        }
-    }
-
     private void resetHomeBounceSeenOnQuickstepEnabledFirstTime() {
         if (mSwipeUpEnabled && !Utilities.getPrefs(mContext).getBoolean(
                 HAS_ENABLED_QUICKSTEP_ONCE, true)) {
diff --git a/quickstep/src/com/android/quickstep/SwipeUpSetting.java b/quickstep/src/com/android/quickstep/SwipeUpSetting.java
index 0f91f97..381ab9f 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpSetting.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpSetting.java
@@ -16,9 +16,15 @@
 
 package com.android.quickstep;
 
+import static com.android.systemui.shared.system.SettingsCompat.SWIPE_UP_SETTING_NAME;
+
+import android.content.Context;
 import android.content.res.Resources;
 import android.util.Log;
 
+import com.android.launcher3.util.SecureSettingsObserver;
+import com.android.launcher3.util.SecureSettingsObserver.OnChangeListener;
+
 public final class SwipeUpSetting {
     private static final String TAG = "SwipeUpSetting";
 
@@ -47,4 +53,10 @@
     public static boolean isSwipeUpEnabledDefaultValue() {
         return getSystemBooleanRes(SWIPE_UP_ENABLED_DEFAULT_RES_NAME);
     }
+
+    public static SecureSettingsObserver newSwipeUpSettingsObserver(Context context,
+            OnChangeListener listener) {
+        return new SecureSettingsObserver(context.getContentResolver(), listener,
+                SWIPE_UP_SETTING_NAME, isSwipeUpEnabledDefaultValue() ? 1 : 0);
+    }
 }
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index b02182c..6bf5812 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -16,7 +16,7 @@
 
 package com.android.launcher3;
 
-import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;
+import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver;
 
 import android.content.ComponentName;
 import android.content.ContentProviderClient;
@@ -33,7 +33,7 @@
 import com.android.launcher3.notification.NotificationListener;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.SettingsObserver;
+import com.android.launcher3.util.SecureSettingsObserver;
 
 public class LauncherAppState {
 
@@ -48,7 +48,7 @@
     private final IconCache mIconCache;
     private final WidgetPreviewLoader mWidgetCache;
     private final InvariantDeviceProfile mInvariantDeviceProfile;
-    private final SettingsObserver mNotificationBadgingObserver;
+    private final SecureSettingsObserver mNotificationBadgingObserver;
 
     public static LauncherAppState getInstance(final Context context) {
         return INSTANCE.get(context);
@@ -99,17 +99,17 @@
             mNotificationBadgingObserver = null;
         } else {
             // Register an observer to rebind the notification listener when badging is re-enabled.
-            mNotificationBadgingObserver = new SettingsObserver.Secure(
-                    mContext.getContentResolver()) {
-                @Override
-                public void onSettingChanged(boolean isNotificationBadgingEnabled) {
-                    if (isNotificationBadgingEnabled) {
-                        NotificationListener.requestRebind(new ComponentName(
-                                mContext, NotificationListener.class));
-                    }
-                }
-            };
-            mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
+            mNotificationBadgingObserver =
+                    newNotificationSettingsObserver(mContext, this::onNotificationSettingsChanged);
+            mNotificationBadgingObserver.register();
+            mNotificationBadgingObserver.dispatchOnChange();
+        }
+    }
+
+    protected void onNotificationSettingsChanged(boolean isNotificationBadgingEnabled) {
+        if (isNotificationBadgingEnabled) {
+            NotificationListener.requestRebind(new ComponentName(
+                    mContext, NotificationListener.class));
         }
     }
 
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index 60edcda..a17f614 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -18,6 +18,7 @@
 
 import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
 import static com.android.launcher3.states.RotationHelper.getAllowRotationDefaultValue;
+import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver;
 
 import android.annotation.TargetApi;
 import android.app.Activity;
@@ -25,7 +26,6 @@
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.app.Fragment;
-import android.app.FragmentManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -47,7 +47,7 @@
 import com.android.launcher3.graphics.IconShapeOverride;
 import com.android.launcher3.notification.NotificationListener;
 import com.android.launcher3.util.ListViewHighlighter;
-import com.android.launcher3.util.SettingsObserver;
+import com.android.launcher3.util.SecureSettingsObserver;
 import com.android.launcher3.views.ButtonPreference;
 
 import java.util.Objects;
@@ -61,8 +61,6 @@
     private static final String FLAGS_PREFERENCE_KEY = "flag_toggler";
 
     private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
-    /** Hidden field Settings.Secure.NOTIFICATION_BADGING */
-    public static final String NOTIFICATION_BADGING = "notification_badging";
     /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
     private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
 
@@ -114,7 +112,7 @@
      */
     public static class LauncherSettingsFragment extends PreferenceFragment {
 
-        private IconBadgingObserver mIconBadgingObserver;
+        private SecureSettingsObserver mIconBadgingObserver;
 
         private String mPreferenceKey;
         private boolean mPreferenceHighlighted = false;
@@ -147,9 +145,14 @@
                 getPreferenceScreen().removePreference(iconBadgingPref);
             } else {
                 // Listen to system notification badge settings while this UI is active.
-                mIconBadgingObserver = new IconBadgingObserver(
-                        iconBadgingPref, resolver, getFragmentManager());
-                mIconBadgingObserver.register(NOTIFICATION_BADGING, NOTIFICATION_ENABLED_LISTENERS);
+                mIconBadgingObserver = newNotificationSettingsObserver(
+                        getActivity(), new IconBadgingObserver(iconBadgingPref, resolver));
+                mIconBadgingObserver.register();
+                // Also listen if notification permission changes
+                mIconBadgingObserver.getResolver().registerContentObserver(
+                        Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS), false,
+                        mIconBadgingObserver);
+                mIconBadgingObserver.dispatchOnChange();
             }
 
             Preference iconShapeOverride = findPreference(IconShapeOverride.KEY_PREFERENCE);
@@ -255,22 +258,18 @@
      * Content observer which listens for system badging setting changes,
      * and updates the launcher badging setting subtext accordingly.
      */
-    private static class IconBadgingObserver extends SettingsObserver.Secure {
+    private static class IconBadgingObserver implements SecureSettingsObserver.OnChangeListener {
 
         private final ButtonPreference mBadgingPref;
         private final ContentResolver mResolver;
-        private final FragmentManager mFragmentManager;
 
-        public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver,
-                FragmentManager fragmentManager) {
-            super(resolver);
+        public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver) {
             mBadgingPref = badgingPref;
             mResolver = resolver;
-            mFragmentManager = fragmentManager;
         }
 
         @Override
-        public void onSettingChanged(boolean enabled) {
+        public void onSettingsChanged(boolean enabled) {
             int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off;
 
             boolean serviceEnabled = true;
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index 68cf7de..f27b728 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -16,7 +16,7 @@
 
 package com.android.launcher3.notification;
 
-import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;
+import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver;
 
 import android.annotation.TargetApi;
 import android.app.Notification;
@@ -28,14 +28,13 @@
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
-import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.SettingsObserver;
+import com.android.launcher3.util.SecureSettingsObserver;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -43,7 +42,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import androidx.annotation.Nullable;
 
@@ -79,7 +77,7 @@
     /** The last notification key that was dismissed from launcher UI */
     private String mLastKeyDismissedByLauncher;
 
-    private SettingsObserver mNotificationBadgingObserver;
+    private SecureSettingsObserver mNotificationBadgingObserver;
 
     private final Handler.Callback mWorkerCallback = new Handler.Callback() {
         @Override
@@ -196,19 +194,20 @@
         super.onListenerConnected();
         sIsConnected = true;
 
-        mNotificationBadgingObserver = new SettingsObserver.Secure(getContentResolver()) {
-            @Override
-            public void onSettingChanged(boolean isNotificationBadgingEnabled) {
-                if (!isNotificationBadgingEnabled && sIsConnected) {
-                    requestUnbind();
-                }
-            }
-        };
-        mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
+        mNotificationBadgingObserver =
+                newNotificationSettingsObserver(this, this::onNotificationBadgingChanged);
+        mNotificationBadgingObserver.register();
+        mNotificationBadgingObserver.dispatchOnChange();
 
         onNotificationFullRefresh();
     }
 
+    private void onNotificationBadgingChanged(boolean isNotificationBadgingEnabled) {
+        if (!isNotificationBadgingEnabled && sIsConnected) {
+            requestUnbind();
+        }
+    }
+
     private void onNotificationFullRefresh() {
         mWorkerHandler.obtainMessage(MSG_NOTIFICATION_FULL_REFRESH).sendToTarget();
     }
diff --git a/src/com/android/launcher3/util/SecureSettingsObserver.java b/src/com/android/launcher3/util/SecureSettingsObserver.java
new file mode 100644
index 0000000..48aa02b
--- /dev/null
+++ b/src/com/android/launcher3/util/SecureSettingsObserver.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.util;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings;
+
+/**
+ * Utility class to listen for secure settings changes
+ */
+public class SecureSettingsObserver extends ContentObserver {
+
+    /** Hidden field Settings.Secure.NOTIFICATION_BADGING */
+    public static final String NOTIFICATION_BADGING = "notification_badging";
+
+    private final ContentResolver mResolver;
+    private final String mKeySetting;
+    private final int mDefaultValue;
+    private final OnChangeListener mOnChangeListener;
+
+    public SecureSettingsObserver(ContentResolver resolver, OnChangeListener listener,
+            String keySetting, int defaultValue) {
+        super(new Handler());
+
+        mResolver = resolver;
+        mOnChangeListener = listener;
+        mKeySetting = keySetting;
+        mDefaultValue = defaultValue;
+    }
+
+    @Override
+    public void onChange(boolean selfChange) {
+        mOnChangeListener.onSettingsChanged(getValue());
+    }
+
+    public boolean getValue() {
+        return Settings.Secure.getInt(mResolver, mKeySetting, mDefaultValue) == 1;
+    }
+
+    public void register() {
+        mResolver.registerContentObserver(Settings.Secure.getUriFor(mKeySetting), false, this);
+    }
+
+    public ContentResolver getResolver() {
+        return mResolver;
+    }
+
+    public void dispatchOnChange() {
+        onChange(true);
+    }
+
+    public void unregister() {
+        mResolver.unregisterContentObserver(this);
+    }
+
+    public interface OnChangeListener {
+        void onSettingsChanged(boolean isEnabled);
+    }
+
+    public static SecureSettingsObserver newNotificationSettingsObserver(Context context,
+            OnChangeListener listener) {
+        return new SecureSettingsObserver(
+                context.getContentResolver(), listener, NOTIFICATION_BADGING, 1);
+    }
+}
diff --git a/src/com/android/launcher3/util/SettingsObserver.java b/src/com/android/launcher3/util/SettingsObserver.java
deleted file mode 100644
index 6baa242..0000000
--- a/src/com/android/launcher3/util/SettingsObserver.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-import android.content.ContentResolver;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.provider.Settings;
-
-public interface SettingsObserver {
-
-    /**
-     * Registers the content observer to call {@link #onSettingChanged(boolean)} when any of the
-     * passed settings change. The value passed to onSettingChanged() is based on the key setting.
-     */
-    void register(String keySetting, String ... dependentSettings);
-    void unregister();
-    void onSettingChanged(boolean keySettingEnabled);
-
-
-    abstract class Secure extends ContentObserver implements SettingsObserver {
-        private ContentResolver mResolver;
-        private String mKeySetting;
-
-        public Secure(ContentResolver resolver) {
-            super(new Handler());
-            mResolver = resolver;
-        }
-
-        @Override
-        public void register(String keySetting, String ... dependentSettings) {
-            mKeySetting = keySetting;
-            mResolver.registerContentObserver(
-                    Settings.Secure.getUriFor(mKeySetting), false, this);
-            for (String setting : dependentSettings) {
-                mResolver.registerContentObserver(
-                        Settings.Secure.getUriFor(setting), false, this);
-            }
-            onChange(true);
-        }
-
-        @Override
-        public void unregister() {
-            mResolver.unregisterContentObserver(this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            super.onChange(selfChange);
-            onSettingChanged(Settings.Secure.getInt(mResolver, mKeySetting, 1) == 1);
-        }
-    }
-
-    abstract class System extends ContentObserver implements SettingsObserver {
-        private ContentResolver mResolver;
-        private String mKeySetting;
-
-        public System(ContentResolver resolver) {
-            super(new Handler());
-            mResolver = resolver;
-        }
-
-        @Override
-        public void register(String keySetting, String ... dependentSettings) {
-            mKeySetting = keySetting;
-            mResolver.registerContentObserver(
-                    Settings.System.getUriFor(mKeySetting), false, this);
-            for (String setting : dependentSettings) {
-                mResolver.registerContentObserver(
-                        Settings.System.getUriFor(setting), false, this);
-            }
-            onChange(true);
-        }
-
-        @Override
-        public void unregister() {
-            mResolver.unregisterContentObserver(this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            super.onChange(selfChange);
-            onSettingChanged(Settings.System.getInt(mResolver, mKeySetting, 1) == 1);
-        }
-    }
-}
diff --git a/tests/Android.mk b/tests/Android.mk
index 7cba33a..d808873 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -27,7 +27,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, tapl) \
   ../quickstep/src/com/android/quickstep/SwipeUpSetting.java \
-  ../src/com/android/launcher3/TestProtocol.java
+  ../src/com/android/launcher3/util/SecureSettingsObserver.java \
+  ../src/com/android/launcher3/TestProtocol.java \
 
 LOCAL_SDK_VERSION := current
 LOCAL_MODULE := ub-launcher-aosp-tapl