summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Lin <giolin@google.com>2023-06-27 21:57:33 +0000
committerGeorge Lin <giolin@google.com>2023-08-07 20:14:06 +0000
commit32e846ff7035d5af926aeba31c848deb9ea46309 (patch)
tree22db2f63fe04aabcc23cabfed0ba1c9dbe4bf671
parentba08abf7a4af1f72eeeafbd7a1f50e59fd881bff (diff)
downloadThemePicker-32e846ff7035d5af926aeba31c848deb9ea46309.tar.gz
Remove single clock view
We can use the mInfinite flag in the carousel to handle single clock case. When clock faces are less than 5, we will force the clock carousel finite. Test: See screeshot in bug. Also made sure for clock faces >= 5, the Test: carousel is infinite again. Bug: 290848550 Bug: 287650278 Change-Id: I1f0d9810ee5b92efc9cfacdfe2c70c6627916628
-rw-r--r--res/layout/single_clock_view.xml27
-rw-r--r--src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt24
-rw-r--r--src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt3
-rw-r--r--src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt15
-rw-r--r--src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt8
-rw-r--r--tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt32
6 files changed, 5 insertions, 104 deletions
diff --git a/res/layout/single_clock_view.xml b/res/layout/single_clock_view.xml
deleted file mode 100644
index ffc60390..00000000
--- 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 89fac894..7880d821 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 androidx.lifecycle.repeatOnLifecycle
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 @@ object ClockCarouselViewBinder {
fun bind(
context: Context,
carouselView: ClockCarouselView,
- singleClockView: ViewGroup,
screenPreviewClickView: ScreenPreviewClickView,
viewModel: ClockCarouselViewModel,
clockViewFactory: ClockViewFactory,
@@ -46,6 +42,7 @@ object ClockCarouselViewBinder {
isTwoPaneAndSmallWidth: Boolean,
) {
carouselView.setClockViewFactory(clockViewFactory)
+ carouselView.isVisible = true
clockViewFactory.updateRegionDarkness()
val carouselAccessibilityDelegate =
CarouselAccessibilityDelegate(
@@ -61,12 +58,8 @@ object ClockCarouselViewBinder {
)
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 @@ object ClockCarouselViewBinder {
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 aa6cc916..2d18ab3c 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 @@ class ClockCarouselView(
}
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 @@ class ClockCarouselView(
}
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 79220545..b2dfa61c 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.delay
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 @@ import kotlinx.coroutines.launch
* 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 @@ constructor(
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 @@ constructor(
}
.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 fa870295..2174ba7e 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.graphics.Rect
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 @@ class PreviewWithClockCarouselSectionController(
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 @@ class PreviewWithClockCarouselSectionController(
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 1b1eb9a9..ca6f8c79 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 @@ class ClockCarouselViewModelTest {
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,