Merge "[2/n] Let picker refresh preview when user selects a different grid" into udc-qpr-dev
diff --git a/res/layout/single_clock_view.xml b/res/layout/single_clock_view.xml
deleted file mode 100644
index ffc6039..0000000
--- a/res/layout/single_clock_view.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- 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.
--->
-<com.android.wallpaper.picker.FixedWidthDisplayRatioFrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/screen_preview_width"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:clipChildren="false">
- <com.android.customization.picker.clock.ui.view.ClockHostView
- android:id="@+id/single_clock_host_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center" />
-</com.android.wallpaper.picker.FixedWidthDisplayRatioFrameLayout>
\ No newline at end of file
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
index 89fac89..7880d82 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
@@ -16,8 +16,6 @@
package com.android.customization.picker.clock.ui.binder
import android.content.Context
-import android.view.ViewGroup
-import android.widget.FrameLayout
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
@@ -27,7 +25,6 @@
import com.android.customization.picker.clock.ui.view.ClockCarouselView
import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
-import com.android.wallpaper.R
import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewClickView
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
@@ -38,7 +35,6 @@
fun bind(
context: Context,
carouselView: ClockCarouselView,
- singleClockView: ViewGroup,
screenPreviewClickView: ScreenPreviewClickView,
viewModel: ClockCarouselViewModel,
clockViewFactory: ClockViewFactory,
@@ -46,6 +42,7 @@
isTwoPaneAndSmallWidth: Boolean,
) {
carouselView.setClockViewFactory(clockViewFactory)
+ carouselView.isVisible = true
clockViewFactory.updateRegionDarkness()
val carouselAccessibilityDelegate =
CarouselAccessibilityDelegate(
@@ -61,12 +58,8 @@
)
screenPreviewClickView.accessibilityDelegate = carouselAccessibilityDelegate
- val singleClockHostView =
- singleClockView.requireViewById<FrameLayout>(R.id.single_clock_host_view)
lifecycleOwner.lifecycleScope.launch {
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
- launch { viewModel.isCarouselVisible.collect { carouselView.isVisible = it } }
-
launch {
combine(viewModel.selectedClockSize, viewModel.allClocks, ::Pair).collect {
(size, allClocks) ->
@@ -98,21 +91,6 @@
launch {
viewModel.seedColor.collect { clockViewFactory.updateColorForAllClocks(it) }
}
-
- launch {
- viewModel.isSingleClockViewVisible.collect { singleClockView.isVisible = it }
- }
-
- launch {
- viewModel.clockId.collect { clockId ->
- singleClockHostView.removeAllViews()
- val clockView = clockViewFactory.getLargeView(clockId)
- // The clock view might still be attached to an existing parent. Detach
- // before adding to another parent.
- (clockView.parent as? ViewGroup)?.removeView(clockView)
- singleClockHostView.addView(clockView)
- }
- }
}
}
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
index aa6cc91..2d18ab3 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -114,6 +114,7 @@
}
adapter = ClockCarouselAdapter(clockSize, clocks, clockViewFactory, onClockSelected)
+ carousel.isInfinite = clocks.size >= MIN_CLOCKS_TO_ENABLE_INFINITE_CAROUSEL
carousel.setAdapter(adapter)
val indexOfSelectedClock =
clocks
@@ -470,6 +471,8 @@
}
companion object {
+ // The carousel needs to have at least 5 different clock faces to be infinite
+ const val MIN_CLOCKS_TO_ENABLE_INFINITE_CAROUSEL = 5
const val CLOCK_CAROUSEL_VIEW_SCALE = 0.5f
val itemViewIds =
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 7922054..b2dfa61 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
@@ -27,7 +27,6 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
@@ -39,8 +38,7 @@
* Clock carousel view model that provides data for the carousel of clock previews. When there is
* only one item, we should show a single clock preview instead of a carousel.
*/
-class ClockCarouselViewModel
-constructor(
+class ClockCarouselViewModel(
private val interactor: ClockPickerInteractor,
private val backgroundDispatcher: CoroutineDispatcher,
) : ViewModel() {
@@ -58,8 +56,6 @@
val seedColor: Flow<Int?> = interactor.seedColor
- val isCarouselVisible: Flow<Boolean> = allClocks.map { it.size > 1 }.distinctUntilChanged()
-
@OptIn(ExperimentalCoroutinesApi::class)
val selectedIndex: Flow<Int> =
allClocks
@@ -77,15 +73,6 @@
}
.mapNotNull { it }
- // Handle the case when there is only one clock in the carousel
- val isSingleClockViewVisible: Flow<Boolean> =
- allClocks.map { it.size == 1 }.distinctUntilChanged()
-
- val clockId: Flow<String> =
- allClocks
- .map { allClockIds -> if (allClockIds.size == 1) allClockIds[0].clockId else null }
- .mapNotNull { it }
-
private var setSelectedClockJob: Job? = null
fun setSelectedClock(clockId: String) {
setSelectedClockJob?.cancel()
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
index fa87029..2174ba7 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -23,7 +23,6 @@
import android.view.TouchDelegate
import android.view.View
import android.view.View.OnAttachStateChangeListener
-import android.view.ViewGroup
import android.view.ViewStub
import androidx.activity.ComponentActivity
import androidx.constraintlayout.helper.widget.Carousel
@@ -156,12 +155,6 @@
guidelineEnd.layoutParams = layoutParams
}
- // TODO (b/270716937) We should handle the single clock case in the clock carousel
- // itself
- val singleClockViewStub: ViewStub = view.requireViewById(R.id.single_clock_view_stub)
- singleClockViewStub.layoutResource = R.layout.single_clock_view
- val singleClockView = singleClockViewStub.inflate() as ViewGroup
-
/**
* Only bind after [Carousel.onAttachedToWindow]. This is to avoid the race condition
* that the flow emits before attached to window where [Carousel.mMotionLayout] is still
@@ -177,7 +170,6 @@
ClockCarouselViewBinder.bind(
context = context,
carouselView = carouselView,
- singleClockView = singleClockView,
screenPreviewClickView = screenPreviewClickView,
viewModel = viewModel,
clockViewFactory = clockViewFactory,
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
index 1b1eb9a..ca6f8c7 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
@@ -88,38 +88,6 @@
assertThat(observedSelectedIndex()).isEqualTo(2)
}
- @Test
- fun multipleClockCase() = runTest {
- underTest =
- ClockCarouselViewModel(
- getClockPickerInteractor(repositoryWithMultipleClocks),
- testDispatcher
- )
- val observedIsCarouselVisible = collectLastValue(underTest.isCarouselVisible)
- val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible)
-
- advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-
- assertThat(observedIsCarouselVisible()).isTrue()
- assertThat(observedIsSingleClockViewVisible()).isFalse()
- }
-
- @Test
- fun singleClockCase() = runTest {
- underTest =
- ClockCarouselViewModel(
- getClockPickerInteractor(repositoryWithSingleClock),
- testDispatcher
- )
- val observedIsCarouselVisible = collectLastValue(underTest.isCarouselVisible)
- val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible)
-
- advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-
- assertThat(observedIsCarouselVisible()).isFalse()
- assertThat(observedIsSingleClockViewVisible()).isTrue()
- }
-
private fun getClockPickerInteractor(repository: ClockPickerRepository): ClockPickerInteractor {
return ClockPickerInteractor(
repository = repository,