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

Commit fe843f87 authored by Matt Pietal's avatar Matt Pietal
Browse files

Restore clock doze transition

I had recently updated the doze path to listen to any change
to/from AOD. This works for other code, but not clocks. Put
the prior code back.

(Apologies, ktfmt changed way more code than I did)

Fixes: 327910913
Test: atest ClockEventControllerTest
Flag: ACONFIG com.android.systemui.migrate_clocks_to_blueprint
TEAMFOOD

Change-Id: I7315f545a75def7a727b8ecd16824f04e0d6ac31
parent db2035d9
Loading
Loading
Loading
Loading
+141 −105
Original line number Diff line number Diff line
@@ -15,8 +15,6 @@
 */
package com.android.keyguard

import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -43,14 +41,16 @@ import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags.REGION_SAMPLING
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.log.core.Logger
import com.android.systemui.plugins.clocks.AlarmData
import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockFaceController
import com.android.systemui.plugins.clocks.ClockMessageBuffers
import com.android.systemui.plugins.clocks.ClockTickRate
import com.android.systemui.plugins.clocks.AlarmData
import com.android.systemui.plugins.clocks.WeatherData
import com.android.systemui.plugins.clocks.ZenData
import com.android.systemui.plugins.clocks.ZenData.ZenMode
@@ -61,16 +61,18 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ZenModeController
import com.android.systemui.util.concurrency.DelayableExecutor
import java.util.Locale
import java.util.TimeZone
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.launch
import java.util.Locale
import java.util.TimeZone
import java.util.concurrent.Executor
import javax.inject.Inject

/**
 * Controller for a Clock provided by the registry and used on the keyguard. Instantiated by
@@ -93,11 +95,13 @@ constructor(
    private val featureFlags: FeatureFlagsClassic,
    private val zenModeController: ZenModeController,
) {
    var loggers = listOf(
    var loggers =
        listOf(
                clockBuffers.infraMessageBuffer,
                clockBuffers.smallClockMessageBuffer,
                clockBuffers.largeClockMessageBuffer
    ).map { Logger(it, TAG) }
            )
            .map { Logger(it, TAG) }

    var clock: ClockController? = null
        get() = field
@@ -108,11 +112,12 @@ constructor(
        }

    private fun disconnectClock(clock: ClockController?) {
        if (clock == null) { return; }
        if (clock == null) {
            return
        }
        smallClockOnAttachStateChangeListener?.let {
            clock.smallClock.view.removeOnAttachStateChangeListener(it)
            smallClockFrame?.viewTreeObserver
                    ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
            smallClockFrame?.viewTreeObserver?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
        }
        largeClockOnAttachStateChangeListener?.let {
            clock.largeClock.view.removeOnAttachStateChangeListener(it)
@@ -120,7 +125,9 @@ constructor(
    }

    private fun connectClock(clock: ClockController?) {
        if (clock == null) { return; }
        if (clock == null) {
            return
        }
        val clockStr = clock.toString()
        loggers.forEach { it.d({ "New Clock: $str1" }) { str1 = clockStr } }

@@ -129,23 +136,27 @@ constructor(
        if (!regionSamplingEnabled) {
            updateColors()
        } else {
            smallRegionSampler = createRegionSampler(
            smallRegionSampler =
                createRegionSampler(
                        clock.smallClock.view,
                        mainExecutor,
                        bgExecutor,
                        regionSamplingEnabled,
                        isLockscreen = true,
                        ::updateColors
            ).apply { startRegionSampler() }
                    )
                    .apply { startRegionSampler() }

            largeRegionSampler = createRegionSampler(
            largeRegionSampler =
                createRegionSampler(
                        clock.largeClock.view,
                        mainExecutor,
                        bgExecutor,
                        regionSamplingEnabled,
                        isLockscreen = true,
                        ::updateColors
            ).apply { startRegionSampler() }
                    )
                    .apply { startRegionSampler() }

            updateColors()
        }
@@ -158,19 +169,17 @@ constructor(
            }
            clock.events.onWeatherDataChanged(it)
        }
        zenData?.let {
            clock.events.onZenDataChanged(it)
        }
        alarmData?.let {
            clock.events.onAlarmDataChanged(it)
        }
        zenData?.let { clock.events.onZenDataChanged(it) }
        alarmData?.let { clock.events.onAlarmDataChanged(it) }

        smallClockOnAttachStateChangeListener = object : OnAttachStateChangeListener {
        smallClockOnAttachStateChangeListener =
            object : OnAttachStateChangeListener {
                var pastVisibility: Int? = null
                override fun onViewAttachedToWindow(view: View) {
                    clock.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
                    // Match the asing for view.parent's layout classes.
                smallClockFrame = (view.parent as ViewGroup)?.also { frame ->
                    smallClockFrame =
                        (view.parent as ViewGroup)?.also { frame ->
                            pastVisibility = frame.visibility
                            onGlobalLayoutListener = OnGlobalLayoutListener {
                                val currentVisibility = frame.visibility
@@ -189,13 +198,15 @@ constructor(
                }

                override fun onViewDetachedFromWindow(p0: View) {
                smallClockFrame?.viewTreeObserver
                    smallClockFrame
                        ?.viewTreeObserver
                        ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
                }
            }
        clock.smallClock.view.addOnAttachStateChangeListener(smallClockOnAttachStateChangeListener)

        largeClockOnAttachStateChangeListener = object : OnAttachStateChangeListener {
        largeClockOnAttachStateChangeListener =
            object : OnAttachStateChangeListener {
                override fun onViewAttachedToWindow(p0: View) {
                    clock.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
                }
@@ -263,7 +274,9 @@ constructor(
            bgExecutor,
            regionSamplingEnabled,
            isLockscreen,
        ) { updateColors() }
        ) {
            updateColors()
        }
    }

    var smallRegionSampler: RegionSampler? = null
@@ -364,7 +377,8 @@ constructor(
            }
        }

    private val zenModeCallback = object : ZenModeController.Callback {
    private val zenModeCallback =
        object : ZenModeController.Callback {
            override fun onZenChanged(zen: Int) {
                var mode = ZenMode.fromInt(zen)
                if (mode == null) {
@@ -372,25 +386,25 @@ constructor(
                    return
                }

            zenData = ZenData(
                zenData =
                    ZenData(
                            mode,
                            if (mode == ZenMode.OFF) SysuiR.string::dnd_is_off.name
                            else SysuiR.string::dnd_is_on.name
            ).also { data ->
                mainExecutor.execute {
                    clock?.run { events.onZenDataChanged(data) }
                }
                        )
                        .also { data ->
                            mainExecutor.execute { clock?.run { events.onZenDataChanged(data) } }
                        }
            }

            override fun onNextAlarmChanged() {
                val nextAlarmMillis = zenModeController.getNextAlarm()
            alarmData = AlarmData(
                alarmData =
                    AlarmData(
                            if (nextAlarmMillis > 0) nextAlarmMillis else null,
                            SysuiR.string::status_bar_alarm.name
            ).also { data ->
                clock?.run { events.onAlarmDataChanged(data) }
            }
                        )
                        .also { data -> clock?.run { events.onAlarmDataChanged(data) } }
            }
        }

@@ -413,6 +427,7 @@ constructor(
                    listenForDozing(this)
                    if (migrateClocksToBlueprint()) {
                        listenForDozeAmountTransition(this)
                        listenForAnyStateToAodTransition(this)
                    } else {
                        listenForDozeAmount(this)
                    }
@@ -444,11 +459,14 @@ constructor(
        largeRegionSampler?.stopRegionSampler()
        smallTimeListener?.stop()
        largeTimeListener?.stop()
        clock?.smallClock?.view
        clock
            ?.smallClock
            ?.view
            ?.removeOnAttachStateChangeListener(smallClockOnAttachStateChangeListener)
        smallClockFrame?.viewTreeObserver
                ?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
        clock?.largeClock?.view
        smallClockFrame?.viewTreeObserver?.removeOnGlobalLayoutListener(onGlobalLayoutListener)
        clock
            ?.largeClock
            ?.view
            ?.removeOnAttachStateChangeListener(largeClockOnAttachStateChangeListener)
    }

@@ -473,12 +491,10 @@ constructor(
        largeTimeListener = null

        clock?.let {
            smallTimeListener = TimeListener(it.smallClock, mainExecutor).apply {
                update(shouldTimeListenerRun)
            }
            largeTimeListener = TimeListener(it.largeClock, mainExecutor).apply {
                update(shouldTimeListenerRun)
            }
            smallTimeListener =
                TimeListener(it.smallClock, mainExecutor).apply { update(shouldTimeListenerRun) }
            largeTimeListener =
                TimeListener(it.largeClock, mainExecutor).apply { update(shouldTimeListenerRun) }
        }
    }

@@ -517,7 +533,27 @@ constructor(
    @VisibleForTesting
    internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job {
        return scope.launch {
            keyguardTransitionInteractor.dozeAmountTransition.collect { handleDoze(it.value) }
            merge(
                    keyguardTransitionInteractor.aodToLockscreenTransition.map { step ->
                        step.copy(value = 1f - step.value)
                    },
                    keyguardTransitionInteractor.lockscreenToAodTransition,
                )
                .collect { handleDoze(it.value) }
        }
    }

    /**
     * When keyguard is displayed again after being gone, the clock must be reset to full dozing.
     */
    @VisibleForTesting
    internal fun listenForAnyStateToAodTransition(scope: CoroutineScope): Job {
        return scope.launch {
            keyguardTransitionInteractor
                .transitionStepsToState(AOD)
                .filter { it.transitionState == TransitionState.STARTED }
                .filter { it.from != LOCKSCREEN }
                .collect { handleDoze(1f) }
        }
    }

+47 −2
Original line number Diff line number Diff line
@@ -21,8 +21,8 @@ import android.view.View
import android.view.ViewTreeObserver
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.Flags as AConfigFlags
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -319,7 +319,10 @@ class ClockEventControllerTest : SysuiTestCase() {
    fun listenForDozeAmountTransition_updatesClockDozeAmount() =
        runBlocking(IMMEDIATE) {
            val transitionStep = MutableStateFlow(TransitionStep())
            whenever(keyguardTransitionInteractor.dozeAmountTransition).thenReturn(transitionStep)
            whenever(keyguardTransitionInteractor.lockscreenToAodTransition)
                .thenReturn(transitionStep)
            whenever(keyguardTransitionInteractor.aodToLockscreenTransition)
                .thenReturn(transitionStep)

            val job = underTest.listenForDozeAmountTransition(this)
            transitionStep.value =
@@ -335,6 +338,48 @@ class ClockEventControllerTest : SysuiTestCase() {
            job.cancel()
        }

    @Test
    fun listenForTransitionToAodFromGone_updatesClockDozeAmountToOne() =
        runBlocking(IMMEDIATE) {
            val transitionStep = MutableStateFlow(TransitionStep())
            whenever(keyguardTransitionInteractor.transitionStepsToState(KeyguardState.AOD))
                .thenReturn(transitionStep)

            val job = underTest.listenForAnyStateToAodTransition(this)
            transitionStep.value =
                TransitionStep(
                    from = KeyguardState.GONE,
                    to = KeyguardState.AOD,
                    transitionState = TransitionState.STARTED,
                )
            yield()

            verify(animations, times(2)).doze(1f)

            job.cancel()
        }

    @Test
    fun listenForTransitionToAodFromLockscreen_neverUpdatesClockDozeAmount() =
        runBlocking(IMMEDIATE) {
            val transitionStep = MutableStateFlow(TransitionStep())
            whenever(keyguardTransitionInteractor.transitionStepsToState(KeyguardState.AOD))
                .thenReturn(transitionStep)

            val job = underTest.listenForAnyStateToAodTransition(this)
            transitionStep.value =
                TransitionStep(
                    from = KeyguardState.LOCKSCREEN,
                    to = KeyguardState.AOD,
                    transitionState = TransitionState.STARTED,
                )
            yield()

            verify(animations, never()).doze(1f)

            job.cancel()
        }

    @Test
    fun unregisterListeners_validate() =
        runBlocking(IMMEDIATE) {