[TP] Clock color updates
Support the update of the clock color.
Clock color will change when a color option is selected.
Test: Manually tested that the clock color can be updated
Bug: 269203967
Change-Id: I5d7632e3d7ba14108ee9111f323edaa912c7bd6f
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
index 66793cd..3474858 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
@@ -16,6 +16,8 @@
*/
package com.android.customization.picker.clock.data.repository
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
import com.android.customization.picker.clock.shared.ClockSize
import com.android.customization.picker.clock.shared.model.ClockMetadataModel
import kotlinx.coroutines.flow.Flow
@@ -33,7 +35,18 @@
fun setSelectedClock(clockId: String)
- fun setClockColor(color: Int?)
+ /**
+ * Set clock color to the settings.
+ *
+ * @param selectedColor selected color in the color option list.
+ * @param colorTone color tone from 0 to 100 to apply to the selected color
+ * @param seedColor the actual clock color after blending the selected color and color tone
+ */
+ fun setClockColor(
+ @ColorInt selectedColor: Int?,
+ @IntRange(from = 0, to = 100) colorTone: Int,
+ @ColorInt seedColor: Int?,
+ )
suspend fun setClockSize(size: ClockSize)
}
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
index a360b6c..e96649b 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -17,6 +17,8 @@
package com.android.customization.picker.clock.data.repository
import android.provider.Settings
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
import com.android.customization.picker.clock.shared.ClockSize
import com.android.customization.picker.clock.shared.model.ClockMetadataModel
import com.android.systemui.plugins.ClockMetadata
@@ -34,6 +36,7 @@
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.shareIn
+import org.json.JSONObject
/** Implementation of [ClockPickerRepository], using [ClockRegistry]. */
class ClockPickerRepositoryImpl(
@@ -50,7 +53,7 @@
registry
.getClocks()
.filter { "NOT_IN_USE" !in it.clockId }
- .map { it.toModel(null) }
+ .map { it.toModel() }
trySend(allClocks)
}
@@ -72,18 +75,22 @@
allClocks
}
- /** The currently-selected clock. */
+ /** The currently-selected clock. This also emits the clock color information. */
override val selectedClock: Flow<ClockMetadataModel> =
callbackFlow {
fun send() {
val currentClockId = registry.currentClockId
- // It is possible that the model can be null since the full clock list is not
- // initiated.
+ val metadata = registry.settings?.metadata
val model =
registry
.getClocks()
.find { clockMetadata -> clockMetadata.clockId == currentClockId }
- ?.toModel(registry.seedColor)
+ ?.toModel(
+ selectedColor = metadata?.getSelectedColor(),
+ colorTone = metadata?.getColorTone()
+ ?: ClockMetadataModel.DEFAULT_COLOR_TONE,
+ seedColor = registry.seedColor
+ )
trySend(model)
}
@@ -104,11 +111,26 @@
.mapNotNull { it }
override fun setSelectedClock(clockId: String) {
- registry.currentClockId = clockId
+ registry.mutateSetting { oldSettings ->
+ val newSettings = oldSettings.copy(clockId = clockId)
+ newSettings.metadata = oldSettings.metadata
+ newSettings
+ }
}
- override fun setClockColor(color: Int?) {
- registry.seedColor = color
+ override fun setClockColor(
+ @ColorInt selectedColor: Int?,
+ @IntRange(from = 0, to = 100) colorTone: Int,
+ @ColorInt seedColor: Int?,
+ ) {
+ registry.mutateSetting { oldSettings ->
+ val newSettings = oldSettings.copy(seedColor = seedColor)
+ newSettings.metadata =
+ oldSettings.metadata
+ .put(KEY_METADATA_SELECTED_COLOR, selectedColor)
+ .put(KEY_METADATA_COLOR_TONE, colorTone)
+ newSettings
+ }
}
override val selectedClockSize: SharedFlow<ClockSize> =
@@ -131,7 +153,38 @@
)
}
- private fun ClockMetadata.toModel(color: Int?): ClockMetadataModel {
- return ClockMetadataModel(clockId = clockId, name = name, color = color)
+ private fun JSONObject.getSelectedColor(): Int? {
+ return if (this.isNull(KEY_METADATA_SELECTED_COLOR)) {
+ null
+ } else {
+ this.getInt(KEY_METADATA_SELECTED_COLOR)
+ }
+ }
+
+ private fun JSONObject.getColorTone(): Int {
+ return this.optInt(KEY_METADATA_COLOR_TONE, ClockMetadataModel.DEFAULT_COLOR_TONE)
+ }
+
+ /** By default, [ClockMetadataModel] has no color information unless specified. */
+ private fun ClockMetadata.toModel(
+ @ColorInt selectedColor: Int? = null,
+ @IntRange(from = 0, to = 100) colorTone: Int = 0,
+ @ColorInt seedColor: Int? = null,
+ ): ClockMetadataModel {
+ return ClockMetadataModel(
+ clockId = clockId,
+ name = name,
+ selectedColor = selectedColor,
+ colorTone = colorTone,
+ seedColor = seedColor,
+ )
+ }
+
+ companion object {
+ // The selected color in the color option list
+ private const val KEY_METADATA_SELECTED_COLOR = "metadataSelectedColor"
+
+ // The color tone to apply to the selected color
+ private const val KEY_METADATA_COLOR_TONE = "metadataColorTone"
}
}
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
index 677fcfa..794706f 100644
--- a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
@@ -21,6 +21,7 @@
import com.android.customization.picker.clock.shared.ClockSize
import com.android.customization.picker.clock.shared.model.ClockMetadataModel
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
/**
@@ -31,9 +32,15 @@
val allClocks: Flow<List<ClockMetadataModel>> = repository.allClocks
- val selectedClock: Flow<ClockMetadataModel> = repository.selectedClock
+ val selectedClockId: Flow<String> =
+ repository.selectedClock.map { clock -> clock.clockId }.distinctUntilChanged()
- val selectedClockColor: Flow<Int?> = repository.selectedClock.map { clock -> clock.color }
+ val selectedColor: Flow<Int?> =
+ repository.selectedClock.map { clock -> clock.selectedColor }.distinctUntilChanged()
+
+ val colorTone: Flow<Int> = repository.selectedClock.map { clock -> clock.colorTone }
+
+ val seedColor: Flow<Int?> = repository.selectedClock.map { clock -> clock.seedColor }
val selectedClockSize: Flow<ClockSize> = repository.selectedClockSize
@@ -41,8 +48,8 @@
repository.setSelectedClock(clockId)
}
- fun setClockColor(color: Int?) {
- repository.setClockColor(color)
+ fun setClockColor(selectedColor: Int?, colorTone: Int, seedColor: Int?) {
+ repository.setClockColor(selectedColor, colorTone, seedColor)
}
suspend fun setClockSize(size: ClockSize) {
diff --git a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
index acbc792..72aeca6 100644
--- a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
+++ b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
@@ -17,9 +17,18 @@
package com.android.customization.picker.clock.shared.model
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
+
/** Model for clock metadata. */
data class ClockMetadataModel(
val clockId: String,
val name: String,
- val color: Int?,
-)
+ @ColorInt val selectedColor: Int?,
+ @IntRange(from = 0, to = 100) val colorTone: Int,
+ @ColorInt val seedColor: Int?,
+) {
+ companion object {
+ const val DEFAULT_COLOR_TONE = 50
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
index 7ea0210..62d7217 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -63,8 +63,10 @@
}
}
- override fun onStartTrackingTouch(p0: SeekBar?) = Unit
- override fun onStopTrackingTouch(p0: SeekBar?) = Unit
+ override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ seekBar?.progress?.let { viewModel.onSliderProgressStop(it) }
+ }
}
)
@@ -120,14 +122,12 @@
launch {
viewModel.sliderProgress.collect { progress ->
- progress?.let { slider.setProgress(progress, false) }
+ slider.setProgress(progress, true)
}
}
launch {
- viewModel.isSliderEnabled.collect { isEnabled ->
- slider.isInvisible = !isEnabled
- }
+ viewModel.isSliderEnabled.collect { isEnabled -> slider.isEnabled = isEnabled }
}
}
}
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
index 8d614e4..8fe9dca 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
@@ -55,8 +55,8 @@
val selectedIndex: Flow<Int> =
allClockIds
.flatMapLatest { allClockIds ->
- interactor.selectedClock.map { selectedClock ->
- val index = allClockIds.indexOf(selectedClock.clockId)
+ interactor.selectedClockId.map { selectedClockId ->
+ val index = allClockIds.indexOf(selectedClockId)
if (index >= 0) {
index
} else {
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 b36c8eb..06fd2af 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
@@ -24,12 +24,11 @@
import com.android.customization.model.color.ColorSeedOption
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
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
import com.android.customization.picker.color.shared.model.ColorType
import com.android.customization.picker.color.ui.viewmodel.ColorOptionViewModel
import com.android.wallpaper.R
-import kotlin.math.abs
-import kotlin.math.roundToInt
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
@@ -38,9 +37,10 @@
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
@@ -57,63 +57,42 @@
SIZE,
}
- private val helperColorHsl: FloatArray by lazy { FloatArray(3) }
+ val selectedColor: StateFlow<Int?> =
+ clockPickerInteractor.selectedColor.stateIn(viewModelScope, SharingStarted.Eagerly, null)
+
+ private val sliderProgressColorTone = MutableStateFlow(ClockMetadataModel.DEFAULT_COLOR_TONE)
+ val isSliderEnabled: Flow<Boolean> =
+ clockPickerInteractor.selectedColor.map { it != null }.distinctUntilChanged()
+ val sliderProgress: Flow<Int> = merge(clockPickerInteractor.colorTone, sliderProgressColorTone)
+
+ private val _seedColor: MutableStateFlow<Int?> = MutableStateFlow(null)
+ val seedColor: Flow<Int?> = merge(clockPickerInteractor.seedColor, _seedColor)
/**
- * Saturation level of the current selected color. Note that this can be null if the selected
- * color is null, which means that the clock color respects the system theme color. In this
- * case, the saturation level is no longer needed since we do not allow changing saturation
- * level of the system theme color.
+ * The slider color tone updates are quick. Do not set color tone and the blended color to the
+ * settings until [onSliderProgressStop] is called. Update to a locally cached temporary
+ * [sliderProgressColorTone] and [_seedColor] instead.
*/
- private val saturationLevel: Flow<Float?> =
- clockPickerInteractor.selectedClockColor
- .map { selectedColor ->
- if (selectedColor == null) {
- null
- } else {
- ColorUtils.colorToHSL(selectedColor, helperColorHsl)
- helperColorHsl[1]
- }
- }
- .shareIn(
- scope = viewModelScope,
- started = SharingStarted.WhileSubscribed(),
- replay = 1,
- )
-
- /**
- * When the selected clock color is null, it means that the clock will respect the system theme
- * color. And we no longer need the slider, which determines the saturation level of the clock's
- * overridden color.
- */
- val isSliderEnabled: Flow<Boolean> = saturationLevel.map { it != null }
-
- /**
- * Slide progress from 0 to 100. Note that this can be null if the selected color is null, which
- * means that the clock color respects the system theme color. In this case, the saturation
- * level is no longer needed since we do not allow changing saturation level of the system theme
- * color.
- */
- val sliderProgress: Flow<Int?> =
- saturationLevel.map { saturation -> saturation?.let { (it * 100).roundToInt() } }
-
fun onSliderProgressChanged(progress: Int) {
- val saturation = progress / 100f
- val selectedOption = colorOptions.value.find { option -> option.isSelected }
- selectedOption?.let { option ->
- ColorUtils.colorToHSL(option.color0, helperColorHsl)
- helperColorHsl[1] = saturation
- clockPickerInteractor.setClockColor(ColorUtils.HSLToColor(helperColorHsl))
+ sliderProgressColorTone.value = progress
+ val color = selectedColor.value
+ if (color != null) {
+ _seedColor.value = blendColorWithTone(color, progress)
}
}
+ fun onSliderProgressStop(progress: Int) {
+ val color = selectedColor.value ?: return
+ clockPickerInteractor.setClockColor(
+ selectedColor = color,
+ colorTone = progress,
+ seedColor = blendColorWithTone(color = color, colorTone = progress)
+ )
+ }
+
@OptIn(ExperimentalCoroutinesApi::class)
val colorOptions: StateFlow<List<ColorOptionViewModel>> =
- combine(
- colorPickerInteractor.colorOptions,
- clockPickerInteractor.selectedClockColor,
- ::Pair,
- )
+ combine(colorPickerInteractor.colorOptions, clockPickerInteractor.selectedColor, ::Pair)
.mapLatest { (colorOptions, selectedColor) ->
// Use mapLatest and delay(100) here to prevent too many selectedClockColor update
// events from ClockRegistry upstream, caused by sliding the saturation level bar.
@@ -138,36 +117,16 @@
add(defaultThemeColorOptionViewModel)
}
- if (selectedColor != null) {
- ColorUtils.colorToHSL(selectedColor, helperColorHsl)
- }
-
val selectedColorPosition =
if (selectedColor != null) {
- getSelectedColorPosition(helperColorHsl)
+ COLOR_SET_LIST.indexOf(selectedColor)
} else {
-1
}
- COLOR_LIST_HSL.forEachIndexed { index, colorHSL ->
- val color = ColorUtils.HSLToColor(colorHSL)
+ COLOR_SET_LIST.forEachIndexed { index, color ->
val isSelected = selectedColorPosition == index
- val colorToSet: Int by lazy {
- val saturation =
- if (selectedColor != null) {
- helperColorHsl[1]
- } else {
- colorHSL[1]
- }
- ColorUtils.HSLToColor(
- listOf(
- colorHSL[0],
- saturation,
- colorHSL[2],
- )
- .toFloatArray()
- )
- }
+ val colorTone = ClockMetadataModel.DEFAULT_COLOR_TONE
add(
ColorOptionViewModel(
color0 = color,
@@ -184,7 +143,17 @@
if (isSelected) {
null
} else {
- { clockPickerInteractor.setClockColor(colorToSet) }
+ {
+ clockPickerInteractor.setClockColor(
+ selectedColor = color,
+ colorTone = colorTone,
+ seedColor =
+ blendColorWithTone(
+ color = color,
+ colorTone = colorTone,
+ ),
+ )
+ }
},
)
)
@@ -214,7 +183,13 @@
if (selectedColor == null) {
null
} else {
- { clockPickerInteractor.setClockColor(null) }
+ {
+ clockPickerInteractor.setClockColor(
+ selectedColor = null,
+ colorTone = ClockMetadataModel.DEFAULT_COLOR_TONE,
+ seedColor = null,
+ )
+ }
},
)
}
@@ -237,7 +212,13 @@
if (selectedColor == null) {
null
} else {
- { clockPickerInteractor.setClockColor(null) }
+ {
+ clockPickerInteractor.setClockColor(
+ selectedColor = null,
+ colorTone = ClockMetadataModel.DEFAULT_COLOR_TONE,
+ seedColor = null,
+ )
+ }
},
)
}
@@ -279,19 +260,28 @@
companion object {
// TODO (b/241966062) The color integers here are temporary for dev purposes. We need to
// finalize the overridden colors.
- val COLOR_LIST_HSL =
+ val COLOR_SET_LIST =
listOf(
- arrayOf(225f, 0.65f, 0.74f).toFloatArray(),
- arrayOf(30f, 0.65f, 0.74f).toFloatArray(),
- arrayOf(249f, 0.65f, 0.74f).toFloatArray(),
- arrayOf(144f, 0.65f, 0.74f).toFloatArray(),
+ -786432,
+ -3648768,
+ -9273600,
+ -16739840,
+ -9420289,
+ -6465837,
+ -5032719,
)
- const val COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS: Long = 100
-
- fun getSelectedColorPosition(selectedColorHsl: FloatArray): Int {
- return COLOR_LIST_HSL.withIndex().minBy { abs(it.value[0] - selectedColorHsl[0]) }.index
+ fun blendColorWithTone(color: Int, colorTone: Int): Int {
+ val helperColorLab: DoubleArray by lazy { DoubleArray(3) }
+ ColorUtils.colorToLAB(color, helperColorLab)
+ return ColorUtils.LABToColor(
+ colorTone.toDouble(),
+ helperColorLab[1],
+ helperColorLab[2],
+ )
}
+
+ const val COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS: Long = 100
}
class Factory(
diff --git a/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
index b2cb452..918cfb1 100644
--- a/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
+++ b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
@@ -15,6 +15,8 @@
*/
package com.android.customization.picker.clock.data.repository
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository.Companion.fakeClocks
import com.android.customization.picker.clock.shared.ClockSize
import com.android.customization.picker.clock.shared.model.ClockMetadataModel
@@ -24,17 +26,30 @@
import kotlinx.coroutines.flow.combine
/** By default [FakeClockPickerRepository] uses [fakeClocks]. */
-open class FakeClockPickerRepository(private val clocks: List<ClockMetadataModel> = fakeClocks) :
+open class FakeClockPickerRepository(clocks: List<ClockMetadataModel> = fakeClocks) :
ClockPickerRepository {
override val allClocks: Flow<List<ClockMetadataModel>> = MutableStateFlow(clocks).asStateFlow()
private val selectedClockId = MutableStateFlow(fakeClocks[0].clockId)
- private val clockColor = MutableStateFlow<Int?>(null)
+ @ColorInt private val selectedColor = MutableStateFlow<Int?>(null)
+ private val colorTone = MutableStateFlow<Int>(ClockMetadataModel.DEFAULT_COLOR_TONE)
+ @ColorInt private val seedColor = MutableStateFlow<Int?>(null)
override val selectedClock: Flow<ClockMetadataModel> =
- combine(selectedClockId, clockColor) { selectedClockId, clockColor ->
+ combine(
+ selectedClockId,
+ selectedColor,
+ colorTone,
+ seedColor,
+ ) { selectedClockId, selectedColor, colorTone, seedColor ->
val selectedClock = fakeClocks.find { clock -> clock.clockId == selectedClockId }
checkNotNull(selectedClock)
- ClockMetadataModel(selectedClock.clockId, selectedClock.name, clockColor)
+ ClockMetadataModel(
+ selectedClock.clockId,
+ selectedClock.name,
+ selectedColor,
+ colorTone,
+ seedColor,
+ )
}
private val _selectedClockSize = MutableStateFlow(ClockSize.SMALL)
@@ -44,8 +59,14 @@
selectedClockId.value = clockId
}
- override fun setClockColor(color: Int?) {
- clockColor.value = color
+ override fun setClockColor(
+ @ColorInt selectedColor: Int?,
+ @IntRange(from = 0, to = 100) colorTone: Int,
+ @ColorInt seedColor: Int?,
+ ) {
+ this.selectedColor.value = selectedColor
+ this.colorTone.value = colorTone
+ this.seedColor.value = seedColor
}
override suspend fun setClockSize(size: ClockSize) {
@@ -55,10 +76,12 @@
companion object {
val fakeClocks =
listOf(
- ClockMetadataModel("clock0", "clock0", null),
- ClockMetadataModel("clock1", "clock1", null),
- ClockMetadataModel("clock2", "clock2", null),
- ClockMetadataModel("clock3", "clock3", null),
+ ClockMetadataModel("clock0", "clock0", null, 50, null),
+ ClockMetadataModel("clock1", "clock1", null, 50, null),
+ ClockMetadataModel("clock2", "clock2", null, 50, null),
+ ClockMetadataModel("clock3", "clock3", null, 50, null),
)
+ val clockColor = 0
+ val clockColorTone = 87
}
}
diff --git a/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt b/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
index 883d68b..01bfce1 100644
--- a/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
+++ b/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
@@ -37,6 +37,14 @@
}
@Test
+ fun setSelectedClock() = runTest {
+ val observedSelectedClockId = collectLastValue(underTest.selectedClockId)
+ underTest.setSelectedClock(FakeClockPickerRepository.fakeClocks[1].clockId)
+ Truth.assertThat(observedSelectedClockId())
+ .isEqualTo(FakeClockPickerRepository.fakeClocks[1].clockId)
+ }
+
+ @Test
fun setClockSize() = runTest {
val observedClockSize = collectLastValue(underTest.selectedClockSize)
underTest.setClockSize(ClockSize.DYNAMIC)
@@ -45,4 +53,19 @@
underTest.setClockSize(ClockSize.SMALL)
Truth.assertThat(observedClockSize()).isEqualTo(ClockSize.SMALL)
}
+
+ @Test
+ fun setColor() = runTest {
+ val observedSelectedColor = collectLastValue(underTest.selectedColor)
+ val observedColorTone = collectLastValue(underTest.colorTone)
+ val observedSeedColor = collectLastValue(underTest.seedColor)
+ underTest.setClockColor(
+ FakeClockPickerRepository.clockColor,
+ FakeClockPickerRepository.clockColorTone,
+ FakeClockPickerRepository.clockColor,
+ )
+ Truth.assertThat(observedSelectedColor()).isEqualTo(FakeClockPickerRepository.clockColor)
+ Truth.assertThat(observedColorTone()).isEqualTo(FakeClockPickerRepository.clockColorTone)
+ Truth.assertThat(observedSeedColor()).isEqualTo(FakeClockPickerRepository.clockColor)
+ }
}
diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
index 35c3518..ea1311f 100644
--- a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
+++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
@@ -42,7 +42,13 @@
private val repositoryWithSingleClock by lazy {
FakeClockPickerRepository(
listOf(
- ClockMetadataModel("clock0", "clock0", null),
+ ClockMetadataModel(
+ "clock0",
+ "clock0",
+ null,
+ ClockMetadataModel.DEFAULT_COLOR_TONE,
+ null,
+ ),
)
)
}
diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModelTest.kt
index 8f61d8b..10994c7 100644
--- a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModelTest.kt
+++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModelTest.kt
@@ -11,7 +11,6 @@
import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
import com.android.wallpaper.testing.FakeSnapshotStore
import com.android.wallpaper.testing.collectLastValue
-import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -66,7 +65,20 @@
}
@Test
- fun setClockColor() = runTest {
+ fun clickOnColorSettingsTab() = runTest {
+ val tabs = collectLastValue(underTest.tabs)
+ assertThat(tabs()?.get(0)?.name).isEqualTo("Color")
+ assertThat(tabs()?.get(0)?.isSelected).isTrue()
+ assertThat(tabs()?.get(1)?.name).isEqualTo("Size")
+ assertThat(tabs()?.get(1)?.isSelected).isFalse()
+
+ tabs()?.get(1)?.onClicked?.invoke()
+ assertThat(tabs()?.get(0)?.isSelected).isFalse()
+ assertThat(tabs()?.get(1)?.isSelected).isTrue()
+ }
+
+ @Test
+ fun setSelectedColor() = runTest {
val observedClockColorOptions = collectLastValue(underTest.colorOptions)
// Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions
advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
@@ -81,30 +93,25 @@
}
@Test
- fun setClockSaturation() = runTest {
+ fun setColorTone() = runTest {
val observedClockColorOptions = collectLastValue(underTest.colorOptions)
val observedIsSliderEnabled = collectLastValue(underTest.isSliderEnabled)
val observedSliderProgress = collectLastValue(underTest.sliderProgress)
// Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions
advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
+ assertThat(observedClockColorOptions()!![0].isSelected).isTrue()
assertThat(observedIsSliderEnabled()).isFalse()
- assertThat(observedSliderProgress()).isNull()
observedClockColorOptions()!![1].onClick?.invoke()
// Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions
advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
assertThat(observedIsSliderEnabled()).isTrue()
- val targetProgress = 99
- underTest.onSliderProgressChanged(targetProgress)
- advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
- assertThat(observedClockColorOptions()!![1].isSelected).isTrue()
- assertThat(observedSliderProgress())
- .isIn(
- Range.closed(
- targetProgress - 1,
- targetProgress + 1,
- )
- )
+ val targetProgress1 = 99
+ underTest.onSliderProgressChanged(targetProgress1)
+ assertThat(observedSliderProgress()).isEqualTo(targetProgress1)
+ val targetProgress2 = 55
+ underTest.onSliderProgressStop(targetProgress2)
+ assertThat(observedSliderProgress()).isEqualTo(targetProgress2)
}
@Test
@@ -116,17 +123,4 @@
underTest.setClockSize(ClockSize.SMALL)
assertThat(observedClockSize()).isEqualTo(ClockSize.SMALL)
}
-
- @Test
- fun `Click on a picker tab`() = runTest {
- val tabs = collectLastValue(underTest.tabs)
- assertThat(tabs()?.get(0)?.name).isEqualTo("Color")
- assertThat(tabs()?.get(0)?.isSelected).isTrue()
- assertThat(tabs()?.get(1)?.name).isEqualTo("Size")
- assertThat(tabs()?.get(1)?.isSelected).isFalse()
-
- tabs()?.get(1)?.onClicked?.invoke()
- assertThat(tabs()?.get(0)?.isSelected).isFalse()
- assertThat(tabs()?.get(1)?.isSelected).isTrue()
- }
}