Set up compose (2/3)
Set up gradle and soong build config to enable using Compose in
customization picker. Also add a flag for the compose refactor and use
it to gate a basic WIP composable for the color floating sheet.
Flag: com.android.wallpaper.compose_refactor_flag
Bug: 391918848
Bug: 391927276
Test: manually verified by building with gradle and soong
Test: manually verified by flipping flag and checking color picker
Change-Id: Ie7038116cc129b2578d7f478faa9f0c9f6a4dd19
diff --git a/Android.bp b/Android.bp
index 58e6413..5efee51 100644
--- a/Android.bp
+++ b/Android.bp
@@ -74,6 +74,17 @@
"androidx.recyclerview_recyclerview",
"SystemUICustomizationLib",
"hilt_android",
+ // Compose
+ "PlatformComposeCore",
+ "androidx.activity_activity-compose",
+ "androidx.compose.foundation_foundation",
+ "androidx.compose.foundation_foundation-layout",
+ "androidx.compose.material3_material3",
+ "androidx.compose.runtime_runtime",
+ "androidx.compose.ui_ui",
+ "androidx.compose.ui_ui-tooling",
+ "androidx.lifecycle_lifecycle-runtime-compose",
+ "androidx.lifecycle_lifecycle-viewmodel-compose",
],
srcs: [
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
index 9fc2a0a..307c893 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
@@ -43,6 +43,7 @@
import com.android.systemui.plugins.clocks.ClockPreviewConfig
import com.android.systemui.shared.Flags
import com.android.themepicker.R
+import com.android.wallpaper.config.BaseFlags
import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerHomeCustomizationOption
import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption
import com.android.wallpaper.customization.ui.viewmodel.ThemePickerCustomizationOptionsViewModel
@@ -100,6 +101,8 @@
navigateToPreviewScreen,
)
+ val isComposeRefactorEnabled = BaseFlags.get().isComposeRefactorEnabled()
+
val optionsViewModel =
viewModel.customizationOptionsViewModel as ThemePickerCustomizationOptionsViewModel
@@ -375,16 +378,18 @@
)
}
- customizationOptionFloatingSheetViewMap
- ?.get(ThemePickerHomeCustomizationOption.COLORS)
- ?.let {
- ColorsFloatingSheetBinder.bind(
- it,
- optionsViewModel,
- colorUpdateViewModel,
- lifecycleOwner,
- )
- }
+ if (!isComposeRefactorEnabled) {
+ customizationOptionFloatingSheetViewMap
+ ?.get(ThemePickerHomeCustomizationOption.COLORS)
+ ?.let {
+ ColorsFloatingSheetBinder.bind(
+ it,
+ optionsViewModel,
+ colorUpdateViewModel,
+ lifecycleOwner,
+ )
+ }
+ }
customizationOptionFloatingSheetViewMap
?.get(ThemePickerHomeCustomizationOption.APP_SHAPE_GRID)
diff --git a/src/com/android/wallpaper/customization/ui/compose/ColorFloatingSheet.kt b/src/com/android/wallpaper/customization/ui/compose/ColorFloatingSheet.kt
new file mode 100644
index 0000000..c81811d
--- /dev/null
+++ b/src/com/android/wallpaper/customization/ui/compose/ColorFloatingSheet.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wallpaper.customization.ui.compose
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.android.compose.theme.PlatformTheme
+import com.android.themepicker.R
+
+@Preview
+@Composable
+fun ColorFloatingSheet() {
+ // TODO (b/391927276): figure out how to animate color scheme changes
+ PlatformTheme {
+ val colorScheme = MaterialTheme.colorScheme
+ // TODO (b/391927276): replace placeholder colors with actual values
+ val colorsList = remember {
+ mutableStateListOf(
+ Color.Red,
+ Color.Green,
+ Color.Blue,
+ Color.Cyan,
+ Color.Magenta,
+ Color.Yellow,
+ Color.Black,
+ )
+ }
+ Box(
+ modifier =
+ Modifier.fillMaxWidth()
+ .padding(horizontal = 16.dp)
+ .clip(shape = RoundedCornerShape(28.dp))
+ .drawBehind { drawRect(colorScheme.surfaceBright) }
+ ) {
+ Column(modifier = Modifier.padding(vertical = 20.dp)) {
+ Text(
+ modifier = Modifier.padding(horizontal = 20.dp),
+ text = stringResource(R.string.wallpaper_color_subheader),
+ color = colorScheme.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ LazyRow(
+ contentPadding = PaddingValues(horizontal = 20.dp),
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
+ ) {
+ items(colorsList) { color ->
+ Box(
+ modifier =
+ Modifier.size(
+ dimensionResource(R.dimen.floating_sheet_color_option_size)
+ )
+ ) {
+ ColorOptionIcon(color)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+@Composable
+fun ColorOptionIcon(color: Color) {
+ Box(modifier = Modifier.clip(CircleShape).fillMaxSize().drawBehind { drawRect(color) })
+}
diff --git a/src/com/android/wallpaper/customization/ui/util/ThemePickerCustomizationOptionUtil.kt b/src/com/android/wallpaper/customization/ui/util/ThemePickerCustomizationOptionUtil.kt
index ec38af5..922384a 100644
--- a/src/com/android/wallpaper/customization/ui/util/ThemePickerCustomizationOptionUtil.kt
+++ b/src/com/android/wallpaper/customization/ui/util/ThemePickerCustomizationOptionUtil.kt
@@ -16,26 +16,33 @@
package com.android.wallpaper.customization.ui.util
+import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
+import androidx.compose.ui.platform.ComposeView
import com.android.customization.picker.mode.shared.util.DarkModeLifecycleUtil
import com.android.themepicker.R
+import com.android.wallpaper.config.BaseFlags
+import com.android.wallpaper.customization.ui.compose.ColorFloatingSheet
import com.android.wallpaper.model.Screen
import com.android.wallpaper.model.Screen.HOME_SCREEN
import com.android.wallpaper.model.Screen.LOCK_SCREEN
import com.android.wallpaper.picker.customization.ui.util.CustomizationOptionUtil
import com.android.wallpaper.picker.customization.ui.util.DefaultCustomizationOptionUtil
+import dagger.hilt.android.qualifiers.ActivityContext
import dagger.hilt.android.scopes.ActivityScoped
import javax.inject.Inject
@ActivityScoped
class ThemePickerCustomizationOptionUtil
@Inject
-constructor(private val defaultCustomizationOptionUtil: DefaultCustomizationOptionUtil) :
- CustomizationOptionUtil {
+constructor(
+ private val defaultCustomizationOptionUtil: DefaultCustomizationOptionUtil,
+ @ActivityContext private val context: Context,
+) : CustomizationOptionUtil {
// Instantiate DarkModeLifecycleUtil for it to observe lifecycle and update DarkModeRepository
@Inject lateinit var darkModeLifecycleUtil: DarkModeLifecycleUtil
@@ -143,6 +150,7 @@
): Map<CustomizationOptionUtil.CustomizationOption, View> {
val map =
defaultCustomizationOptionUtil.initFloatingSheet(bottomSheetContainer, layoutInflater)
+ val isComposeRefactorEnabled = BaseFlags.get().isComposeRefactorEnabled()
return buildMap {
putAll(map)
put(
@@ -165,11 +173,15 @@
)
put(
ThemePickerHomeCustomizationOption.COLORS,
- inflateFloatingSheet(
- ThemePickerHomeCustomizationOption.COLORS,
- bottomSheetContainer,
- layoutInflater,
- )
+ if (isComposeRefactorEnabled) {
+ ComposeView(context).apply { setContent { ColorFloatingSheet() } }
+ } else {
+ inflateFloatingSheet(
+ ThemePickerHomeCustomizationOption.COLORS,
+ bottomSheetContainer,
+ layoutInflater,
+ )
+ }
.also { bottomSheetContainer.addView(it) },
)
put(