Loading src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt +12 −1 Original line number Diff line number Diff line Loading @@ -169,6 +169,17 @@ object ClockFloatingSheetBinder { viewModel.onSliderProgressChanged(value.roundToInt()) } } addOnSliderTouchListener( object : OnSliderTouchListener { override fun onStartTrackingTouch(slider: Slider) { // Do nothing intended } override fun onStopTrackingTouch(slider: Slider) { viewModel.onSliderTouchUpProgressChanged(slider.value.roundToInt()) } } ) } val isClockColorActive = { isFloatingSheetActive() && viewModel.selectedTab.value == Tab.COLOR Loading Loading @@ -410,7 +421,7 @@ object ClockFloatingSheetBinder { } launch { viewModel.previewingSliderProgress.collect { progress -> viewModel.previewingColorSliderProgress.collect { progress -> clockColorSlider.value = progress.toFloat() } } Loading src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt +95 −63 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ constructor( combine(overridingClock, selectedClock) { overridingClock, selectedClock -> overridingClock != null && overridingClock.clockId != selectedClock.clockId } .distinctUntilChanged() val _previewingClockColorOptionIndex = MutableStateFlow<Int>(0) val previewingClockColorOptionIndex = _previewingClockColorOptionIndex.asStateFlow() Loading Loading @@ -227,8 +228,10 @@ constructor( overridingClockPresetIndexedStyle, selectedClockPresetIndexedStyle -> overridingClockPresetIndexedStyle != null && (overridingClockPresetIndexedStyle.style != selectedClockPresetIndexedStyle?.style) (overridingClockPresetIndexedStyle.style != selectedClockPresetIndexedStyle?.style) } .distinctUntilChanged() private val groups: Flow<List<AxisPresetConfig.Group>?> = previewingClock.map { it.axisPresetConfig?.groups } Loading Loading @@ -329,6 +332,7 @@ constructor( selectedClockSize -> overridingClockSize != null && overridingClockSize != selectedClockSize } .distinctUntilChanged() val previewingClockSize = combine(overridingClockSize, clockPickerInteractor.selectedClockSize) { overridingClockSize, Loading @@ -353,6 +357,7 @@ constructor( selectedColorId -> overridingClockColorId != null && (overridingClockColorId != selectedColorId) } .distinctUntilChanged() private val previewingClockColorId = combine(overridingClockColorId, clockPickerInteractor.selectedColorId) { overridingClockColorId, Loading @@ -360,19 +365,31 @@ constructor( overridingClockColorId ?: selectedColorId ?: DEFAULT_CLOCK_COLOR_ID } // Clock color slider progress. Range is 0 - 100. private val overridingSliderProgress = MutableStateFlow<Int?>(null) // Clock color slider progress. Range is 0 - 100. It update as frequently as user drags the // slider. private val overridingColorSliderProgress = MutableStateFlow<Int?>(null) // Clock color slider progress. Range is 0 - 100. It only update as user touches up the slider. private val overridingColorSliderTouchUpProgress = MutableStateFlow<Int?>(null) private val isSliderProgressEdited = combine(overridingSliderProgress, clockPickerInteractor.colorToneProgress) { overridingSliderProgress, combine(overridingColorSliderTouchUpProgress, clockPickerInteractor.colorToneProgress) { overridingColorSliderTouchUpProgress, colorToneProgress -> overridingSliderProgress != null && (overridingSliderProgress != colorToneProgress) overridingColorSliderTouchUpProgress != null && (overridingColorSliderTouchUpProgress != colorToneProgress) } val previewingSliderProgress: Flow<Int> = combine(overridingSliderProgress, clockPickerInteractor.colorToneProgress) { overridingSliderProgress, .distinctUntilChanged() // Note that this flow emits as frequently as user drags the slider. val previewingColorSliderProgress: Flow<Int> = combine(overridingColorSliderProgress, clockPickerInteractor.colorToneProgress) { overridingColorSliderProgress, colorToneProgress -> overridingColorSliderProgress ?: colorToneProgress } private val previewingColorSliderTouchUpProgress: Flow<Int> = combine(overridingColorSliderTouchUpProgress, clockPickerInteractor.colorToneProgress) { overridingColorSliderTouchUpProgress, colorToneProgress -> overridingSliderProgress ?: colorToneProgress overridingColorSliderTouchUpProgress ?: colorToneProgress } val isSliderEnabled: Flow<Boolean> = combine(previewingClock, previewingClockColorId) { clock, clockColorId -> Loading @@ -381,11 +398,19 @@ constructor( .distinctUntilChanged() fun onSliderProgressChanged(progress: Int) { overridingSliderProgress.value = progress overridingColorSliderProgress.value = progress } fun onSliderTouchUpProgressChanged(progress: Int) { overridingColorSliderProgress.value = progress overridingColorSliderTouchUpProgress.value = progress } // Note that this flow can emit as frequently as user drags the color slider. val previewingSeedColor: Flow<Int?> = combine(previewingClockColorId, previewingSliderProgress) { clockColorId, sliderProgress -> combine(previewingClockColorId, previewingColorSliderProgress) { clockColorId, colorSliderProgress -> val clockColorViewModel = if (clockColorId == DEFAULT_CLOCK_COLOR_ID) null else colorMap[clockColorId] if (clockColorViewModel == null) { Loading @@ -393,7 +418,7 @@ constructor( } else { blendColorWithTone( color = clockColorViewModel.color, colorTone = clockColorViewModel.getColorTone(sliderProgress), colorTone = clockColorViewModel.getColorTone(colorSliderProgress), ) } } Loading Loading @@ -442,7 +467,9 @@ constructor( { _previewingClockColorOptionIndex.value = index overridingClockColorId.value = colorModel.colorId overridingSliderProgress.value = overridingColorSliderProgress.value = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS overridingColorSliderTouchUpProgress.value = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS } } Loading Loading @@ -494,7 +521,9 @@ constructor( } else { { overridingClockColorId.value = DEFAULT_CLOCK_COLOR_ID overridingSliderProgress.value = overridingColorSliderProgress.value = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS overridingColorSliderTouchUpProgress.value = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS } } Loading @@ -502,41 +531,37 @@ constructor( ) } private val isEdited = val onApply: Flow<(suspend () -> Unit)?> = combine( isClockEdited, isClockAxisStyleEdited, isClockSizeEdited, isClockColorIdEdited, isSliderProgressEdited, ) { isClockEdited, isClockAxisStyleEdited, isClockSizeEdited, isClockColorEdited, isSliderProgressEdited -> isClockEdited || isClockAxisStyleEdited || isClockSizeEdited || isClockColorEdited || isSliderProgressEdited } val onApply: Flow<(suspend () -> Unit)?> = combine( isEdited, previewingClock, previewingClockSize, previewingClockColorId, previewingSliderProgress, previewingColorSliderTouchUpProgress, previewingClockPresetIndexedStyle, ) { array -> val isEdited: Boolean = array[0] as Boolean val clock: ClockMetadataModel = array[1] as ClockMetadataModel val size: ClockSize = array[2] as ClockSize val previewingColorId: String = array[3] as String val previewProgress: Int = array[4] as Int val isClockEdited: Boolean = array[0] as Boolean val isClockAxisStyleEdited: Boolean = array[1] as Boolean val isClockSizeEdited: Boolean = array[2] as Boolean val isClockColorIdEdited: Boolean = array[3] as Boolean val isSliderProgressEdited: Boolean = array[4] as Boolean val clock: ClockMetadataModel = array[5] as ClockMetadataModel val size: ClockSize = array[6] as ClockSize val previewingColorId: String = array[7] as String val previewingColorSliderProgress: Int = array[8] as Int val clockAxisStyle: ClockAxisStyle = (array[5] as? IndexedStyle)?.style ?: ClockAxisStyle() (array[9] as? IndexedStyle)?.style ?: ClockAxisStyle() val isEdited = isClockEdited || isClockAxisStyleEdited || isClockSizeEdited || isClockColorIdEdited || isSliderProgressEdited if (isEdited) { { val clockId: String = clock.clockId Loading @@ -544,26 +569,32 @@ constructor( colorMap[previewingColorId]?.let { blendColorWithTone( color = it.color, colorTone = it.getColorTone(previewProgress), colorTone = it.getColorTone(previewingColorSliderProgress), ) } clockPickerInteractor.applyClock( clockId = clockId, size = size, selectedColorId = previewingColorId, colorToneProgress = previewProgress, colorToneProgress = previewingColorSliderProgress, seedColor = seedColor, axisSettings = clockAxisStyle, ) logger.logClockApplied(clockId) if (isClockEdited) { logger.logClockApplied(clockId = clockId) } if (isClockSizeEdited) { logger.logClockSizeApplied( when (size) { ClockSize.SMALL -> StyleEnums.CLOCK_SIZE_SMALL ClockSize.DYNAMIC -> StyleEnums.CLOCK_SIZE_DYNAMIC } ) } if (isClockColorIdEdited) { seedColor?.let { logger.logClockColorApplied(it) } } } } else { null } Loading @@ -573,7 +604,8 @@ constructor( overridingClock.value = null overridingClockSize.value = null overridingClockColorId.value = null overridingSliderProgress.value = null overridingColorSliderProgress.value = null overridingColorSliderTouchUpProgress.value = null overridingClockPresetIndexedStyle.value = null _selectedTab.value = Tab.STYLE _showClockFacePresetGroupIndexUpdateToast.value = null Loading tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt +14 −3 Original line number Diff line number Diff line Loading @@ -402,7 +402,7 @@ class ClockPickerViewModelTest { //// Clock color @Test fun sliderProgress_whenOnSliderProgressChanged() = runTest { val sliderProgress = collectLastValue(underTest.previewingSliderProgress) val sliderProgress = collectLastValue(underTest.previewingColorSliderProgress) assertThat(sliderProgress()).isEqualTo(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS) Loading @@ -411,6 +411,17 @@ class ClockPickerViewModelTest { assertThat(sliderProgress()).isEqualTo(87) } @Test fun sliderTouchUpProgress_whenOnSliderProgressChanged() = runTest { val sliderProgress = collectLastValue(underTest.previewingColorSliderProgress) assertThat(sliderProgress()).isEqualTo(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS) underTest.onSliderTouchUpProgressChanged(87) assertThat(sliderProgress()).isEqualTo(87) } @Test fun isSliderEnabledShouldBeTrue_whenTheClockIsReactiveToToneAndSolidColor() = runTest { val clockStyleOptions = collectLastValue(underTest.clockStyleOptions) Loading Loading @@ -608,7 +619,7 @@ class ClockPickerViewModelTest { fun apply_notNullWhenSliderProgressChanged() = runTest { val onApply = collectLastValue(underTest.onApply) underTest.onSliderProgressChanged(87) underTest.onSliderTouchUpProgressChanged(87) assertThat(onApply()).isNotNull() } Loading @@ -617,7 +628,7 @@ class ClockPickerViewModelTest { fun apply_nullAfterApplyingSliderProgress() = runTest { val onApply = collectLastValue(underTest.onApply) underTest.onSliderProgressChanged(87) underTest.onSliderTouchUpProgressChanged(87) onApply()?.invoke() assertThat(onApply()).isNull() Loading Loading
src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt +12 −1 Original line number Diff line number Diff line Loading @@ -169,6 +169,17 @@ object ClockFloatingSheetBinder { viewModel.onSliderProgressChanged(value.roundToInt()) } } addOnSliderTouchListener( object : OnSliderTouchListener { override fun onStartTrackingTouch(slider: Slider) { // Do nothing intended } override fun onStopTrackingTouch(slider: Slider) { viewModel.onSliderTouchUpProgressChanged(slider.value.roundToInt()) } } ) } val isClockColorActive = { isFloatingSheetActive() && viewModel.selectedTab.value == Tab.COLOR Loading Loading @@ -410,7 +421,7 @@ object ClockFloatingSheetBinder { } launch { viewModel.previewingSliderProgress.collect { progress -> viewModel.previewingColorSliderProgress.collect { progress -> clockColorSlider.value = progress.toFloat() } } Loading
src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt +95 −63 Original line number Diff line number Diff line Loading @@ -149,6 +149,7 @@ constructor( combine(overridingClock, selectedClock) { overridingClock, selectedClock -> overridingClock != null && overridingClock.clockId != selectedClock.clockId } .distinctUntilChanged() val _previewingClockColorOptionIndex = MutableStateFlow<Int>(0) val previewingClockColorOptionIndex = _previewingClockColorOptionIndex.asStateFlow() Loading Loading @@ -227,8 +228,10 @@ constructor( overridingClockPresetIndexedStyle, selectedClockPresetIndexedStyle -> overridingClockPresetIndexedStyle != null && (overridingClockPresetIndexedStyle.style != selectedClockPresetIndexedStyle?.style) (overridingClockPresetIndexedStyle.style != selectedClockPresetIndexedStyle?.style) } .distinctUntilChanged() private val groups: Flow<List<AxisPresetConfig.Group>?> = previewingClock.map { it.axisPresetConfig?.groups } Loading Loading @@ -329,6 +332,7 @@ constructor( selectedClockSize -> overridingClockSize != null && overridingClockSize != selectedClockSize } .distinctUntilChanged() val previewingClockSize = combine(overridingClockSize, clockPickerInteractor.selectedClockSize) { overridingClockSize, Loading @@ -353,6 +357,7 @@ constructor( selectedColorId -> overridingClockColorId != null && (overridingClockColorId != selectedColorId) } .distinctUntilChanged() private val previewingClockColorId = combine(overridingClockColorId, clockPickerInteractor.selectedColorId) { overridingClockColorId, Loading @@ -360,19 +365,31 @@ constructor( overridingClockColorId ?: selectedColorId ?: DEFAULT_CLOCK_COLOR_ID } // Clock color slider progress. Range is 0 - 100. private val overridingSliderProgress = MutableStateFlow<Int?>(null) // Clock color slider progress. Range is 0 - 100. It update as frequently as user drags the // slider. private val overridingColorSliderProgress = MutableStateFlow<Int?>(null) // Clock color slider progress. Range is 0 - 100. It only update as user touches up the slider. private val overridingColorSliderTouchUpProgress = MutableStateFlow<Int?>(null) private val isSliderProgressEdited = combine(overridingSliderProgress, clockPickerInteractor.colorToneProgress) { overridingSliderProgress, combine(overridingColorSliderTouchUpProgress, clockPickerInteractor.colorToneProgress) { overridingColorSliderTouchUpProgress, colorToneProgress -> overridingSliderProgress != null && (overridingSliderProgress != colorToneProgress) overridingColorSliderTouchUpProgress != null && (overridingColorSliderTouchUpProgress != colorToneProgress) } val previewingSliderProgress: Flow<Int> = combine(overridingSliderProgress, clockPickerInteractor.colorToneProgress) { overridingSliderProgress, .distinctUntilChanged() // Note that this flow emits as frequently as user drags the slider. val previewingColorSliderProgress: Flow<Int> = combine(overridingColorSliderProgress, clockPickerInteractor.colorToneProgress) { overridingColorSliderProgress, colorToneProgress -> overridingColorSliderProgress ?: colorToneProgress } private val previewingColorSliderTouchUpProgress: Flow<Int> = combine(overridingColorSliderTouchUpProgress, clockPickerInteractor.colorToneProgress) { overridingColorSliderTouchUpProgress, colorToneProgress -> overridingSliderProgress ?: colorToneProgress overridingColorSliderTouchUpProgress ?: colorToneProgress } val isSliderEnabled: Flow<Boolean> = combine(previewingClock, previewingClockColorId) { clock, clockColorId -> Loading @@ -381,11 +398,19 @@ constructor( .distinctUntilChanged() fun onSliderProgressChanged(progress: Int) { overridingSliderProgress.value = progress overridingColorSliderProgress.value = progress } fun onSliderTouchUpProgressChanged(progress: Int) { overridingColorSliderProgress.value = progress overridingColorSliderTouchUpProgress.value = progress } // Note that this flow can emit as frequently as user drags the color slider. val previewingSeedColor: Flow<Int?> = combine(previewingClockColorId, previewingSliderProgress) { clockColorId, sliderProgress -> combine(previewingClockColorId, previewingColorSliderProgress) { clockColorId, colorSliderProgress -> val clockColorViewModel = if (clockColorId == DEFAULT_CLOCK_COLOR_ID) null else colorMap[clockColorId] if (clockColorViewModel == null) { Loading @@ -393,7 +418,7 @@ constructor( } else { blendColorWithTone( color = clockColorViewModel.color, colorTone = clockColorViewModel.getColorTone(sliderProgress), colorTone = clockColorViewModel.getColorTone(colorSliderProgress), ) } } Loading Loading @@ -442,7 +467,9 @@ constructor( { _previewingClockColorOptionIndex.value = index overridingClockColorId.value = colorModel.colorId overridingSliderProgress.value = overridingColorSliderProgress.value = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS overridingColorSliderTouchUpProgress.value = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS } } Loading Loading @@ -494,7 +521,9 @@ constructor( } else { { overridingClockColorId.value = DEFAULT_CLOCK_COLOR_ID overridingSliderProgress.value = overridingColorSliderProgress.value = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS overridingColorSliderTouchUpProgress.value = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS } } Loading @@ -502,41 +531,37 @@ constructor( ) } private val isEdited = val onApply: Flow<(suspend () -> Unit)?> = combine( isClockEdited, isClockAxisStyleEdited, isClockSizeEdited, isClockColorIdEdited, isSliderProgressEdited, ) { isClockEdited, isClockAxisStyleEdited, isClockSizeEdited, isClockColorEdited, isSliderProgressEdited -> isClockEdited || isClockAxisStyleEdited || isClockSizeEdited || isClockColorEdited || isSliderProgressEdited } val onApply: Flow<(suspend () -> Unit)?> = combine( isEdited, previewingClock, previewingClockSize, previewingClockColorId, previewingSliderProgress, previewingColorSliderTouchUpProgress, previewingClockPresetIndexedStyle, ) { array -> val isEdited: Boolean = array[0] as Boolean val clock: ClockMetadataModel = array[1] as ClockMetadataModel val size: ClockSize = array[2] as ClockSize val previewingColorId: String = array[3] as String val previewProgress: Int = array[4] as Int val isClockEdited: Boolean = array[0] as Boolean val isClockAxisStyleEdited: Boolean = array[1] as Boolean val isClockSizeEdited: Boolean = array[2] as Boolean val isClockColorIdEdited: Boolean = array[3] as Boolean val isSliderProgressEdited: Boolean = array[4] as Boolean val clock: ClockMetadataModel = array[5] as ClockMetadataModel val size: ClockSize = array[6] as ClockSize val previewingColorId: String = array[7] as String val previewingColorSliderProgress: Int = array[8] as Int val clockAxisStyle: ClockAxisStyle = (array[5] as? IndexedStyle)?.style ?: ClockAxisStyle() (array[9] as? IndexedStyle)?.style ?: ClockAxisStyle() val isEdited = isClockEdited || isClockAxisStyleEdited || isClockSizeEdited || isClockColorIdEdited || isSliderProgressEdited if (isEdited) { { val clockId: String = clock.clockId Loading @@ -544,26 +569,32 @@ constructor( colorMap[previewingColorId]?.let { blendColorWithTone( color = it.color, colorTone = it.getColorTone(previewProgress), colorTone = it.getColorTone(previewingColorSliderProgress), ) } clockPickerInteractor.applyClock( clockId = clockId, size = size, selectedColorId = previewingColorId, colorToneProgress = previewProgress, colorToneProgress = previewingColorSliderProgress, seedColor = seedColor, axisSettings = clockAxisStyle, ) logger.logClockApplied(clockId) if (isClockEdited) { logger.logClockApplied(clockId = clockId) } if (isClockSizeEdited) { logger.logClockSizeApplied( when (size) { ClockSize.SMALL -> StyleEnums.CLOCK_SIZE_SMALL ClockSize.DYNAMIC -> StyleEnums.CLOCK_SIZE_DYNAMIC } ) } if (isClockColorIdEdited) { seedColor?.let { logger.logClockColorApplied(it) } } } } else { null } Loading @@ -573,7 +604,8 @@ constructor( overridingClock.value = null overridingClockSize.value = null overridingClockColorId.value = null overridingSliderProgress.value = null overridingColorSliderProgress.value = null overridingColorSliderTouchUpProgress.value = null overridingClockPresetIndexedStyle.value = null _selectedTab.value = Tab.STYLE _showClockFacePresetGroupIndexUpdateToast.value = null Loading
tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt +14 −3 Original line number Diff line number Diff line Loading @@ -402,7 +402,7 @@ class ClockPickerViewModelTest { //// Clock color @Test fun sliderProgress_whenOnSliderProgressChanged() = runTest { val sliderProgress = collectLastValue(underTest.previewingSliderProgress) val sliderProgress = collectLastValue(underTest.previewingColorSliderProgress) assertThat(sliderProgress()).isEqualTo(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS) Loading @@ -411,6 +411,17 @@ class ClockPickerViewModelTest { assertThat(sliderProgress()).isEqualTo(87) } @Test fun sliderTouchUpProgress_whenOnSliderProgressChanged() = runTest { val sliderProgress = collectLastValue(underTest.previewingColorSliderProgress) assertThat(sliderProgress()).isEqualTo(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS) underTest.onSliderTouchUpProgressChanged(87) assertThat(sliderProgress()).isEqualTo(87) } @Test fun isSliderEnabledShouldBeTrue_whenTheClockIsReactiveToToneAndSolidColor() = runTest { val clockStyleOptions = collectLastValue(underTest.clockStyleOptions) Loading Loading @@ -608,7 +619,7 @@ class ClockPickerViewModelTest { fun apply_notNullWhenSliderProgressChanged() = runTest { val onApply = collectLastValue(underTest.onApply) underTest.onSliderProgressChanged(87) underTest.onSliderTouchUpProgressChanged(87) assertThat(onApply()).isNotNull() } Loading @@ -617,7 +628,7 @@ class ClockPickerViewModelTest { fun apply_nullAfterApplyingSliderProgress() = runTest { val onApply = collectLastValue(underTest.onApply) underTest.onSliderProgressChanged(87) underTest.onSliderTouchUpProgressChanged(87) onApply()?.invoke() assertThat(onApply()).isNull() Loading