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

Commit 3a2b8529 authored by Matt Pietal's avatar Matt Pietal Committed by Android (Google) Code Review
Browse files

Merge "Overhaul keyguard occlusion and camera launch transitions." into main

parents 6c29e1ea cb313ad9
Loading
Loading
Loading
Loading
+12 −28
Original line number Diff line number Diff line
@@ -45,32 +45,32 @@ import com.android.systemui.biometrics.ui.viewmodel.DefaultUdfpsTouchOverlayView
import com.android.systemui.biometrics.ui.viewmodel.DeviceEntryUdfpsTouchOverlayViewModel
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.FromAodTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.power.data.repository.FakePowerRepository
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.power.shared.model.WakefulnessState
import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.phone.SystemUIDialogManager
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.testKosmos
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -102,6 +102,7 @@ private const val SENSOR_HEIGHT = 60
@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
class UdfpsControllerOverlayTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    @JvmField @Rule var rule = MockitoJUnit.rule()

@@ -148,28 +149,11 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {

    @Before
    fun setup() {
        testScope = TestScope(StandardTestDispatcher())
        powerRepository = FakePowerRepository()
        powerInteractor =
            PowerInteractor(
                powerRepository,
                mock(FalsingCollector::class.java),
                mock(ScreenOffAnimationController::class.java),
                statusBarStateController,
            )
        keyguardTransitionRepository = FakeKeyguardTransitionRepository()
        keyguardTransitionInteractor =
            KeyguardTransitionInteractor(
                scope = testScope.backgroundScope,
                repository = keyguardTransitionRepository,
                fromLockscreenTransitionInteractor = {
                    mock(FromLockscreenTransitionInteractor::class.java)
                },
                fromPrimaryBouncerTransitionInteractor = {
                    mock(FromPrimaryBouncerTransitionInteractor::class.java)
                },
                fromAodTransitionInteractor = { mock(FromAodTransitionInteractor::class.java) },
            )
        testScope = kosmos.testScope
        powerRepository = kosmos.fakePowerRepository
        powerInteractor = kosmos.powerInteractor
        keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
        keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor
        whenever(inflater.inflate(R.layout.udfps_view, null, false)).thenReturn(udfpsView)
        whenever(inflater.inflate(R.layout.udfps_bp_view, null))
            .thenReturn(mock(UdfpsBpView::class.java))
+23 −19
Original line number Diff line number Diff line
@@ -25,18 +25,17 @@ import com.android.systemui.animation.AnimatorTestRule
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.BiometricUnlockSource
import com.android.systemui.power.data.repository.FakePowerRepository
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.kosmos.testScope
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
import com.android.systemui.power.domain.interactor.PowerInteractorFactory
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.CircleReveal
import com.android.systemui.statusbar.LightRevealEffect
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.mock
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -49,9 +48,10 @@ import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class LightRevealScrimRepositoryTest : SysuiTestCase() {
    private lateinit var fakeKeyguardRepository: FakeKeyguardRepository
    private lateinit var powerRepository: FakePowerRepository
    private lateinit var powerInteractor: PowerInteractor
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private val fakeKeyguardRepository = kosmos.fakeKeyguardRepository
    private val powerInteractor = kosmos.powerInteractor
    private lateinit var underTest: LightRevealScrimRepositoryImpl

    @get:Rule val animatorTestRule = AnimatorTestRule(this)
@@ -59,13 +59,13 @@ class LightRevealScrimRepositoryTest : SysuiTestCase() {
    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        fakeKeyguardRepository = FakeKeyguardRepository()
        powerRepository = FakePowerRepository()
        powerInteractor =
            PowerInteractorFactory.create(repository = powerRepository).powerInteractor

        underTest =
            LightRevealScrimRepositoryImpl(fakeKeyguardRepository, context, powerInteractor, mock())
            LightRevealScrimRepositoryImpl(
                kosmos.fakeKeyguardRepository,
                context,
                kosmos.powerInteractor,
                mock()
            )
    }

    @Test
@@ -168,8 +168,9 @@ class LightRevealScrimRepositoryTest : SysuiTestCase() {
    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    fun revealAmount_emitsTo1AfterAnimationStarted() =
        runTest(UnconfinedTestDispatcher()) {
        testScope.runTest {
            val value by collectLastValue(underTest.revealAmount)
            runCurrent()
            underTest.startRevealAmountAnimator(true)
            assertEquals(0.0f, value)
            animatorTestRule.advanceTimeBy(500L)
@@ -179,8 +180,9 @@ class LightRevealScrimRepositoryTest : SysuiTestCase() {
    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    fun revealAmount_startingRevealTwiceWontRerunAnimator() =
        runTest(UnconfinedTestDispatcher()) {
        testScope.runTest {
            val value by collectLastValue(underTest.revealAmount)
            runCurrent()
            underTest.startRevealAmountAnimator(true)
            assertEquals(0.0f, value)
            animatorTestRule.advanceTimeBy(250L)
@@ -193,12 +195,14 @@ class LightRevealScrimRepositoryTest : SysuiTestCase() {
    @Test
    @TestableLooper.RunWithLooper(setAsMainLooper = true)
    fun revealAmount_emitsTo0AfterAnimationStartedReversed() =
        runTest(UnconfinedTestDispatcher()) {
            val value by collectLastValue(underTest.revealAmount)
        testScope.runTest {
            val lastValue by collectLastValue(underTest.revealAmount)
            runCurrent()
            underTest.startRevealAmountAnimator(true)
            animatorTestRule.advanceTimeBy(500L)
            underTest.startRevealAmountAnimator(false)
            assertEquals(1.0f, value)
            animatorTestRule.advanceTimeBy(500L)
            assertEquals(0.0f, value)
            assertEquals(0.0f, lastValue)
        }

    /**
+5 −0
Original line number Diff line number Diff line
@@ -18,9 +18,11 @@
package com.android.systemui.keyguard.domain.interactor

import android.app.StatusBarManager
import android.platform.test.annotations.DisableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
@@ -120,6 +122,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testKeyguardGuardVisibilityStopsSecureCamera() =
        testScope.runTest {
            val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
@@ -144,6 +147,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun testBouncerShowingResetsSecureCameraState() =
        testScope.runTest {
            val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
@@ -166,6 +170,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
    fun keyguardVisibilityIsDefinedAsKeyguardShowingButNotOccluded() = runTest {
        val isVisible = collectLastValue(underTest.isKeyguardVisible)
        repository.setKeyguardShowing(true)
+18 −9
Original line number Diff line number Diff line
@@ -24,9 +24,12 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.shared.model.BiometricMessage
import com.android.systemui.deviceentry.shared.model.FingerprintLockoutMessage
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.ErrorFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.power.domain.interactor.PowerInteractor
@@ -60,8 +63,12 @@ constructor(
    private val context: Context,
    activityStarter: ActivityStarter,
    powerInteractor: PowerInteractor,
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
) {
    private val keyguardOccludedByApp: Flow<Boolean> =
        if (KeyguardWmStateRefactor.isEnabled) {
            keyguardTransitionInteractor.currentKeyguardState.map { it == KeyguardState.OCCLUDED }
        } else {
            combine(
                    keyguardInteractor.isKeyguardOccluded,
                    keyguardInteractor.isKeyguardShowing,
@@ -71,6 +78,8 @@ constructor(
                    occluded && showing && !primaryBouncerShowing && !alternateBouncerVisible
                }
                .distinctUntilChanged()
        }

    private val fingerprintUnlockSuccessEvents: Flow<Unit> =
        fingerprintAuthRepository.authenticationStatus
            .ifKeyguardOccludedByApp()
+11 −2
Original line number Diff line number Diff line
@@ -289,6 +289,8 @@ public class KeyguardService extends Service {
        };
    }

    private final WindowManagerOcclusionManager mWmOcclusionManager;

    @Inject
    public KeyguardService(
            KeyguardViewMediator keyguardViewMediator,
@@ -302,7 +304,8 @@ public class KeyguardService extends Service {
            KeyguardSurfaceBehindParamsApplier keyguardSurfaceBehindAnimator,
            @Application CoroutineScope scope,
            FeatureFlags featureFlags,
            PowerInteractor powerInteractor) {
            PowerInteractor powerInteractor,
            WindowManagerOcclusionManager windowManagerOcclusionManager) {
        super();
        mKeyguardViewMediator = keyguardViewMediator;
        mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
@@ -323,6 +326,8 @@ public class KeyguardService extends Service {
                    keyguardSurfaceBehindAnimator,
                    scope);
        }

        mWmOcclusionManager = windowManagerOcclusionManager;
    }

    @Override
@@ -414,7 +419,11 @@ public class KeyguardService extends Service {

            Trace.beginSection("KeyguardService.mBinder#setOccluded");
            checkPermission();
            if (!KeyguardWmStateRefactor.isEnabled()) {
                mKeyguardViewMediator.setOccluded(isOccluded, animate);
            } else {
                mWmOcclusionManager.onKeyguardServiceSetOccluded(isOccluded);
            }
            Trace.endSection();
        }

Loading