Merge "Set up compose (2/3)" into main
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
index 52521d6..88e3f80 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
@@ -31,6 +31,8 @@
 import com.android.customization.picker.color.shared.model.ColorOptionModel
 import com.android.customization.picker.color.shared.model.ColorType
 import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
+import com.android.systemui.monet.ColorScheme
+import com.android.systemui.monet.Style
 import com.android.themepicker.R
 import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
 import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
@@ -140,6 +142,16 @@
                 }
 
                 colorMap.values.forEachIndexed { index, colorModel ->
+                    // Adjust clock colors for light theme for better color contrast
+                    val lightThemeColor =
+                        ColorScheme(
+                                /* seed= */ colorModel.color,
+                                /* darkTheme= */ false,
+                                /* style= */ if (colorModel.colorId == "GRAY") Style.MONOCHROMATIC
+                                else Style.RAINBOW,
+                            )
+                            .accent1
+                            .getAtTone(450f)
                     val isSelectedFlow =
                         selectedColorId
                             .map { colorMap.keys.indexOf(it) == index }
@@ -150,10 +162,10 @@
                             key = MutableStateFlow(colorModel.colorId) as StateFlow<String>,
                             payload =
                                 ColorOptionIconViewModel(
-                                    lightThemeColor0 = colorModel.color,
-                                    lightThemeColor1 = colorModel.color,
-                                    lightThemeColor2 = colorModel.color,
-                                    lightThemeColor3 = colorModel.color,
+                                    lightThemeColor0 = lightThemeColor,
+                                    lightThemeColor1 = lightThemeColor,
+                                    lightThemeColor2 = lightThemeColor,
+                                    lightThemeColor3 = lightThemeColor,
                                     darkThemeColor0 = colorModel.color,
                                     darkThemeColor1 = colorModel.color,
                                     darkThemeColor2 = colorModel.color,
diff --git a/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl2.kt b/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl2.kt
index 5e90b41..96f9368 100644
--- a/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl2.kt
+++ b/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl2.kt
@@ -16,14 +16,18 @@
  */
 package com.android.customization.picker.color.data.repository
 
+import android.app.WallpaperColors
+import android.app.WallpaperManager
+import android.os.Handler
+import android.os.Looper
 import android.util.Log
 import com.android.customization.model.CustomizationManager
 import com.android.customization.model.color.ColorCustomizationManager
 import com.android.customization.model.color.ColorOption
 import com.android.customization.model.color.ColorOptionImpl
 import com.android.customization.picker.color.shared.model.ColorType
-import com.android.wallpaper.picker.customization.data.repository.WallpaperColorsRepository
-import com.android.wallpaper.picker.customization.shared.model.WallpaperColorsModel
+import com.android.wallpaper.model.Screen
+import com.android.wallpaper.picker.customization.data.content.WallpaperClient
 import com.android.wallpaper.picker.di.modules.BackgroundDispatcher
 import javax.inject.Inject
 import javax.inject.Singleton
@@ -31,11 +35,11 @@
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.callbackFlow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.shareIn
 import kotlinx.coroutines.suspendCancellableCoroutine
 
 @Singleton
@@ -43,41 +47,41 @@
 @Inject
 constructor(
     @BackgroundDispatcher private val scope: CoroutineScope,
-    wallpaperColorsRepository: WallpaperColorsRepository,
     private val colorManager: ColorCustomizationManager,
+    client: WallpaperClient,
 ) : ColorPickerRepository2 {
 
-    private val homeWallpaperColors: StateFlow<WallpaperColorsModel?> =
-        wallpaperColorsRepository.homeWallpaperColors
-    private val lockWallpaperColors: StateFlow<WallpaperColorsModel?> =
-        wallpaperColorsRepository.lockWallpaperColors
+    private val wallpaperColorsCallback: Flow<Pair<Screen, WallpaperColors?>> =
+        callbackFlow {
+                trySend(Pair(Screen.HOME_SCREEN, client.getWallpaperColors(Screen.HOME_SCREEN)))
+                trySend(Pair(Screen.LOCK_SCREEN, client.getWallpaperColors(Screen.LOCK_SCREEN)))
+                val listener = { colors: WallpaperColors?, which: Int ->
+                    if (which and WallpaperManager.FLAG_SYSTEM != 0) {
+                        trySend(Pair(Screen.HOME_SCREEN, colors))
+                    }
+                    if (which and WallpaperManager.FLAG_LOCK != 0) {
+                        trySend(Pair(Screen.LOCK_SCREEN, colors))
+                    }
+                }
+                client.addOnColorsChangedListener(listener, Handler(Looper.getMainLooper()))
+                awaitClose { client.removeOnColorsChangedListener(listener) }
+            }
+            // Make this a shared flow to make sure only one listener is added.
+            .shareIn(scope = scope, started = SharingStarted.WhileSubscribed(), replay = 1)
+    private val homeWallpaperColors: Flow<WallpaperColors?> =
+        wallpaperColorsCallback
+            .filter { (screen, _) -> screen == Screen.HOME_SCREEN }
+            .map { (_, colors) -> colors }
+    private val lockWallpaperColors: Flow<WallpaperColors?> =
+        wallpaperColorsCallback
+            .filter { (screen, _) -> screen == Screen.LOCK_SCREEN }
+            .map { (_, colors) -> colors }
 
     override val colorOptions: Flow<Map<ColorType, List<ColorOption>>> =
-        combine(homeWallpaperColors, lockWallpaperColors) { homeColors, lockColors ->
-                homeColors to lockColors
-            }
+        combine(homeWallpaperColors, lockWallpaperColors, ::Pair)
             .map { (homeColors, lockColors) ->
                 suspendCancellableCoroutine { continuation ->
-                    if (
-                        homeColors is WallpaperColorsModel.Loading ||
-                            lockColors is WallpaperColorsModel.Loading
-                    ) {
-                        continuation.resumeWith(
-                            Result.success(
-                                mapOf(
-                                    ColorType.WALLPAPER_COLOR to listOf(),
-                                    ColorType.PRESET_COLOR to listOf(),
-                                )
-                            )
-                        )
-                        return@suspendCancellableCoroutine
-                    }
-                    val homeColorsLoaded = homeColors as WallpaperColorsModel.Loaded
-                    val lockColorsLoaded = lockColors as WallpaperColorsModel.Loaded
-                    colorManager.setWallpaperColors(
-                        homeColorsLoaded.colors,
-                        lockColorsLoaded.colors,
-                    )
+                    colorManager.setWallpaperColors(homeColors, lockColors)
                     colorManager.fetchOptions(
                         object : CustomizationManager.OptionsFetchedListener<ColorOption> {
                             override fun onOptionsLoaded(options: MutableList<ColorOption>?) {
@@ -114,12 +118,17 @@
                     )
                 }
             }
+            .shareIn(scope = scope, started = SharingStarted.WhileSubscribed(), replay = 1)
 
-    private val settingsChanged = callbackFlow {
-        trySend(Unit)
-        colorManager.setListener { trySend(Unit) }
-        awaitClose { colorManager.setListener(null) }
-    }
+    private val settingsChanged =
+        callbackFlow {
+                trySend(Unit)
+                colorManager.setListener { trySend(Unit) }
+                awaitClose { colorManager.setListener(null) }
+            }
+            // Make this a shared flow to prevent colorManager.setListener from being called
+            // every time this flow is collected, since colorManager is a singleton.
+            .shareIn(scope = scope, started = SharingStarted.WhileSubscribed(), replay = 1)
 
     override val selectedColorOption =
         combine(colorOptions, settingsChanged) { options, _ ->
@@ -132,7 +141,7 @@
                 }
                 return@combine null
             }
-            .stateIn(scope = scope, started = SharingStarted.WhileSubscribed(), initialValue = null)
+            .shareIn(scope = scope, started = SharingStarted.WhileSubscribed(), replay = 1)
 
     override suspend fun select(colorOption: ColorOption) {
         suspendCancellableCoroutine { continuation ->
@@ -155,6 +164,6 @@
     }
 
     companion object {
-        private const val TAG = "ColorPickerRepositoryImpl"
+        private const val TAG = "ColorPickerRepositoryImpl2"
     }
 }
diff --git a/src/com/android/customization/picker/color/ui/binder/ColorSectionViewBinder.kt b/src/com/android/customization/picker/color/ui/binder/ColorSectionViewBinder.kt
index 88b7d39..2558d8f 100644
--- a/src/com/android/customization/picker/color/ui/binder/ColorSectionViewBinder.kt
+++ b/src/com/android/customization/picker/color/ui/binder/ColorSectionViewBinder.kt
@@ -129,15 +129,14 @@
                 )
             }
             val optionSelectedView = itemView.requireViewById<ImageView>(R.id.option_selected)
-            val colorView: View = itemView.requireViewById(R.id.option_tile)
-            colorView.isClickable = true
-            colorView.isFocusable = true
+            itemView.isClickable = true
+            itemView.isFocusable = true
 
             lifecycleOwner.lifecycleScope.launch {
                 launch {
                     item.isSelected.collect { isSelected ->
                         optionSelectedView.isVisible = isSelected
-                        colorView.isSelected = isSelected
+                        itemView.isSelected = isSelected
                     }
                 }
                 launch {
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockOptionItemViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockOptionItemViewModel.kt
deleted file mode 100644
index cd223a0..0000000
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockOptionItemViewModel.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2024 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.viewmodel
-
-import android.graphics.drawable.Drawable
-
-data class ClockOptionItemViewModel(
-    val clockId: String,
-    val isSelected: Boolean,
-    val contentDescription: String,
-    val thumbnail: Drawable,
-)
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockSizeOptionViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockSizeOptionViewModel.kt
deleted file mode 100644
index de2c54a..0000000
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockSizeOptionViewModel.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2024 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.viewmodel
-
-import com.android.customization.picker.clock.shared.ClockSize
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
-
-data class ClockSizeOptionViewModel(
-    val size: ClockSize,
-    val isSelected: StateFlow<Boolean>,
-    val onClicked: Flow<(() -> Unit)?>,
-)