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

Commit b579f132 authored by Lucas Silva's avatar Lucas Silva Committed by Android (Google) Code Review
Browse files

Merge "Fix glanceable hub to/from aod transition" into main

parents 7290ef5f 9e7d0138
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -35,12 +35,20 @@ package com.android.systemui.keyguard.domain.interactor
import android.os.PowerManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
import com.android.systemui.common.data.repository.batteryRepository
import com.android.systemui.common.data.repository.fake
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.setCommunalV2Available
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
@@ -54,6 +62,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
@@ -62,6 +72,8 @@ import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.settings.fakeSettings
import com.google.common.truth.Truth
import junit.framework.Assert.assertEquals
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.advanceTimeBy
@@ -416,4 +428,25 @@ class FromAodTransitionInteractorTest : SysuiTestCase() {
            assertThat(transitionRepository)
                .startedTransition(from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN)
        }

    @Test
    @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
    fun testTransitionToGlanceableHub_onWakeUpFromAod() =
        kosmos.runTest {
            val user = setCommunalV2Available(true)
            fakeSettings.putIntForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1, user.id)
            batteryRepository.fake.setDevicePluggedIn(true)

            val currentScene by collectLastValue(communalSceneInteractor.currentScene)
            fakeCommunalSceneRepository.changeScene(CommunalScenes.Blank)

            // Communal is not showing
            Truth.assertThat(currentScene).isEqualTo(CommunalScenes.Blank)

            powerInteractor.setAwakeForTest()
            testScope.advanceTimeBy(100) // account for debouncing

            Truth.assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
            assertThat(transitionRepository).noTransitionsStarted()
        }
}
+16 −0
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@ import android.animation.ValueAnimator
import android.util.Log
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -54,6 +58,9 @@ constructor(
    keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
    val deviceEntryRepository: DeviceEntryRepository,
    private val wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor,
    private val communalSettingsInteractor: CommunalSettingsInteractor,
    private val communalSceneInteractor: CommunalSceneInteractor,
    private val communalInteractor: CommunalInteractor,
) :
    TransitionInteractor(
        fromState = KeyguardState.AOD,
@@ -103,6 +110,7 @@ constructor(
                    val isKeyguardOccludedLegacy = keyguardInteractor.isKeyguardOccluded.value
                    val biometricUnlockMode = keyguardInteractor.biometricUnlockState.value.mode
                    val primaryBouncerShowing = keyguardInteractor.primaryBouncerShowing.value
                    val shouldShowCommunal = communalInteractor.shouldShowCommunal.value

                    if (!maybeHandleInsecurePowerGesture()) {
                        val shouldTransitionToLockscreen =
@@ -129,6 +137,9 @@ constructor(
                            (!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen()) ||
                                (KeyguardWmStateRefactor.isEnabled && canWakeDirectlyToGone)

                        val shouldTransitionToCommunal =
                            communalSettingsInteractor.isV2FlagEnabled() && shouldShowCommunal

                        if (shouldTransitionToGone) {
                            // TODO(b/360368320): Adapt for scene framework
                            if (SceneContainerFlag.isEnabled) return@collect
@@ -137,6 +148,11 @@ constructor(
                                modeOnCanceled = TransitionModeOnCanceled.REVERSE,
                                ownerReason = "canWakeDirectlyToGone = true",
                            )
                        } else if (shouldTransitionToCommunal) {
                            communalSceneInteractor.changeScene(
                                CommunalScenes.Communal,
                                "listen for aod to communal",
                            )
                        } else if (shouldTransitionToLockscreen) {
                            val modeOnCanceled =
                                if (startedStep.from == KeyguardState.LOCKSCREEN) {
+6 −5
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ constructor(
        if (!communalSettingsInteractor.isCommunalFlagEnabled()) {
            return
        }
        listenForHubToDozing()
        listenForHubToAodOrDozing()
        listenForHubToPrimaryBouncer()
        listenForHubToAlternateBouncer()
        listenForHubToOccluded()
@@ -123,15 +123,15 @@ constructor(
        }
    }

    private fun listenForHubToDozing() {
    private fun listenForHubToAodOrDozing() {
        scope.launch {
            powerInteractor.isAsleep
                .filterRelevantKeyguardStateAnd { isAsleep -> isAsleep }
                .collect {
                    communalSceneInteractor.snapToScene(
                    communalSceneInteractor.changeScene(
                        newScene = CommunalScenes.Blank,
                        loggingReason = "hub to dozing",
                        keyguardState = KeyguardState.DOZING,
                        loggingReason = "hub to sleep",
                        keyguardState = keyguardInteractor.asleepKeyguardState.value,
                    )
                }
        }
@@ -254,5 +254,6 @@ constructor(
        val TO_LOCKSCREEN_DURATION = 1.seconds
        val TO_BOUNCER_DURATION = 400.milliseconds
        val TO_OCCLUDED_DURATION = 450.milliseconds
        val TO_AOD_DURATION = 500.milliseconds
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransiti
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToPrimaryBouncerTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToGoneTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToOccludedTransitionViewModel
@@ -33,6 +34,7 @@ import com.android.systemui.keyguard.ui.viewmodel.DozingToPrimaryBouncerTransiti
import com.android.systemui.keyguard.ui.viewmodel.DreamingToAodTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DreamingToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToAodTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToDreamingTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GoneToAodTransitionViewModel
@@ -116,6 +118,12 @@ abstract class DeviceEntryIconTransitionModule {
        impl: AodToPrimaryBouncerTransitionViewModel
    ): DeviceEntryIconTransition

    @Binds
    @IntoSet
    abstract fun aodToGlanceableHub(
        impl: AodToGlanceableHubTransitionViewModel
    ): DeviceEntryIconTransition

    @Binds
    @IntoSet
    abstract fun dozingToGone(impl: DozingToGoneTransitionViewModel): DeviceEntryIconTransition
@@ -256,6 +264,12 @@ abstract class DeviceEntryIconTransitionModule {
        impl: GlanceableHubToOccludedTransitionViewModel
    ): DeviceEntryIconTransition

    @Binds
    @IntoSet
    abstract fun glanceableHubToAod(
        impl: GlanceableHubToAodTransitionViewModel
    ): DeviceEntryIconTransition

    @Binds
    @IntoSet
    abstract fun occludedToGlanceableHub(
+78 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.
 */

package com.android.systemui.keyguard.ui.viewmodel

import android.util.MathUtils
import com.android.systemui.Flags.lightRevealMigration
import com.android.systemui.communal.ui.compose.TransitionDuration
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.dagger.GlanceableHubBlurComponent
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.GlanceableHubTransition
import com.android.systemui.scene.shared.model.Scenes
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.flow.Flow

@SysUISingleton
class AodToGlanceableHubTransitionViewModel
@Inject
constructor(
    animationFlow: KeyguardTransitionAnimationFlow,
    blurFactory: GlanceableHubBlurComponent.Factory,
) : DeviceEntryIconTransition, GlanceableHubTransition {
    private val transitionAnimation =
        animationFlow
            .setup(
                duration = TransitionDuration.TO_GLANCEABLE_HUB_DURATION_MS.milliseconds,
                edge = Edge.create(AOD, Scenes.Communal),
            )
            .setupWithoutSceneContainer(edge = Edge.create(AOD, GLANCEABLE_HUB))

    override val deviceEntryParentViewAlpha: Flow<Float> =
        transitionAnimation.immediatelyTransitionTo(1f)

    /** Fade out the lockscreen during a transition to GLANCEABLE_HUB. */
    fun lockscreenAlpha(viewState: ViewStateAccessor): Flow<Float> {
        var currentAlpha = 0f
        return transitionAnimation.sharedFlow(
            duration = 250.milliseconds,
            startTime =
                if (lightRevealMigration()) {
                    100.milliseconds // Wait for the light reveal to "hit" the LS elements.
                } else {
                    0.milliseconds
                },
            onStart = {
                currentAlpha =
                    if (lightRevealMigration()) {
                        viewState.alpha()
                    } else {
                        0f
                    }
            },
            onStep = { MathUtils.lerp(currentAlpha, 0f, it) },
        )
    }

    override val windowBlurRadius: Flow<Float> =
        blurFactory.create(transitionAnimation).getBlurProvider().enterBlurRadius
}
Loading