Merge "Add ToggleableGlobalSettingsFlag for QUICK_SWITCH" into ub-launcher3-master
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index b27ae31..1ec7eec 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -17,11 +17,13 @@
 package com.android.launcher3.config;
 
 import static androidx.core.util.Preconditions.checkNotNull;
-
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.provider.Settings;
-
+import androidx.annotation.GuardedBy;
+import androidx.annotation.Keep;
+import androidx.annotation.VisibleForTesting;
 import com.android.launcher3.Utilities;
 
 import java.util.ArrayList;
@@ -29,10 +31,6 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import androidx.annotation.GuardedBy;
-import androidx.annotation.Keep;
-import androidx.annotation.VisibleForTesting;
-
 /**
  * Defines a set of flags used to control various launcher behaviors.
  *
@@ -88,7 +86,8 @@
     // trying to make them fit the orientation the device is in.
     public static final boolean OVERVIEW_USE_SCREENSHOT_ORIENTATION = true;
 
-    public static final TogglableFlag QUICK_SWITCH = new TogglableFlag("QUICK_SWITCH", false,
+    public static final ToggleableGlobalSettingsFlag QUICK_SWITCH
+            = new ToggleableGlobalSettingsFlag("navbar_quick_switch_enabled", false,
             "Swiping right on the nav bar while in an app switches to the previous app");
 
     /**
@@ -100,11 +99,9 @@
     public static void initialize(Context context) {
         // Avoid the disk read for user builds
         if (Utilities.IS_DEBUG_DEVICE) {
-            SharedPreferences sharedPreferences =
-                    context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE);
             synchronized (sLock) {
                 for (TogglableFlag flag : sFlags) {
-                    flag.currentValue = sharedPreferences.getBoolean(flag.key, flag.defaultValue);
+                    flag.initialize(context);
                 }
             }
         } else {
@@ -131,7 +128,7 @@
         return new ArrayList<>(flagsByKey.values());
     }
 
-    public static final class TogglableFlag {
+    public static class TogglableFlag {
         private final String key;
         private final boolean defaultValue;
         private final String description;
@@ -159,6 +156,24 @@
         public String getKey() {
             return key;
         }
+        void initialize(Context context) {
+            currentValue = getFromStorage(context, defaultValue);
+        }
+
+        void updateStorage(Context context, boolean value) {
+            SharedPreferences.Editor editor = context.getSharedPreferences(FLAGS_PREF_NAME,
+                    Context.MODE_PRIVATE).edit();
+            if (value == defaultValue) {
+                editor.remove(key).apply();
+            } else {
+                editor.putBoolean(key, value).apply();
+            }
+        }
+
+        boolean getFromStorage(Context context, boolean defaultValue) {
+            return context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
+                    .getBoolean(key, defaultValue);
+        }
 
         boolean getDefaultValue() {
             return defaultValue;
@@ -208,4 +223,37 @@
             return h$;
         }
     }
+
+    /**
+     * Stores the FeatureFlag's value in Settings.Global instead of our SharedPrefs.
+     * This is useful if we want to be able to control this flag from another process.
+     */
+    public static final class ToggleableGlobalSettingsFlag extends TogglableFlag {
+        private ContentResolver contentResolver;
+
+        ToggleableGlobalSettingsFlag(String key, boolean defaultValue, String description) {
+            super(key, defaultValue, description);
+        }
+
+        @Override
+        public void initialize(Context context) {
+            contentResolver = context.getContentResolver();
+            super.initialize(context);
+        }
+
+        @Override
+        void updateStorage(Context context, boolean value) {
+            Settings.Global.putInt(contentResolver, getKey(), value ? 1 : 0);
+        }
+
+        @Override
+        boolean getFromStorage(Context context, boolean defaultValue) {
+            return Settings.Global.getInt(contentResolver, getKey(), defaultValue ? 1 : 0) == 1;
+        }
+
+        @Override
+        public boolean get() {
+            return getFromStorage(null, getDefaultValue());
+        }
+    }
 }
diff --git a/src/com/android/launcher3/config/FlagTogglerPrefUi.java b/src/com/android/launcher3/config/FlagTogglerPrefUi.java
index d3be51d..5ecb186 100644
--- a/src/com/android/launcher3/config/FlagTogglerPrefUi.java
+++ b/src/com/android/launcher3/config/FlagTogglerPrefUi.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.os.Process;
+import android.text.Html;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -49,19 +50,24 @@
         public void putBoolean(String key, boolean value) {
             for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
                 if (flag.getKey().equals(key)) {
-                    if (value == flag.getDefaultValue()) {
-                        mSharedPreferences.edit().remove(key).apply();
-                    } else {
-                        mSharedPreferences.edit().putBoolean(key, value).apply();
-                    }
+                    boolean prevValue = flag.get();
+                    flag.updateStorage(mContext, value);
                     updateMenu();
+                    if (flag.get() != prevValue) {
+                        Toast.makeText(mContext, "Flag applied", Toast.LENGTH_SHORT).show();
+                    }
                 }
             }
         }
 
         @Override
-        public boolean getBoolean(String key, boolean defValue) {
-            return mSharedPreferences.getBoolean(key, defValue);
+        public boolean getBoolean(String key, boolean defaultValue) {
+            for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
+                if (flag.getKey().equals(key)) {
+                    return flag.getFromStorage(mContext, defaultValue);
+                }
+            }
+            return defaultValue;
         }
     };
 
@@ -83,14 +89,23 @@
             switchPreference.setDefaultValue(flag.getDefaultValue());
             switchPreference.setChecked(getFlagStateFromSharedPrefs(flag));
             switchPreference.setTitle(flag.getKey());
-            switchPreference.setSummaryOn(flag.getDefaultValue() ? "" : "overridden");
-            switchPreference.setSummaryOff(flag.getDefaultValue() ? "overridden" : "");
+            updateSummary(switchPreference, flag);
             switchPreference.setPreferenceDataStore(mDataStore);
             parent.addPreference(switchPreference);
         }
         updateMenu();
     }
 
+    /**
+     * Updates the summary to show the description and whether the flag overrides the default value.
+     */
+    private void updateSummary(SwitchPreference switchPreference, TogglableFlag flag) {
+        String onWarning = flag.getDefaultValue() ? "" : "<b>OVERRIDDEN</b><br>";
+        String offWarning = flag.getDefaultValue() ? "<b>OVERRIDDEN</b><br>" : "";
+        switchPreference.setSummaryOn(Html.fromHtml(onWarning + flag.getDescription()));
+        switchPreference.setSummaryOff(Html.fromHtml(offWarning + flag.getDescription()));
+    }
+
     private void updateMenu() {
         mFragment.setHasOptionsMenu(anyChanged());
         mFragment.getActivity().invalidateOptionsMenu();