Restarting launcher if a flag changes

> Only restart when the screen is off.
> This allows better propogation of flags similar to systemUI
> Adding support for integer flags

Bug: 266854800
Test: Verified on device using device_config shell command
Change-Id: I4ea9c564f2d973f11f9570b5a21365183afefab7
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index 29ef2b4..84b873d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -18,28 +18,53 @@
 
 import static android.app.ActivityThread.currentApplication;
 
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
+import android.util.Log;
 
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags.BooleanFlag;
+import com.android.launcher3.config.FeatureFlags.IntFlag;
+import com.android.launcher3.util.ScreenOnTracker;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Helper class to create various flags for system build
  */
 public class FlagsFactory {
 
+    private static final String TAG = "FlagsFactory";
+
+    private static final FlagsFactory INSTANCE = new FlagsFactory();
+    private static final boolean FLAG_AUTO_APPLY_ENABLED = false;
+
     public static final String FLAGS_PREF_NAME = "featureFlags";
     public static final String NAMESPACE_LAUNCHER = "launcher";
 
     private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
 
+
+    private final Set<String> mKeySet = new HashSet<>();
+    private boolean mRestartRequested = false;
+
+    private FlagsFactory() {
+        if (!FLAG_AUTO_APPLY_ENABLED) {
+            return;
+        }
+        DeviceConfig.addOnPropertiesChangedListener(
+                NAMESPACE_LAUNCHER, UI_HELPER_EXECUTOR, this::onPropertiesChanged);
+    }
+
     /**
      * Creates a new debug flag
      */
@@ -63,6 +88,7 @@
      */
     public static BooleanFlag getReleaseFlag(
             int bugId, String key, boolean defaultValueInCode, String description) {
+        INSTANCE.mKeySet.add(key);
         boolean defaultValue = DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, key, defaultValueInCode);
         if (Utilities.IS_DEBUG_DEVICE) {
             SharedPreferences prefs = currentApplication()
@@ -78,6 +104,15 @@
         }
     }
 
+    /**
+     * Creates a new integer flag. Integer flags are always release flags
+     */
+    public static IntFlag getIntFlag(
+            int bugId, String key, int defaultValueInCode, String description) {
+        INSTANCE.mKeySet.add(key);
+        return new IntFlag(DeviceConfig.getInt(NAMESPACE_LAUNCHER, key, defaultValueInCode));
+    }
+
     static List<DebugFlag> getDebugFlags() {
         if (!Utilities.IS_DEBUG_DEVICE) {
             return Collections.emptyList();
@@ -121,4 +156,28 @@
             }
         }
     }
+
+    private void onPropertiesChanged(Properties properties) {
+        if (!Collections.disjoint(properties.getKeyset(), mKeySet)) {
+            // Schedule a restart
+            if (mRestartRequested) {
+                return;
+            }
+            Log.e(TAG, "Flag changed, scheduling restart");
+            mRestartRequested = true;
+            ScreenOnTracker sot = ScreenOnTracker.INSTANCE.get(currentApplication());
+            if (sot.isScreenOn()) {
+                sot.addListener(this::onScreenOnChanged);
+            } else {
+                onScreenOnChanged(false);
+            }
+        }
+    }
+
+    private void onScreenOnChanged(boolean isOn) {
+        if (mRestartRequested && !isOn) {
+            Log.e(TAG, "Restart requested, killing process");
+            System.exit(0);
+        }
+    }
 }
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index db2b759..6adf54d 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -400,4 +400,20 @@
             return mCurrentValue;
         }
     }
+
+    /**
+     * Class representing an integer flag
+     */
+    public static class IntFlag {
+
+        private final int mCurrentValue;
+
+        public IntFlag(int currentValue) {
+            mCurrentValue = currentValue;
+        }
+
+        public int get() {
+            return mCurrentValue;
+        }
+    }
 }
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index 599969b..4463adc 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -17,6 +17,7 @@
 package com.android.launcher3.uioverrides.flags;
 
 import com.android.launcher3.config.FeatureFlags.BooleanFlag;
+import com.android.launcher3.config.FeatureFlags.IntFlag;
 
 import java.io.PrintWriter;
 
@@ -43,6 +44,14 @@
     }
 
     /**
+     * Creates a new integer flag. Integer flags are always release flags
+     */
+    public static IntFlag getIntFlag(
+            int bugId, String key, int defaultValueInCode, String description) {
+        return new IntFlag(defaultValueInCode);
+    }
+
+    /**
      * Dumps the current flags state to the print writer
      */
     public static void dump(PrintWriter pw) { }