From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: empratyush <codelab@pratyush.dev>
Date: Sun, 27 Mar 2022 11:56:58 +0530
Subject: [PATCH] add a UI for enabling Material You

---
 res/layout/monet_mode_section_view.xml        |  30 +++++
 res/values/strings.xml                        |   2 +
 .../monet/MonetModeSectionController.java     | 126 ++++++++++++++++++
 .../module/DefaultCustomizationSections.java  |   5 +
 .../picker/monet/MonetModeSectionView.java    |  53 ++++++++
 5 files changed, 216 insertions(+)
 create mode 100644 res/layout/monet_mode_section_view.xml
 create mode 100644 src/com/android/customization/model/monet/MonetModeSectionController.java
 create mode 100644 src/com/android/customization/picker/monet/MonetModeSectionView.java

diff --git a/res/layout/monet_mode_section_view.xml b/res/layout/monet_mode_section_view.xml
new file mode 100644
index 0000000..2cfed92
--- /dev/null
+++ b/res/layout/monet_mode_section_view.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.customization.picker.monet.MonetModeSectionView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?selectableItemBackground"
+    android:clickable="true"
+    android:gravity="center_vertical"
+    android:orientation="horizontal"
+    android:paddingVertical="@dimen/section_vertical_padding"
+    android:paddingHorizontal="@dimen/section_horizontal_padding">
+
+    <TextView
+        android:id="@+id/monet_mode_toggle_title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:text="@string/monet_title"
+        style="@style/SectionTitleTextStyle"/>
+
+    <Switch
+        android:id="@+id/monet_mode_toggle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@null"
+        android:clickable="false"
+        android:focusable="false"
+        style="@style/Switch.SettingsLib"/>
+
+</com.android.customization.picker.monet.MonetModeSectionView>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f2d0f21..d5f0c46 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -236,6 +236,8 @@
     <!-- The title of mode section view. [CHAR_LIMIT=20] -->
     <string name="mode_title" msgid="1000319159005403986">Dark theme</string>
     <string name="mode_disabled_msg" msgid="1926077857799715086">Temporarily disabled due to Battery Saver</string>
+
+    <string name="monet_title">Use wallpaper colors</string>
     <!-- The text for A11y announcement when theme changes. -->
     <string name="mode_changed">Theme changed</string>
 
diff --git a/src/com/android/customization/model/monet/MonetModeSectionController.java b/src/com/android/customization/model/monet/MonetModeSectionController.java
new file mode 100644
index 0000000..95796a1
--- /dev/null
+++ b/src/com/android/customization/model/monet/MonetModeSectionController.java
@@ -0,0 +1,126 @@
+package com.android.customization.model.monet;
+
+import static android.provider.Settings.Secure.MONET_MODE_DISABLED;
+import static android.provider.Settings.Secure.MONET_MODE_ENABLED;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.widget.Switch;
+
+import androidx.annotation.MainThread;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
+import com.android.customization.picker.monet.MonetModeSectionView;
+import com.android.wallpaper.R;
+import com.android.wallpaper.model.CustomizationSectionController;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class MonetModeSectionController implements
+        CustomizationSectionController<MonetModeSectionView>, LifecycleObserver {
+
+    private static final ExecutorService sExecutorService = Executors.newSingleThreadExecutor();
+    private final Lifecycle mLifecycle;
+    private Context mContext;
+    private MonetModeSectionView mMonetModeSectionView;
+
+    private final ContentObserver mContentObserver = new ContentObserver(
+            new Handler(Looper.getMainLooper())) {
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            sExecutorService.execute(() -> {
+                //set is checked ??
+            });
+        }
+    };
+
+    public MonetModeSectionController(Context context, Lifecycle lifecycle) {
+        mContext = context;
+        mLifecycle = lifecycle;
+        mLifecycle.addObserver(this);
+    }
+
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_START)
+    @MainThread
+    public void onStart() {
+        sExecutorService.submit(() -> {
+            if (mContext != null && mLifecycle.getCurrentState().isAtLeast(
+                    Lifecycle.State.STARTED)) {
+
+                mContext.getContentResolver().registerContentObserver(
+                        Settings.Secure.getUriFor(Settings.Secure.MONET_MODE), false,
+                        mContentObserver);
+            }
+        });
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+    @MainThread
+    public void onStop() {
+        sExecutorService.submit(() -> {
+            mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+        });
+    }
+
+    @Override
+    public void release() {
+        mLifecycle.removeObserver(this);
+        mContext = null;
+    }
+
+    @Override
+    public boolean isAvailable(Context context) {
+        return context != null;
+    }
+
+    @Override
+    public MonetModeSectionView createView(Context context) {
+        mMonetModeSectionView = (MonetModeSectionView) LayoutInflater.from(context).inflate(
+                R.layout.monet_mode_section_view, /* root= */ null);
+        mMonetModeSectionView.setViewListener(this::onViewActivated);
+        mMonetModeSectionView.setEnabled(isAvailable(context));
+        return mMonetModeSectionView;
+    }
+
+    private void onViewActivated(Context context, boolean viewActivated) {
+        if (context == null) {
+            return;
+        }
+        Switch switchView = mMonetModeSectionView.findViewById(R.id.monet_mode_toggle);
+        int shortDelay = context.getResources().getInteger(android.R.integer.config_shortAnimTime);
+        new Handler(Looper.getMainLooper()).postDelayed(() -> {
+                    mMonetModeSectionView.announceForAccessibility(
+                            context.getString(R.string.mode_changed));
+                    setMonetEnabled(viewActivated, context);
+                },
+                /* delayMillis= */ shortDelay);
+    }
+
+    public static boolean isMonetEnabled(Context context) {
+        return Settings.Secure.getIntForUser(
+                context.getContentResolver(),
+                Settings.Secure.MONET_MODE,
+                MONET_MODE_ENABLED,
+                context.getUserId()
+        ) == MONET_MODE_ENABLED;
+    }
+
+    public static void setMonetEnabled(boolean isEnabled, Context context) {
+        Settings.Secure.putIntForUser(context.getContentResolver(),
+                Settings.Secure.MONET_MODE,
+                isEnabled ? MONET_MODE_ENABLED : MONET_MODE_DISABLED,
+                context.getUserId()
+        );
+    }
+
+
+}
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index a4510ea..1aff3e7 100644
--- a/src/com/android/customization/module/DefaultCustomizationSections.java
+++ b/src/com/android/customization/module/DefaultCustomizationSections.java
@@ -9,6 +9,7 @@ import androidx.lifecycle.LifecycleOwner;
 import com.android.customization.model.grid.GridOptionsManager;
 import com.android.customization.model.grid.GridSectionController;
 import com.android.customization.model.mode.DarkModeSectionController;
+import com.android.customization.model.monet.MonetModeSectionController;
 import com.android.customization.model.themedicon.ThemedIconSectionController;
 import com.android.customization.model.themedicon.ThemedIconSwitchProvider;
 import com.android.wallpaper.model.CustomizationSectionController;
@@ -45,6 +46,10 @@ public final class DefaultCustomizationSections implements CustomizationSections
         sectionControllers.add(new DarkModeSectionController(activity,
                 lifecycleOwner.getLifecycle()));
 
+        // Monet enable/disable section.
+        sectionControllers.add(new MonetModeSectionController(activity,
+                lifecycleOwner.getLifecycle()));
+
         // Themed app icon section.
         sectionControllers.add(new ThemedIconSectionController(
                 ThemedIconSwitchProvider.getInstance(activity), workspaceViewModel,
diff --git a/src/com/android/customization/picker/monet/MonetModeSectionView.java b/src/com/android/customization/picker/monet/MonetModeSectionView.java
new file mode 100644
index 0000000..90d6e43
--- /dev/null
+++ b/src/com/android/customization/picker/monet/MonetModeSectionView.java
@@ -0,0 +1,53 @@
+package com.android.customization.picker.monet;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Switch;
+
+import androidx.annotation.Nullable;
+
+import com.android.customization.model.monet.MonetModeSectionController;
+import com.android.wallpaper.R;
+import com.android.wallpaper.picker.SectionView;
+
+public final class MonetModeSectionView extends SectionView {
+
+    private boolean mIsMonetEnabled;
+    private Switch switchView;
+
+    public MonetModeSectionView(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        setTitle(context.getString(R.string.mode_title));
+        mIsMonetEnabled = MonetModeSectionController.isMonetEnabled(context);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        switchView = findViewById(R.id.monet_mode_toggle);
+        switchView.setChecked(mIsMonetEnabled);
+        switchView.setOnCheckedChangeListener((buttonView, isChecked) ->
+                switchView.setChecked(mIsMonetEnabled)
+        );
+        setOnClickListener(view -> modeToggleClicked());
+    }
+
+    private void modeToggleClicked() {
+        mIsMonetEnabled = !mIsMonetEnabled;
+        viewActivated(mIsMonetEnabled);
+    }
+
+    private void viewActivated(boolean isChecked) {
+        if (mSectionViewListener != null) {
+            mSectionViewListener.onViewActivated(getContext(), isChecked);
+        }
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        final int numOfChildViews = getChildCount();
+        for (int i = 0; i < numOfChildViews; i++) {
+            getChildAt(i).setEnabled(enabled);
+        }
+    }
+}
