New Monochrome Color Preview
To allow Monochrome tile to be displayed similar to a wallpaper color,
code was refactored to use a singular color option class for both
wallpaper and basic colors going forward to allow more flexibility. The
ColorOptionImpl class unifies ColorBundle and ColorSeedOption for
revamped UI and beyond, since the two ColorOption types differ mainly
in their preview. This refactor will also move toward cleaner
architecture by removing ColorOption's ability to bind views in the
revamped UI and beyond, keeping it soley as a model.
Bug: 275625332
Bug: 270187739
Test: Manually tested in revamped UI and original UI
Test: Adjusted fake repository for new ColorOptionImpl model, interactor
and view-model unit tests still pass with the same logic
Change-Id: I5d61cecd7e17c2327a3b0eed52c5d7d57769ac62
diff --git a/src/com/android/customization/model/color/ColorOptionImpl.kt b/src/com/android/customization/model/color/ColorOptionImpl.kt
new file mode 100644
index 0000000..70aaa92
--- /dev/null
+++ b/src/com/android/customization/model/color/ColorOptionImpl.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2023 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.customization.model.color
+
+import android.content.Context
+import android.view.View
+import androidx.annotation.ColorInt
+import com.android.customization.model.color.ColorOptionsProvider.ColorSource
+import com.android.customization.picker.color.shared.model.ColorType
+import com.android.systemui.monet.Style
+import com.android.wallpaper.R
+
+/**
+ * Represents a color option in the revamped UI, it can be used for both wallpaper and preset colors
+ */
+class ColorOptionImpl(
+ title: String?,
+ overlayPackages: Map<String, String?>,
+ isDefault: Boolean,
+ private val source: String?,
+ style: Style,
+ index: Int,
+ private val previewInfo: PreviewInfo,
+ val type: ColorType,
+) : ColorOption(title, overlayPackages, isDefault, style, index) {
+
+ class PreviewInfo(
+ @ColorInt val lightColors: IntArray,
+ @ColorInt val darkColors: IntArray,
+ ) : ColorOption.PreviewInfo {
+ @ColorInt
+ fun resolveColors(darkTheme: Boolean): IntArray {
+ return if (darkTheme) darkColors else lightColors
+ }
+ }
+
+ override fun bindThumbnailTile(view: View?) {
+ // Do nothing. This function will no longer be used in the Revamped UI
+ }
+
+ override fun getLayoutResId(): Int {
+ return R.layout.color_option
+ }
+
+ override fun getPreviewInfo(): PreviewInfo {
+ return previewInfo
+ }
+
+ override fun getContentDescription(context: Context): CharSequence? {
+ if (type == ColorType.WALLPAPER_COLOR) {
+ return context.getString(R.string.wallpaper_color_title)
+ }
+ return super.getContentDescription(context)
+ }
+
+ override fun getSource(): String? {
+ return source
+ }
+
+ class Builder {
+ var title: String? = null
+
+ @ColorInt var lightColors: IntArray = intArrayOf()
+
+ @ColorInt var darkColors: IntArray = intArrayOf()
+
+ @ColorSource var source: String? = null
+ var isDefault = false
+ var style = Style.TONAL_SPOT
+ var index = 0
+ var packages: MutableMap<String, String?> = HashMap()
+ var type = ColorType.WALLPAPER_COLOR
+
+ fun build(): ColorOptionImpl {
+ return ColorOptionImpl(
+ title,
+ packages,
+ isDefault,
+ source,
+ style,
+ index,
+ createPreviewInfo(),
+ type
+ )
+ }
+
+ private fun createPreviewInfo(): PreviewInfo {
+ return PreviewInfo(lightColors, darkColors)
+ }
+
+ fun addOverlayPackage(category: String?, packageName: String?): ColorOptionImpl.Builder {
+ category?.let { packages[category] = packageName }
+ return this
+ }
+ }
+}
diff --git a/src/com/android/customization/model/color/ColorProvider.kt b/src/com/android/customization/model/color/ColorProvider.kt
index 639a886..6ce6f0b 100644
--- a/src/com/android/customization/model/color/ColorProvider.kt
+++ b/src/com/android/customization/model/color/ColorProvider.kt
@@ -34,11 +34,11 @@
import com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_HOME
import com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_LOCK
import com.android.customization.model.color.ColorUtils.toColorString
+import com.android.customization.picker.color.shared.model.ColorType
import com.android.systemui.monet.ColorScheme
import com.android.systemui.monet.Style
import com.android.wallpaper.compat.WallpaperManagerCompat
import com.android.wallpaper.module.InjectorProvider
-import java.util.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
@@ -101,7 +101,7 @@
scope.launch {
try {
if (colorBundles == null || reload) {
- loadPreset()
+ loadPreset(shouldUseRevampedUi)
}
if (wallpaperColorsChanged || reload) {
loadSeedColors(
@@ -176,7 +176,16 @@
)
}
- bundles.addAll(colorBundles?.filterNot { it is ColorSeedOption } ?: emptyList())
+ if (shouldUseRevampedUi) {
+ bundles.addAll(
+ colorBundles?.filterNot {
+ (it as ColorOptionImpl).type == ColorType.WALLPAPER_COLOR
+ }
+ ?: emptyList()
+ )
+ } else {
+ bundles.addAll(colorBundles?.filterNot { it is ColorSeedOption } ?: emptyList())
+ }
colorBundles = bundles
}
@@ -206,40 +215,51 @@
) {
// TODO(b/202145216): Measure time cost in the loop.
for (style in styleList) {
- val builder = ColorSeedOption.Builder()
val lightColorScheme = ColorScheme(colorInt, /* darkTheme= */ false, style)
val darkColorScheme = ColorScheme(colorInt, /* darkTheme= */ true, style)
- builder
- .setLightColors(
- if (shouldUseRevampedUi) lightColorScheme.getRevampedUILightColorPreview()
- else lightColorScheme.getLightColorPreview()
- )
- .setDarkColors(
- if (shouldUseRevampedUi) darkColorScheme.getRevampedUIDarkColorPreview()
- else darkColorScheme.getDarkColorPreview()
- )
- .addOverlayPackage(
+ if (shouldUseRevampedUi) {
+ val builder = ColorOptionImpl.Builder()
+ builder.lightColors = lightColorScheme.getRevampedUILightColorPreview()
+ builder.darkColors = darkColorScheme.getRevampedUIDarkColorPreview()
+ builder.addOverlayPackage(
OVERLAY_CATEGORY_SYSTEM_PALETTE,
if (isDefault) "" else toColorString(colorInt)
)
- .addOverlayPackage(
- OVERLAY_CATEGORY_COLOR,
- if (isDefault) "" else toColorString(colorInt)
- )
- .setSource(source)
- .setStyle(style)
+ builder.source = source
+ builder.style = style
// Color option index value starts from 1.
- .setIndex(i + 1)
+ builder.index = i + 1
+ builder.isDefault = isDefault
+ builder.type = ColorType.WALLPAPER_COLOR
+ bundles.add(builder.build())
+ } else {
+ val builder = ColorSeedOption.Builder()
+ builder
+ .setLightColors(lightColorScheme.getLightColorPreview())
+ .setDarkColors(darkColorScheme.getDarkColorPreview())
+ .addOverlayPackage(
+ OVERLAY_CATEGORY_SYSTEM_PALETTE,
+ if (isDefault) "" else toColorString(colorInt)
+ )
+ .addOverlayPackage(
+ OVERLAY_CATEGORY_COLOR,
+ if (isDefault) "" else toColorString(colorInt)
+ )
+ .setSource(source)
+ .setStyle(style)
+ // Color option index value starts from 1.
+ .setIndex(i + 1)
- if (isDefault) builder.asDefault()
+ if (isDefault) builder.asDefault()
- bundles.add(builder.build())
+ bundles.add(builder.build())
+ }
}
}
/**
* Returns the colors for the light theme version of the preview of a ColorScheme based on this
- * order: |-------| | 0 | 1 | |---+---| | 2 | 3 | |-------|
+ * order: top left, top right, bottom left, bottom right
*/
@ColorInt
private fun ColorScheme.getLightColorPreview(): IntArray {
@@ -263,13 +283,17 @@
/**
* Returns the color for the dark theme version of the preview of a ColorScheme based on this
- * order: |-------| | 0 | 1 | |---+---| | 2 | 3 | |-------|
+ * order: top left, top right, bottom left, bottom right
*/
@ColorInt
private fun ColorScheme.getDarkColorPreview(): IntArray {
return getLightColorPreview()
}
+ /**
+ * Returns the light theme version of the Revamped UI preview of a ColorScheme based on this
+ * order: top left, top right, bottom left, bottom right
+ */
@ColorInt
private fun ColorScheme.getRevampedUILightColorPreview(): IntArray {
return intArrayOf(
@@ -281,8 +305,8 @@
}
/**
- * Returns the color for the dark theme version of the preview of a ColorScheme based on this
- * order: |-------| | 0 | 1 | |---+---| | 2 | 3 | |-------|
+ * Returns the dark theme version of the Revamped UI preview of a ColorScheme based on this
+ * order: top left, top right, bottom left, bottom right
*/
@ColorInt
private fun ColorScheme.getRevampedUIDarkColorPreview(): IntArray {
@@ -294,6 +318,25 @@
)
}
+ /**
+ * Returns the Revamped UI preview of a preset ColorScheme based on this order: top left, top
+ * right, bottom left, bottom right
+ */
+ private fun ColorScheme.getRevampedUIPresetColorPreview(seed: Int): IntArray {
+ val colors =
+ when (this.style) {
+ Style.FRUIT_SALAD -> intArrayOf(seed, this.accent1.s100)
+ Style.TONAL_SPOT -> intArrayOf(this.accentColor, this.accentColor)
+ else -> intArrayOf(this.accent1.s100, this.accent1.s100)
+ }
+ return intArrayOf(
+ colors[0],
+ colors[1],
+ colors[0],
+ colors[1],
+ )
+ }
+
private fun ColorScheme.getPresetColorPreview(seed: Int): IntArray {
return when (this.style) {
Style.FRUIT_SALAD -> intArrayOf(seed, this.accent1.s100)
@@ -307,7 +350,7 @@
}
}
- private suspend fun loadPreset() =
+ private suspend fun loadPreset(shouldUseRevampedUi: Boolean) =
withContext(Dispatchers.IO) {
val extractor = ColorBundlePreviewExtractor(mContext)
val bundles: MutableList<ColorOption> = ArrayList()
@@ -317,48 +360,117 @@
var index = 1
val maxPresetColors = if (themeStyleEnabled) bundleNames.size else MAX_PRESET_COLORS
for (bundleName in bundleNames.take(maxPresetColors)) {
- val builder = ColorBundle.Builder()
- builder.title = getItemStringFromStub(COLOR_BUNDLE_NAME_PREFIX, bundleName)
- builder.setIndex(index)
- val colorFromStub = getItemColorFromStub(COLOR_BUNDLE_MAIN_COLOR_PREFIX, bundleName)
- extractor.addPrimaryColor(builder, colorFromStub)
- extractor.addSecondaryColor(builder, colorFromStub)
- if (themeStyleEnabled) {
- val styleName =
- try {
- getItemStringFromStub(COLOR_BUNDLE_STYLE_PREFIX, bundleName)
- } catch (e: Resources.NotFoundException) {
- null
+ if (shouldUseRevampedUi) {
+ val builder = ColorOptionImpl.Builder()
+ builder.title = getItemStringFromStub(COLOR_BUNDLE_NAME_PREFIX, bundleName)
+ builder.index = index
+ builder.source = ColorOptionsProvider.COLOR_SOURCE_PRESET
+ builder.type = ColorType.PRESET_COLOR
+ val colorFromStub =
+ getItemColorFromStub(COLOR_BUNDLE_MAIN_COLOR_PREFIX, bundleName)
+ var darkColorScheme = ColorScheme(colorFromStub, /* darkTheme= */ true)
+ var lightColorScheme = ColorScheme(colorFromStub, /* darkTheme= */ false)
+ val lightColor = lightColorScheme.accentColor
+ val darkColor = darkColorScheme.accentColor
+ var lightColors = intArrayOf(lightColor, lightColor, lightColor, lightColor)
+ var darkColors = intArrayOf(darkColor, darkColor, darkColor, darkColor)
+ builder.addOverlayPackage(OVERLAY_CATEGORY_COLOR, toColorString(colorFromStub))
+ builder.addOverlayPackage(
+ OVERLAY_CATEGORY_SYSTEM_PALETTE,
+ toColorString(colorFromStub)
+ )
+ if (themeStyleEnabled) {
+ val styleName =
+ try {
+ getItemStringFromStub(COLOR_BUNDLE_STYLE_PREFIX, bundleName)
+ } catch (e: Resources.NotFoundException) {
+ null
+ }
+ val style =
+ try {
+ if (styleName != null) Style.valueOf(styleName)
+ else Style.TONAL_SPOT
+ } catch (e: IllegalArgumentException) {
+ Style.TONAL_SPOT
+ }
+ builder.style = style
+
+ lightColorScheme = ColorScheme(colorFromStub, /* darkTheme= */ false, style)
+ darkColorScheme = ColorScheme(colorFromStub, /* darkTheme= */ true, style)
+
+ when (style) {
+ Style.MONOCHROMATIC -> {
+ if (
+ !InjectorProvider.getInjector()
+ .getFlags()
+ .isMonochromaticThemeEnabled(mContext)
+ ) {
+ continue
+ }
+ darkColors = darkColorScheme.getRevampedUIDarkColorPreview()
+ lightColors = lightColorScheme.getRevampedUILightColorPreview()
+ }
+ else -> {
+ darkColors =
+ darkColorScheme.getRevampedUIPresetColorPreview(colorFromStub)
+ lightColors =
+ lightColorScheme.getRevampedUIPresetColorPreview(colorFromStub)
+ }
}
- extractor.addColorStyle(builder, styleName)
- val style =
- try {
- if (styleName != null) Style.valueOf(styleName) else Style.TONAL_SPOT
- } catch (e: IllegalArgumentException) {
- Style.TONAL_SPOT
+ }
+ builder.lightColors = lightColors
+ builder.darkColors = darkColors
+
+ bundles.add(builder.build())
+ } else {
+ val builder = ColorBundle.Builder()
+ builder.title = getItemStringFromStub(COLOR_BUNDLE_NAME_PREFIX, bundleName)
+ builder.setIndex(index)
+ val colorFromStub =
+ getItemColorFromStub(COLOR_BUNDLE_MAIN_COLOR_PREFIX, bundleName)
+ extractor.addPrimaryColor(builder, colorFromStub)
+ extractor.addSecondaryColor(builder, colorFromStub)
+ if (themeStyleEnabled) {
+ val styleName =
+ try {
+ getItemStringFromStub(COLOR_BUNDLE_STYLE_PREFIX, bundleName)
+ } catch (e: Resources.NotFoundException) {
+ null
+ }
+ extractor.addColorStyle(builder, styleName)
+ val style =
+ try {
+ if (styleName != null) Style.valueOf(styleName)
+ else Style.TONAL_SPOT
+ } catch (e: IllegalArgumentException) {
+ Style.TONAL_SPOT
+ }
+
+ if (
+ style == Style.MONOCHROMATIC &&
+ !InjectorProvider.getInjector()
+ .getFlags()
+ .isMonochromaticThemeEnabled(mContext)
+ ) {
+ continue
}
- if (
- style == Style.MONOCHROMATIC &&
- !InjectorProvider.getInjector()
- .getFlags()
- .isMonochromaticThemeEnabled(mContext)
- ) {
- continue
+ val darkColors =
+ ColorScheme(colorFromStub, /* darkTheme= */ true, style)
+ .getPresetColorPreview(colorFromStub)
+ val lightColors =
+ ColorScheme(colorFromStub, /* darkTheme= */ false, style)
+ .getPresetColorPreview(colorFromStub)
+ builder
+ .setColorPrimaryDark(darkColors[0])
+ .setColorSecondaryDark(darkColors[1])
+ builder
+ .setColorPrimaryLight(lightColors[0])
+ .setColorSecondaryLight(lightColors[1])
}
- val darkColors =
- ColorScheme(colorFromStub, true, style).getPresetColorPreview(colorFromStub)
- val lightColors =
- ColorScheme(colorFromStub, false, style)
- .getPresetColorPreview(colorFromStub)
- builder.setColorPrimaryDark(darkColors[0]).setColorSecondaryDark(darkColors[1])
- builder
- .setColorPrimaryLight(lightColors[0])
- .setColorSecondaryLight(lightColors[1])
+ bundles.add(builder.build(mContext))
}
-
- bundles.add(builder.build(mContext))
index++
}
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 a0ac370..b0ff1db 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
@@ -20,8 +20,7 @@
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
-import com.android.customization.model.color.ColorBundle
-import com.android.customization.model.color.ColorSeedOption
+import com.android.customization.model.color.ColorOptionImpl
import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
import com.android.customization.picker.clock.shared.ClockSize
import com.android.customization.picker.clock.shared.model.ClockMetadataModel
@@ -201,52 +200,32 @@
private suspend fun ColorOptionModel.toOptionItemViewModel(
context: Context
): OptionItemViewModel<ColorOptionIconViewModel> {
- val optionItemPayload =
- when (colorOption) {
- is ColorSeedOption -> {
- val lightThemeColors =
- colorOption.previewInfo.resolveColors(
- /** darkTheme= */
- false
- )
- val darkThemeColors =
- colorOption.previewInfo.resolveColors(
- /** darkTheme= */
- true
- )
- ColorOptionIconViewModel(
- lightThemeColor0 = lightThemeColors[0],
- lightThemeColor1 = lightThemeColors[1],
- lightThemeColor2 = lightThemeColors[2],
- lightThemeColor3 = lightThemeColors[3],
- darkThemeColor0 = darkThemeColors[0],
- darkThemeColor1 = darkThemeColors[1],
- darkThemeColor2 = darkThemeColors[2],
- darkThemeColor3 = darkThemeColors[3],
- )
- }
- is ColorBundle -> {
- val primaryColor =
- colorOption.previewInfo.resolvePrimaryColor(context.resources)
- val secondaryColor =
- colorOption.previewInfo.resolveSecondaryColor(context.resources)
- ColorOptionIconViewModel(
- lightThemeColor0 = primaryColor,
- lightThemeColor1 = secondaryColor,
- lightThemeColor2 = primaryColor,
- lightThemeColor3 = secondaryColor,
- darkThemeColor0 = primaryColor,
- darkThemeColor1 = secondaryColor,
- darkThemeColor2 = primaryColor,
- darkThemeColor3 = secondaryColor,
- )
- }
- else -> null
- }
+ val lightThemeColors =
+ (colorOption as ColorOptionImpl)
+ .previewInfo
+ .resolveColors(
+ /** darkTheme= */
+ false
+ )
+ val darkThemeColors =
+ colorOption.previewInfo.resolveColors(
+ /** darkTheme= */
+ true
+ )
val isSelectedFlow = selectedColorId.map { it == null }.stateIn(viewModelScope)
return OptionItemViewModel<ColorOptionIconViewModel>(
key = MutableStateFlow(key) as StateFlow<String>,
- payload = optionItemPayload,
+ payload =
+ ColorOptionIconViewModel(
+ lightThemeColor0 = lightThemeColors[0],
+ lightThemeColor1 = lightThemeColors[1],
+ lightThemeColor2 = lightThemeColors[2],
+ lightThemeColor3 = lightThemeColors[3],
+ darkThemeColor0 = darkThemeColors[0],
+ darkThemeColor1 = darkThemeColors[1],
+ darkThemeColor2 = darkThemeColors[2],
+ darkThemeColor3 = darkThemeColors[3],
+ ),
text = Text.Loaded(context.getString(R.string.default_theme_title)),
isTextUserVisible = true,
isSelected = isSelectedFlow,
diff --git a/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt b/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt
index a044174..464e8bf 100644
--- a/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt
@@ -19,10 +19,9 @@
import android.app.WallpaperColors
import android.util.Log
import com.android.customization.model.CustomizationManager
-import com.android.customization.model.color.ColorBundle
import com.android.customization.model.color.ColorCustomizationManager
import com.android.customization.model.color.ColorOption
-import com.android.customization.model.color.ColorSeedOption
+import com.android.customization.model.color.ColorOptionImpl
import com.android.customization.picker.color.shared.model.ColorOptionModel
import com.android.customization.picker.color.shared.model.ColorType
import com.android.systemui.monet.Style
@@ -60,10 +59,11 @@
val presetColorOptions: MutableList<ColorOptionModel> =
mutableListOf()
options?.forEach { option ->
- when (option) {
- is ColorSeedOption ->
+ when ((option as ColorOptionImpl).type) {
+ ColorType.WALLPAPER_COLOR ->
wallpaperColorOptions.add(option.toModel())
- is ColorBundle -> presetColorOptions.add(option.toModel())
+ ColorType.PRESET_COLOR ->
+ presetColorOptions.add(option.toModel())
}
}
continuation.resumeWith(
@@ -113,16 +113,16 @@
val overlays = colorManager.currentOverlays
val styleOrNull = colorManager.currentStyle
val style = styleOrNull?.let { Style.valueOf(it) } ?: Style.TONAL_SPOT
- val colorOptionBuilder =
- // Does not matter whether ColorSeedOption or ColorBundle builder is used here
- // because to apply the color, one just needs a generic ColorOption
- ColorSeedOption.Builder().setSource(colorManager.currentColorSource).setStyle(style)
+ val source = colorManager.currentColorSource
+ val colorOptionBuilder = ColorOptionImpl.Builder()
+ colorOptionBuilder.source = source
+ colorOptionBuilder.style = style
for (overlay in overlays) {
colorOptionBuilder.addOverlayPackage(overlay.key, overlay.value)
}
val colorOption = colorOptionBuilder.build()
return ColorOptionModel(
- key = "${colorOption.style}::${colorOption.serializedPackages}",
+ key = "",
colorOption = colorOption,
isSelected = false,
)
@@ -132,9 +132,9 @@
return colorManager.currentColorSource
}
- private fun ColorOption.toModel(): ColorOptionModel {
+ private fun ColorOptionImpl.toModel(): ColorOptionModel {
return ColorOptionModel(
- key = "${this.style}::${this.serializedPackages}",
+ key = "${this.type}::${this.style}::${this.serializedPackages}",
colorOption = this,
isSelected = isActive(colorManager),
)
diff --git a/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt b/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt
index edbf6dc..714129d 100644
--- a/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt
+++ b/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt
@@ -19,9 +19,8 @@
import android.content.Context
import android.graphics.Color
import android.text.TextUtils
-import com.android.customization.model.color.ColorBundle
+import com.android.customization.model.color.ColorOptionImpl
import com.android.customization.model.color.ColorOptionsProvider
-import com.android.customization.model.color.ColorSeedOption
import com.android.customization.picker.color.shared.model.ColorOptionModel
import com.android.customization.picker.color.shared.model.ColorType
import kotlinx.coroutines.flow.MutableStateFlow
@@ -82,9 +81,7 @@
ColorOptionModel(
key = "${ColorType.PRESET_COLOR}::$index",
colorOption = buildPresetOption(index),
- isSelected =
- selectedColorOptionType == ColorType.PRESET_COLOR &&
- selectedColorOptionIndex == index,
+ isSelected = isSelected,
)
if (isSelected) {
selectedColorOption = colorOption
@@ -95,36 +92,36 @@
)
}
- private fun buildPresetOption(index: Int): ColorBundle {
- return ColorBundle.Builder()
+ private fun buildPresetOption(index: Int): ColorOptionImpl {
+ val builder = ColorOptionImpl.Builder()
+ builder.lightColors =
+ intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT)
+ builder.darkColors =
+ intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT)
+ builder.index = index
+ builder.type = ColorType.PRESET_COLOR
+ builder.source = ColorOptionsProvider.COLOR_SOURCE_PRESET
+ builder.title = "Preset"
+ builder
.addOverlayPackage("TEST_PACKAGE_TYPE", "preset_color")
.addOverlayPackage("TEST_PACKAGE_INDEX", "$index")
- .setIndex(index)
- .build(context)
+ return builder.build()
}
- private fun buildWallpaperOption(index: Int): ColorSeedOption {
- return ColorSeedOption.Builder()
- .setLightColors(
- intArrayOf(
- Color.TRANSPARENT,
- Color.TRANSPARENT,
- Color.TRANSPARENT,
- Color.TRANSPARENT
- )
- )
- .setDarkColors(
- intArrayOf(
- Color.TRANSPARENT,
- Color.TRANSPARENT,
- Color.TRANSPARENT,
- Color.TRANSPARENT
- )
- )
+ private fun buildWallpaperOption(index: Int): ColorOptionImpl {
+ val builder = ColorOptionImpl.Builder()
+ builder.lightColors =
+ intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT)
+ builder.darkColors =
+ intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT)
+ builder.index = index
+ builder.type = ColorType.WALLPAPER_COLOR
+ builder.source = ColorOptionsProvider.COLOR_SOURCE_HOME
+ builder.title = "Dynamic"
+ builder
.addOverlayPackage("TEST_PACKAGE_TYPE", "wallpaper_color")
.addOverlayPackage("TEST_PACKAGE_INDEX", "$index")
- .setIndex(index)
- .build()
+ return builder.build()
}
override suspend fun select(colorOptionModel: ColorOptionModel) {
@@ -163,9 +160,9 @@
override fun getCurrentColorOption(): ColorOptionModel = selectedColorOption
override fun getCurrentColorSource(): String? =
- when (selectedColorOption.colorOption) {
- is ColorSeedOption -> ColorOptionsProvider.COLOR_SOURCE_HOME
- is ColorBundle -> ColorOptionsProvider.COLOR_SOURCE_PRESET
+ when ((selectedColorOption.colorOption as ColorOptionImpl).type) {
+ ColorType.WALLPAPER_COLOR -> ColorOptionsProvider.COLOR_SOURCE_HOME
+ ColorType.PRESET_COLOR -> ColorOptionsProvider.COLOR_SOURCE_PRESET
else -> null
}
diff --git a/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt b/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt
index 97dbba6..119584d 100644
--- a/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt
+++ b/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt
@@ -20,8 +20,7 @@
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
-import com.android.customization.model.color.ColorBundle
-import com.android.customization.model.color.ColorSeedOption
+import com.android.customization.model.color.ColorOptionImpl
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
import com.android.customization.picker.color.shared.model.ColorType
import com.android.wallpaper.R
@@ -96,125 +95,52 @@
colorOptions
.map { colorOptionEntry ->
colorOptionEntry.key to
- when (colorOptionEntry.key) {
- ColorType.WALLPAPER_COLOR -> {
- colorOptionEntry.value.map { colorOptionModel ->
- val colorSeedOption: ColorSeedOption =
- colorOptionModel.colorOption as ColorSeedOption
- val lightThemeColors =
- colorSeedOption.previewInfo.resolveColors(
- /* darkTheme= */ false
- )
- val darkThemeColors =
- colorSeedOption.previewInfo.resolveColors(
- /* darkTheme= */ true
- )
- val isSelectedFlow: StateFlow<Boolean> =
- interactor.activeColorOption
- .map {
- it?.colorOption?.isEquivalent(
- colorOptionModel.colorOption
- )
- ?: colorOptionModel.isSelected
- }
- .stateIn(viewModelScope)
- OptionItemViewModel<ColorOptionIconViewModel>(
- key =
- MutableStateFlow(colorOptionModel.key)
- as StateFlow<String>,
- payload =
- ColorOptionIconViewModel(
- lightThemeColor0 = lightThemeColors[0],
- lightThemeColor1 = lightThemeColors[1],
- lightThemeColor2 = lightThemeColors[2],
- lightThemeColor3 = lightThemeColors[3],
- darkThemeColor0 = darkThemeColors[0],
- darkThemeColor1 = darkThemeColors[1],
- darkThemeColor2 = darkThemeColors[2],
- darkThemeColor3 = darkThemeColors[3],
- ),
- text =
- Text.Loaded(
- colorSeedOption
- .getContentDescription(context)
- .toString()
- ),
- isTextUserVisible = false,
- isSelected = isSelectedFlow,
- onClicked =
- isSelectedFlow.map { isSelected ->
- if (isSelected) {
- null
- } else {
- {
- viewModelScope.launch {
- interactor.select(colorOptionModel)
- }
- }
+ colorOptionEntry.value.map { colorOptionModel ->
+ val colorOption: ColorOptionImpl =
+ colorOptionModel.colorOption as ColorOptionImpl
+ val lightThemeColors =
+ colorOption.previewInfo.resolveColors(/* darkTheme= */ false)
+ val darkThemeColors =
+ colorOption.previewInfo.resolveColors(/* darkTheme= */ true)
+ val isSelectedFlow: StateFlow<Boolean> =
+ interactor.activeColorOption
+ .map {
+ it?.colorOption?.isEquivalent(colorOptionModel.colorOption)
+ ?: colorOptionModel.isSelected
+ }
+ .stateIn(viewModelScope)
+ OptionItemViewModel<ColorOptionIconViewModel>(
+ key = MutableStateFlow(colorOptionModel.key) as StateFlow<String>,
+ payload =
+ ColorOptionIconViewModel(
+ lightThemeColor0 = lightThemeColors[0],
+ lightThemeColor1 = lightThemeColors[1],
+ lightThemeColor2 = lightThemeColors[2],
+ lightThemeColor3 = lightThemeColors[3],
+ darkThemeColor0 = darkThemeColors[0],
+ darkThemeColor1 = darkThemeColors[1],
+ darkThemeColor2 = darkThemeColors[2],
+ darkThemeColor3 = darkThemeColors[3],
+ ),
+ text =
+ Text.Loaded(
+ colorOption.getContentDescription(context).toString()
+ ),
+ isTextUserVisible = false,
+ isSelected = isSelectedFlow,
+ onClicked =
+ isSelectedFlow.map { isSelected ->
+ if (isSelected) {
+ null
+ } else {
+ {
+ viewModelScope.launch {
+ interactor.select(colorOptionModel)
}
- },
- )
- }
- }
- ColorType.PRESET_COLOR -> {
- colorOptionEntry.value.map { colorOptionModel ->
- val colorBundle: ColorBundle =
- colorOptionModel.colorOption as ColorBundle
- val primaryColor =
- colorBundle.previewInfo.resolvePrimaryColor(
- context.resources
- )
- val secondaryColor =
- colorBundle.previewInfo.resolveSecondaryColor(
- context.resources
- )
- val isSelectedFlow: StateFlow<Boolean> =
- interactor.activeColorOption
- .map {
- it?.colorOption?.isEquivalent(
- colorOptionModel.colorOption
- )
- ?: colorOptionModel.isSelected
}
- .stateIn(viewModelScope)
- OptionItemViewModel<ColorOptionIconViewModel>(
- key =
- MutableStateFlow(colorOptionModel.key)
- as StateFlow<String>,
- payload =
- ColorOptionIconViewModel(
- lightThemeColor0 = primaryColor,
- lightThemeColor1 = secondaryColor,
- lightThemeColor2 = primaryColor,
- lightThemeColor3 = secondaryColor,
- darkThemeColor0 = primaryColor,
- darkThemeColor1 = secondaryColor,
- darkThemeColor2 = primaryColor,
- darkThemeColor3 = secondaryColor,
- ),
- text =
- Text.Loaded(
- colorBundle
- .getContentDescription(context)
- .toString()
- ),
- isTextUserVisible = false,
- isSelected = isSelectedFlow,
- onClicked =
- isSelectedFlow.map { isSelected ->
- if (isSelected) {
- null
- } else {
- {
- viewModelScope.launch {
- interactor.select(colorOptionModel)
- }
- }
- }
- },
- )
- }
- }
+ }
+ },
+ )
}
}
.toMap()
diff --git a/tests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt b/tests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt
index 1d9457a..a29d559 100644
--- a/tests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt
+++ b/tests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt
@@ -61,8 +61,8 @@
fun setUp() {
context = InstrumentationRegistry.getInstrumentation().targetContext
val testDispatcher = StandardTestDispatcher()
- testScope = TestScope(testDispatcher)
Dispatchers.setMain(testDispatcher)
+ testScope = TestScope(testDispatcher)
repository = FakeColorPickerRepository(context = context)
store = FakeSnapshotStore()