Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83dc7747 authored by George Lin's avatar George Lin Committed by Android (Google) Code Review
Browse files

Merge changes from topic "clock-carousel-view-model" into udc-dev

* changes:
  Make clock carousel extend ViewModel
  Fix race condition for clock carousel
parents 643d049e 71cc848a
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -63,7 +63,9 @@ interface CustomizationInjector : Injector {
        wallpaperColorsViewModel: WallpaperColorsViewModel,
    ): ColorPickerViewModel.Factory

    fun getClockCarouselViewModel(context: Context): ClockCarouselViewModel
    fun getClockCarouselViewModelFactory(
        interactor: ClockPickerInteractor,
    ): ClockCarouselViewModel.Factory

    fun getClockViewFactory(activity: Activity): ClockViewFactory

+17 −6
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import androidx.activity.ComponentActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.get
import com.android.customization.model.color.ColorCustomizationManager
import com.android.customization.model.color.ColorOptionsProvider
import com.android.customization.model.grid.GridOptionsManager
@@ -102,7 +103,7 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject
    private var clockRegistry: ClockRegistry? = null
    private var clockPickerInteractor: ClockPickerInteractor? = null
    private var clockSectionViewModel: ClockSectionViewModel? = null
    private var clockCarouselViewModel: ClockCarouselViewModel? = null
    private var clockCarouselViewModelFactory: ClockCarouselViewModel.Factory? = null
    private var clockViewFactory: ClockViewFactory? = null
    private var notificationsInteractor: NotificationsInteractor? = null
    private var notificationSectionViewModelFactory: NotificationSectionViewModel.Factory? = null
@@ -119,6 +120,14 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject
    private var gridScreenViewModelFactory: GridScreenViewModel.Factory? = null

    override fun getCustomizationSections(activity: ComponentActivity): CustomizationSections {
        val clockCarouselViewModel =
            ViewModelProvider(
                    activity,
                    getClockCarouselViewModelFactory(
                        getClockPickerInteractor(activity.applicationContext),
                    ),
                )
                .get() as ClockCarouselViewModel
        return customizationSections
            ?: DefaultCustomizationSections(
                    getColorPickerViewModelFactory(
@@ -131,7 +140,7 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject
                        interactor = getNotificationsInteractor(activity),
                    ),
                    getFlags(),
                    getClockCarouselViewModel(activity),
                    clockCarouselViewModel,
                    getClockViewFactory(activity),
                    getDarkModeSnapshotRestorer(activity),
                    getThemedIconSnapshotRestorer(activity),
@@ -346,10 +355,12 @@ open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInject
            }
    }

    override fun getClockCarouselViewModel(context: Context): ClockCarouselViewModel {
        return clockCarouselViewModel
            ?: ClockCarouselViewModel(getClockPickerInteractor(context)).also {
                clockCarouselViewModel = it
    override fun getClockCarouselViewModelFactory(
        interactor: ClockPickerInteractor,
    ): ClockCarouselViewModel.Factory {
        return clockCarouselViewModelFactory
            ?: ClockCarouselViewModel.Factory(interactor).also {
                clockCarouselViewModelFactory = it
            }
    }

+12 −8
Original line number Diff line number Diff line
@@ -47,16 +47,20 @@ object ClockCarouselViewBinder {

                launch {
                    viewModel.allClockIds.collect { allClockIds ->
                        if (allClockIds.size > 1) {
                            carouselView.setUpClockCarouselView(
                                clockIds = allClockIds,
                                onGetClockController = { clockId ->
                                    clockViewFactory.getController(clockId)
                                },
                            onClockSelected = { clockId -> viewModel.setSelectedClock(clockId) },
                                onClockSelected = { clockId ->
                                    viewModel.setSelectedClock(clockId)
                                },
                                getPreviewRatio = { clockViewFactory.getRatio() }
                            )
                        }
                    }
                }

                launch {
                    viewModel.allClockIds.collect {
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ class ClockCarouselView(

    var isCarouselInTransition = false

    private val carousel: Carousel
    val carousel: Carousel
    private val motionLayout: MotionLayout
    private lateinit var adapter: ClockCarouselAdapter
    private lateinit var scalingUpClockController: ClockController
+29 −8
Original line number Diff line number Diff line
@@ -15,30 +15,39 @@
 */
package com.android.customization.picker.clock.ui.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
import kotlinx.coroutines.ExperimentalCoroutinesApi
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
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.stateIn

/**
 * 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(
class ClockCarouselViewModel
constructor(
    private val interactor: ClockPickerInteractor,
) {
) : ViewModel() {
    @OptIn(ExperimentalCoroutinesApi::class)
    val allClockIds: Flow<List<String>> =
        interactor.allClocks.mapLatest { allClocks ->
    val allClockIds: StateFlow<List<String>> =
        interactor.allClocks
            .mapLatest { allClocks ->
                // Delay to avoid the case that the full list of clocks is not initiated.
                delay(CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
                allClocks.map { it.clockId }
            }
            .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())

    val seedColor: Flow<Int?> = interactor.seedColor

@@ -72,6 +81,18 @@ class ClockCarouselViewModel(
        interactor.setSelectedClock(clockId)
    }

    class Factory(
        private val interactor: ClockPickerInteractor,
    ) : ViewModelProvider.Factory {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            @Suppress("UNCHECKED_CAST")
            return ClockCarouselViewModel(
                interactor = interactor,
            )
                as T
        }
    }

    companion object {
        const val CLOCKS_EVENT_UPDATE_DELAY_MILLIS: Long = 100
    }
Loading