Add a toggle for Monet themeing, credit GrapheneOS

Signed-off-by: Tad <tad@spotco.us>
This commit is contained in:
Tad 2022-07-06 21:13:40 -04:00
parent 2c27a88a24
commit f07f288e3a
4 changed files with 515 additions and 4 deletions

View File

@ -2,10 +2,6 @@ RQ3A.211001.001.2021100606
QQ3A.200805.001.2020.09.11.14
PQ3B.190801.002.2019.08.25.15
monet toggle
12 https://github.com/GrapheneOS/platform_frameworks_base/commit/e77f8f544c8c6e826d8497be6ebbc69d72d2f1a5
12 https://github.com/GrapheneOS/platform_packages_apps_ThemePicker/commit/a287544b550887ea646277d78cde80b19e1ca9af
https time
12 https://github.com/GrapheneOS/platform_frameworks_base/commit/1d4e3f495b7b544f6314f04243e9d47b3f8e7102
12 https://github.com/GrapheneOS/platform_frameworks_base/commit/2c04a077ec9f3ac6857885199f49f4845b70ec2e
@ -65,6 +61,10 @@ nojit
9 https://github.com/GrapheneOS/platform_build/commit/5b9927197e63593b9220d1a9280021252ef205e9
9 https://github.com/GrapheneOS/platform_build/commit/e36c7aefaa78a1ed5b94c7f51d29277008eea232
[implemented] monet toggle
12 https://github.com/GrapheneOS/platform_frameworks_base/commit/e77f8f544c8c6e826d8497be6ebbc69d72d2f1a5
12 https://github.com/GrapheneOS/platform_packages_apps_ThemePicker/commit/a287544b550887ea646277d78cde80b19e1ca9af
[implemented] user logout
12 https://github.com/GrapheneOS/platform_frameworks_base/commit/93838b55c9b6460249a22be42f04026d8780fefc

View File

@ -0,0 +1,226 @@
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 | 78 +++++++++++--------
2 files changed, 66 insertions(+), 33 deletions(-)
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1c5650b540f0..c1a6f740f780 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6341,6 +6341,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 482a70defb3f..7967c645a7b5 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -1,4 +1,4 @@
-/*
+f/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -111,7 +111,6 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
private final SecureSettings mSecureSettings;
private final Executor mMainExecutor;
private final Handler mBgHandler;
- private final boolean mIsMonetEnabled;
private final UserTracker mUserTracker;
private final ConfigurationController mConfigurationController;
private final DeviceProvisionedController mDeviceProvisionedController;
@@ -250,7 +249,11 @@ public class ThemeOverlayController extends SystemUI 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);
}
@@ -347,6 +350,15 @@ public class ThemeOverlayController extends SystemUI 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,
@@ -358,7 +370,6 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
configurationController) {
super(context);
- mIsMonetEnabled = featureFlags.isMonetEnabled();
mConfigurationController = configurationController;
mDeviceProvisionedController = deviceProvisionedController;
mBroadcastDispatcher = broadcastDispatcher;
@@ -408,10 +419,6 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
},
UserHandle.USER_ALL);
- if (!mIsMonetEnabled) {
- return;
- }
-
mUserTracker.addCallback(mUserTrackerCallback, mMainExecutor);
mConfigurationController.addCallback(mConfigurationListener);
@@ -419,8 +426,8 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
// 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);
@@ -446,7 +453,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
@Override
public void onFinishedGoingToSleep() {
final int userId = mUserTracker.getUserId();
- final WallpaperColors colors = mDeferredWallpaperColors.get(userId);
+ final WallpaperColors colors =isMonetEnabled(mUserTracker.getUserId())? mDeferredWallpaperColors.get(userId) : null;
if (colors != null) {
int flags = mDeferredWallpaperColorsFlags.get(userId);
@@ -457,10 +464,27 @@ public class ThemeOverlayController extends SystemUI 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;
final int accentCandidate;
if (currentColors == null) {
@@ -479,14 +503,12 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
mMainWallpaperColor = mainColor;
mWallpaperAccentColor = accentCandidate;
- if (mIsMonetEnabled) {
- mSecondaryOverlay = getOverlay(mWallpaperAccentColor, ACCENT);
- mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL);
- mNeedsOverlayCreation = true;
- if (DEBUG) {
- Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
- + " neutral: " + mNeutralOverlay);
- }
+ mSecondaryOverlay = getOverlay(mWallpaperAccentColor, ACCENT);
+ mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL);
+ mNeedsOverlayCreation = true;
+ if (DEBUG) {
+ Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
+ + " neutral: " + mNeutralOverlay);
}
updateThemeOverlays();
@@ -563,7 +585,7 @@ public class ThemeOverlayController extends SystemUI 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("#")) {
@@ -577,20 +599,11 @@ public class ThemeOverlayController extends SystemUI 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);
- } catch (NumberFormatException e) {
- // This is a package name. All good, let's continue
- }
}
// Same for accent color.
OverlayIdentifier accentPalette = categoryToPackage.get(OVERLAY_CATEGORY_ACCENT_COLOR);
- if (mIsMonetEnabled && accentPalette != null && accentPalette.getPackageName() != null) {
+ if (accentPalette != null && accentPalette.getPackageName() != null) {
try {
String colorString = accentPalette.getPackageName().toLowerCase();
if (!colorString.startsWith("#")) {
@@ -604,7 +617,7 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
// Color.parseColor doesn't catch any exceptions from the calls it makes
Log.w(TAG, "Invalid color definition: " + accentPalette.getPackageName(), e);
}
- } else if (!mIsMonetEnabled && accentPalette != null) {
+ } else if (accentPalette != null) {
try {
Integer.parseInt(accentPalette.getPackageName().toLowerCase(), 16);
categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
@@ -654,7 +667,6 @@ public class ThemeOverlayController extends SystemUI implements Dumpable {
pw.println("mWallpaperAccentColor=" + Integer.toHexString(mWallpaperAccentColor));
pw.println("mSecondaryOverlay=" + mSecondaryOverlay);
pw.println("mNeutralOverlay=" + mNeutralOverlay);
- pw.println("mIsMonetEnabled=" + mIsMonetEnabled);
pw.println("mColorScheme=" + mColorScheme);
pw.println("mNeedsOverlayCreation=" + mNeedsOverlayCreation);
pw.println("mAcceptColorEvents=" + mAcceptColorEvents);

View File

@ -0,0 +1,279 @@
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..214d6b1
--- /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_DISABLED,
+ 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);
+ }
+ }
+}

View File

@ -165,6 +165,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0022-Ignore_StatementService_AN
applyPatch "$DOS_PATCHES/android_frameworks_base/326692.patch"; #Skip screen on animation when wake and unlock via biometrics (jesec)
applyPatch "$DOS_PATCHES/android_frameworks_base/0023-Skip_Screen_Animation.patch"; #SystemUI: Skip screen-on animation in all scenarios (kdrag0n)
applyPatch "$DOS_PATCHES/android_frameworks_base/0024-Burnin_Protection.patch"; #SystemUI: add burnIn protection (arter97)
applyPatch "$DOS_PATCHES/android_frameworks_base/0025-Monet_Toggle.patch"; #Make monet based theming user configurable (GrapheneOS)
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
hardenLocationConf services/core/java/com/android/server/location/gnss/gps_debug.conf; #Harden the default GPS config
changeDefaultDNS; #Change the default DNS servers
@ -283,6 +284,11 @@ if enterAndClear "packages/apps/SetupWizard"; then
applyPatch "$DOS_PATCHES/android_packages_apps_SetupWizard/0001-Remove_Analytics.patch"; #Remove analytics (DivestOS)
fi;
if enterAndClear "packages/apps/ThemePicker"; then
applyPatch "$DOS_PATCHES/android_packages_apps_ThemePicker/0001-Monet_Toggle.patch"; #Add a UI for enabling Material You (GrapheneOS)
fi;
if enterAndClear "packages/apps/Trebuchet"; then
cp $DOS_BUILD_BASE/vendor/divested/overlay/common/packages/apps/Trebuchet/res/xml/default_workspace_*.xml res/xml/; #XXX: Likely no longer needed
fi;