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

Commit efd9a4f1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix clock can be gone in wallpaper picker multi crop preview by...

Merge "Fix clock can be gone in wallpaper picker multi crop preview by creating a new clock instance for each previewRenderer" into main
parents b617fc57 395090de
Loading
Loading
Loading
Loading
+27 −28
Original line number Diff line number Diff line
@@ -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,20 +127,16 @@ 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 (
    private fun getClockSize(): SettingsClockSize {
        return if (
            secureSettings.getIntForUser(
                Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
                1,
@@ -149,4 +149,3 @@ constructor(
        }
    }
}
}
+2 −3
Original line number Diff line number Diff line
@@ -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

+26 −48
Original line number Diff line number Diff line
@@ -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,51 +69,37 @@ 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
                        }
                        .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)
                    var lastClock: ClockController? = null
                    viewModel.previewClock.collect { currentClock ->
                        lastClock?.let { clock ->
                            (clock.largeClock.layout.views + clock.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)
                            (currentClock.largeClock.layout.views +
                                    currentClock.smallClock.layout.views)
                                .forEach { it.alpha = KeyguardPreviewRenderer.DIM_ALPHA }
                        }
                            clockPreview.largeClock.layout.views.forEach {
                        currentClock.largeClock.layout.views.forEach {
                            (it.parent as? ViewGroup)?.removeView(it)
                            rootView.addView(it)
                        }

                            clockPreview.smallClock.layout.views.forEach {
                        currentClock.smallClock.layout.views.forEach {
                            (it.parent as? ViewGroup)?.removeView(it)
                            rootView.addView(it)
                        }
                            applyPreviewConstraints(context, rootView, viewModel)
                        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)
    }
+0 −2
Original line number Diff line number Diff line
@@ -411,10 +411,8 @@ constructor(
            if (MigrateClocksToBlueprint.isEnabled) {
                KeyguardPreviewClockViewBinder.bind(
                    context,
                    displayId,
                    keyguardRootView,
                    clockViewModel,
                    clockController,
                    ::updateClockAppearance
                )
            } else {
+2 −12
Original line number Diff line number Diff line
@@ -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
}
Loading