From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: empratyush <codelab@pratyush.dev>
Date: Thu, 24 Mar 2022 11:55:21 +0530
Subject: [PATCH] make monet based theming user configurable

---
 core/java/android/provider/Settings.java      | 21 +++++
 .../theme/ThemeOverlayController.java         | 86 +++++++++++--------
 2 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a60ec93697a6..29a26dcd5d4b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6600,6 +6600,27 @@ public final class Settings {
             return putStringForUser(cr, name, Float.toString(value), userHandle);
         }
 
+        /**
+         * Control whether to enable dynamic monet based theming mode.
+         * @hide
+         */
+        @UnsupportedAppUsage
+        public static final String MONET_MODE = "monet_mode";
+
+        /**
+         * MONET_MODE value for enabled mode.
+         * @hide
+         */
+        @UnsupportedAppUsage
+        public static final int MONET_MODE_ENABLED = 1;
+
+        /**
+         * MONET_MODE value for disabled mode.
+         * @hide
+         */
+        @UnsupportedAppUsage
+        public static final int MONET_MODE_DISABLED = 0;
+
         /**
          * Control whether to enable adaptive sleep mode.
          * @hide
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 48e05575b8bb..9ed599e0a722 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -122,7 +122,6 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
     private final SystemSettings mSystemSettings;
     private final Executor mMainExecutor;
     private final Handler mBgHandler;
-    private final boolean mIsMonetEnabled;
     private final UserTracker mUserTracker;
     private final ConfigurationController mConfigurationController;
     private final DeviceProvisionedController mDeviceProvisionedController;
@@ -268,7 +267,11 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
         final boolean hadWallpaperColors = mCurrentColors.get(userId) != null;
         int latestWallpaperType = getLatestWallpaperType(userId);
         if ((flags & latestWallpaperType) != 0) {
-            mCurrentColors.put(userId, wallpaperColors);
+            if (isMonetEnabled(userId)) {
+                mCurrentColors.put(userId, wallpaperColors);
+            } else {
+                mCurrentColors.put(userId, null);
+            }
             if (DEBUG) Log.d(TAG, "got new colors: " + wallpaperColors + " where: " + flags);
         }
 
@@ -366,6 +369,15 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
         }
     };
 
+    private boolean isMonetEnabled(int user) {
+        return Settings.Secure.getIntForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.MONET_MODE,
+                Settings.Secure.MONET_MODE_DISABLED,
+                user
+        ) == Settings.Secure.MONET_MODE_ENABLED;
+    }
+
     @Inject
     public ThemeOverlayController(Context context, BroadcastDispatcher broadcastDispatcher,
             @Background Handler bgHandler, @Main Executor mainExecutor,
@@ -377,7 +389,6 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
             SystemSettings systemSettings, ConfigurationController configurationController) {
         super(context);
 
-        mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET);
         mConfigurationController = configurationController;
         mDeviceProvisionedController = deviceProvisionedController;
         mBroadcastDispatcher = broadcastDispatcher;
@@ -477,24 +488,17 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
                 },
                 UserHandle.USER_ALL);
 
-        if (!mIsMonetEnabled) {
-            return;
-        }
-
         mUserTracker.addCallback(mUserTrackerCallback, mMainExecutor);
 
         mConfigurationController.addCallback(mConfigurationListener);
         mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
 
-        // All wallpaper color and keyguard logic only applies when Monet is enabled.
-        if (!mIsMonetEnabled) {
-            return;
-        }
-
         // Upon boot, make sure we have the most up to date colors
         Runnable updateColors = () -> {
-            WallpaperColors systemColor = mWallpaperManager.getWallpaperColors(
-                    getLatestWallpaperType(mUserTracker.getUserId()));
+            WallpaperColors systemColor = isMonetEnabled(
+                    mUserTracker.getUserId()) ? mWallpaperManager.getWallpaperColors(
+                    getLatestWallpaperType(mUserTracker.getUserId()))
+                                             : null;
             Runnable applyColors = () -> {
                 if (DEBUG) Log.d(TAG, "Boot colors: " + systemColor);
                 mCurrentColors.put(mUserTracker.getUserId(), systemColor);
@@ -520,7 +524,8 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
             @Override
             public void onFinishedGoingToSleep() {
                 final int userId = mUserTracker.getUserId();
-                final WallpaperColors colors = mDeferredWallpaperColors.get(userId);
+                final WallpaperColors colors = isMonetEnabled(userId)
+                        ? mDeferredWallpaperColors.get(userId) : null;
                 if (colors != null) {
                     int flags = mDeferredWallpaperColorsFlags.get(userId);
 
@@ -531,10 +536,30 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
                 }
             }
         });
+
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.getUriFor(Settings.Secure.MONET_MODE),
+                false,
+                new ContentObserver(mBgHandler) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        super.onChange(selfChange);
+                        WallpaperColors color = isMonetEnabled(mUserTracker.getUserId())
+                                ? mWallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM, mUserTracker.getUserId())
+
+                                : null;
+                        handleWallpaperColors(color, WallpaperManager.FLAG_SYSTEM, mUserTracker.getUserId());
+                        reevaluateSystemTheme(true);
+                    }
+                },
+                UserHandle.USER_ALL
+        );
     }
 
     private void reevaluateSystemTheme(boolean forceReload) {
-        final WallpaperColors currentColors = mCurrentColors.get(mUserTracker.getUserId());
+        final WallpaperColors currentColors = isMonetEnabled(
+                   mUserTracker.getUserId()) ? mCurrentColors.get(mUserTracker.getUserId())
+                                             : null;
         final int mainColor;
         if (currentColors == null) {
             mainColor = Color.TRANSPARENT;
@@ -547,15 +572,13 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
         }
         mMainWallpaperColor = mainColor;
 
-        if (mIsMonetEnabled) {
-            mThemeStyle = fetchThemeStyleFromSetting();
-            mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
-            mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
-            mNeedsOverlayCreation = true;
-            if (DEBUG) {
-                Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
-                        + " neutral: " + mNeutralOverlay);
-            }
+        mThemeStyle = fetchThemeStyleFromSetting();
+        mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
+        mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
+        mNeedsOverlayCreation = true;
+        if (DEBUG) {
+            Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
+                    + " neutral: " + mNeutralOverlay);
         }
 
         updateThemeOverlays();
@@ -655,7 +678,7 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
 
         // Let's generate system overlay if the style picker decided to override it.
         OverlayIdentifier systemPalette = categoryToPackage.get(OVERLAY_CATEGORY_SYSTEM_PALETTE);
-        if (mIsMonetEnabled && systemPalette != null && systemPalette.getPackageName() != null) {
+        if (systemPalette != null && systemPalette.getPackageName() != null) {
             try {
                 String colorString =  systemPalette.getPackageName().toLowerCase();
                 if (!colorString.startsWith("#")) {
@@ -671,16 +694,6 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
                 // Color.parseColor doesn't catch any exceptions from the calls it makes
                 Log.w(TAG, "Invalid color definition: " + systemPalette.getPackageName(), e);
             }
-        } else if (!mIsMonetEnabled && systemPalette != null) {
-            try {
-                // It's possible that we flipped the flag off and still have a @ColorInt in the
-                // setting. We need to sanitize the input, otherwise the overlay transaction will
-                // fail.
-                categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
-                categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
-            } catch (NumberFormatException e) {
-                // This is a package name. All good, let's continue
-            }
         }
 
         // Compatibility with legacy themes, where full packages were defined, instead of just
@@ -758,7 +771,6 @@ public class ThemeOverlayController extends CoreStartable implements Dumpable {
         pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor));
         pw.println("mSecondaryOverlay=" + mSecondaryOverlay);
         pw.println("mNeutralOverlay=" + mNeutralOverlay);
-        pw.println("mIsMonetEnabled=" + mIsMonetEnabled);
         pw.println("mColorScheme=" + mColorScheme);
         pw.println("mNeedsOverlayCreation=" + mNeedsOverlayCreation);
         pw.println("mAcceptColorEvents=" + mAcceptColorEvents);
