diff options
6 files changed, 60 insertions, 102 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt index 7a56554be1d2..3f4d3a8544d0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.data.repository import android.os.UserHandle import android.provider.Settings -import androidx.annotation.VisibleForTesting import com.android.keyguard.ClockEventController import com.android.keyguard.KeyguardClockSwitch.ClockSize import com.android.keyguard.KeyguardClockSwitch.LARGE @@ -52,14 +51,14 @@ interface KeyguardClockRepository { val clockSize: StateFlow<Int> /** clock size selected in picker, DYNAMIC or SMALL */ - val selectedClockSize: Flow<SettingsClockSize> + val selectedClockSize: StateFlow<SettingsClockSize> /** clock id, selected from clock carousel in wallpaper picker */ val currentClockId: Flow<ClockId> val currentClock: StateFlow<ClockController?> - val previewClockPair: StateFlow<Pair<ClockController, ClockController>> + val previewClock: Flow<ClockController> val clockEventController: ClockEventController fun setClockSize(@ClockSize size: Int) @@ -84,14 +83,19 @@ constructor( _clockSize.value = size } - override val selectedClockSize: Flow<SettingsClockSize> = + override val selectedClockSize: StateFlow<SettingsClockSize> = secureSettings .observerFlow( names = arrayOf(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK), userId = UserHandle.USER_SYSTEM, ) .onStart { emit(Unit) } // Forces an initial update. - .map { getClockSize() } + .map { withContext(backgroundDispatcher) { getClockSize() } } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = getClockSize() + ) override val currentClockId: Flow<ClockId> = callbackFlow { @@ -123,30 +127,25 @@ constructor( initialValue = clockRegistry.createCurrentClock() ) - override val previewClockPair: StateFlow<Pair<ClockController, ClockController>> = - currentClockId - .map { Pair(clockRegistry.createCurrentClock(), clockRegistry.createCurrentClock()) } - .stateIn( - scope = applicationScope, - started = SharingStarted.WhileSubscribed(), - initialValue = - Pair(clockRegistry.createCurrentClock(), clockRegistry.createCurrentClock()) - ) + override val previewClock: Flow<ClockController> = + currentClockId.map { + // We should create a new instance for each collect call + // cause in preview, the same clock will be attached to different view + // at the same time + clockRegistry.createCurrentClock() + } - @VisibleForTesting - suspend fun getClockSize(): SettingsClockSize { - return withContext(backgroundDispatcher) { - if ( - secureSettings.getIntForUser( - Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, - 1, - UserHandle.USER_CURRENT - ) == 1 - ) { - SettingsClockSize.DYNAMIC - } else { - SettingsClockSize.SMALL - } + private fun getClockSize(): SettingsClockSize { + return if ( + secureSettings.getIntForUser( + Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, + 1, + UserHandle.USER_CURRENT + ) == 1 + ) { + SettingsClockSize.DYNAMIC + } else { + SettingsClockSize.SMALL } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt index 2cf91563b3e4..d492135bd482 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt @@ -38,14 +38,13 @@ constructor( private val keyguardClockRepository: KeyguardClockRepository, ) { - val selectedClockSize: Flow<SettingsClockSize> = keyguardClockRepository.selectedClockSize + val selectedClockSize: StateFlow<SettingsClockSize> = keyguardClockRepository.selectedClockSize val currentClockId: Flow<ClockId> = keyguardClockRepository.currentClockId val currentClock: StateFlow<ClockController?> = keyguardClockRepository.currentClock - val previewClockPair: StateFlow<Pair<ClockController, ClockController>> = - keyguardClockRepository.previewClockPair + val previewClock: Flow<ClockController> = keyguardClockRepository.previewClock var clock: ClockController? by keyguardClockRepository.clockEventController::clock diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt index 46c354a45c92..d9f12c34c4f1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt @@ -32,7 +32,6 @@ import androidx.constraintlayout.widget.ConstraintSet.TOP import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.keyguard.ClockEventController import com.android.systemui.customization.R as customizationR import com.android.systemui.keyguard.shared.model.SettingsClockSize import com.android.systemui.keyguard.ui.preview.KeyguardPreviewRenderer @@ -44,12 +43,10 @@ import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.res.R import com.android.systemui.util.Utils import kotlin.reflect.KSuspendFunction1 -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch /** Binder for the small clock view, large clock view. */ object KeyguardPreviewClockViewBinder { - @JvmStatic fun bind( largeClockHostView: View, @@ -72,52 +69,38 @@ object KeyguardPreviewClockViewBinder { @JvmStatic fun bind( context: Context, - displayId: Int, rootView: ConstraintLayout, viewModel: KeyguardPreviewClockViewModel, - clockEventController: ClockEventController, updateClockAppearance: KSuspendFunction1<ClockController, Unit>, ) { - // TODO(b/327668072): When this function is called multiple times, the clock view can be - // gone due to a race condition on removeView and addView. rootView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { launch { - combine(viewModel.selectedClockSize, viewModel.previewClockPair) { _, clock -> - clock + var lastClock: ClockController? = null + viewModel.previewClock.collect { currentClock -> + lastClock?.let { clock -> + (clock.largeClock.layout.views + clock.smallClock.layout.views) + .forEach { rootView.removeView(it) } } - .collect { previewClockPair -> - viewModel.lastClockPair?.let { clockPair -> - (clockPair.first.largeClock.layout.views + - clockPair.first.smallClock.layout.views) - .forEach { rootView.removeView(it) } - (clockPair.second.largeClock.layout.views + - clockPair.second.smallClock.layout.views) - .forEach { rootView.removeView(it) } - } - viewModel.lastClockPair = previewClockPair - val clockPreview = - if (displayId == 0) previewClockPair.first - else previewClockPair.second - clockEventController.clock = clockPreview - updateClockAppearance(clockPreview) + lastClock = currentClock + updateClockAppearance(currentClock) - if (viewModel.shouldHighlightSelectedAffordance) { - (clockPreview.largeClock.layout.views + - clockPreview.smallClock.layout.views) - .forEach { it.alpha = KeyguardPreviewRenderer.DIM_ALPHA } - } - clockPreview.largeClock.layout.views.forEach { - (it.parent as? ViewGroup)?.removeView(it) - rootView.addView(it) - } + if (viewModel.shouldHighlightSelectedAffordance) { + (currentClock.largeClock.layout.views + + currentClock.smallClock.layout.views) + .forEach { it.alpha = KeyguardPreviewRenderer.DIM_ALPHA } + } + currentClock.largeClock.layout.views.forEach { + (it.parent as? ViewGroup)?.removeView(it) + rootView.addView(it) + } - clockPreview.smallClock.layout.views.forEach { - (it.parent as? ViewGroup)?.removeView(it) - rootView.addView(it) - } - applyPreviewConstraints(context, rootView, viewModel) + currentClock.smallClock.layout.views.forEach { + (it.parent as? ViewGroup)?.removeView(it) + rootView.addView(it) } + applyPreviewConstraints(context, rootView, currentClock, viewModel) + } } } } @@ -170,15 +153,13 @@ object KeyguardPreviewClockViewBinder { private fun applyPreviewConstraints( context: Context, rootView: ConstraintLayout, + previewClock: ClockController, viewModel: KeyguardPreviewClockViewModel ) { val cs = ConstraintSet().apply { clone(rootView) } - val clockPair = viewModel.previewClockPair.value applyClockDefaultConstraints(context, cs) - clockPair.first.largeClock.layout.applyPreviewConstraints(cs) - clockPair.first.smallClock.layout.applyPreviewConstraints(cs) - clockPair.second.largeClock.layout.applyPreviewConstraints(cs) - clockPair.second.smallClock.layout.applyPreviewConstraints(cs) + previewClock.largeClock.layout.applyPreviewConstraints(cs) + previewClock.smallClock.layout.applyPreviewConstraints(cs) // When selectedClockSize is the initial value, make both clocks invisible to avoid // flickering @@ -194,12 +175,9 @@ object KeyguardPreviewClockViewBinder { SettingsClockSize.SMALL -> VISIBLE null -> INVISIBLE } - cs.apply { - setVisibility(clockPair.first.largeClock.layout.views, largeClockVisibility) - setVisibility(clockPair.first.smallClock.layout.views, smallClockVisibility) - setVisibility(clockPair.second.largeClock.layout.views, largeClockVisibility) - setVisibility(clockPair.second.smallClock.layout.views, smallClockVisibility) + setVisibility(previewClock.largeClock.layout.views, largeClockVisibility) + setVisibility(previewClock.smallClock.layout.views, smallClockVisibility) } cs.applyTo(rootView) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt index 6f3919266e93..14ab17f9641b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt @@ -411,10 +411,8 @@ constructor( if (MigrateClocksToBlueprint.isEnabled) { KeyguardPreviewClockViewBinder.bind( context, - displayId, keyguardRootView, clockViewModel, - clockController, ::updateClockAppearance ) } else { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt index b9ff25926f02..4f2c6f576904 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt @@ -24,10 +24,8 @@ import com.android.systemui.plugins.clocks.ClockController import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn /** View model for the small clock view, large clock view. */ class KeyguardPreviewClockViewModel @@ -45,15 +43,7 @@ constructor( val isSmallClockVisible: Flow<Boolean> = interactor.selectedClockSize.map { it == SettingsClockSize.SMALL } - var lastClockPair: Pair<ClockController, ClockController>? = null + val previewClock: Flow<ClockController> = interactor.previewClock - val previewClockPair: StateFlow<Pair<ClockController, ClockController>> = - interactor.previewClockPair - - val selectedClockSize: StateFlow<SettingsClockSize?> = - interactor.selectedClockSize.stateIn( - scope = applicationScope, - started = SharingStarted.WhileSubscribed(), - initialValue = null - ) + val selectedClockSize: StateFlow<SettingsClockSize?> = interactor.selectedClockSize } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt index 5b642ea645f5..eba5a11cecdb 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt @@ -45,15 +45,9 @@ class FakeKeyguardClockRepository @Inject constructor() : KeyguardClockRepositor private val _currentClock: MutableStateFlow<ClockController?> = MutableStateFlow(null) override val currentClock = _currentClock - private val _previewClockPair = - MutableStateFlow( - Pair( - Mockito.mock(ClockController::class.java), - Mockito.mock(ClockController::class.java) - ) - ) - override val previewClockPair: StateFlow<Pair<ClockController, ClockController>> = - _previewClockPair + private val _previewClock = MutableStateFlow(Mockito.mock(ClockController::class.java)) + override val previewClock: Flow<ClockController> + get() = _previewClock override val clockEventController: ClockEventController get() = mock() |