Loading packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepositoryTest.kt→packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepositoryTest.kt +94 −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.bouncer.data.repository import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testScope import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.time.SystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test Loading @@ -33,18 +51,44 @@ class KeyguardBouncerRepositoryTest : SysuiTestCase() { fun setup() { MockitoAnnotations.initMocks(this) underTest = object : KeyguardBouncerRepositoryImpl( systemClock, testScope.backgroundScope, bouncerLogger, ) ) { override fun isDebuggable(): Boolean = true } } @Test fun changingFlowValueTriggersLogging() = testScope.runTest { underTest.setPrimaryShow(true) runCurrent() Mockito.verify(bouncerLogger) .logChange(eq(""), eq("PrimaryBouncerShow"), value = eq(false), any()) } @Test fun primaryStartDisappearAnimation() = testScope.runTest { assertThat(underTest.isPrimaryBouncerStartingDisappearAnimation()).isFalse() underTest.setPrimaryStartDisappearAnimation(Runnable {}) assertThat(underTest.isPrimaryBouncerStartingDisappearAnimation()).isTrue() underTest.setPrimaryStartDisappearAnimation(null) assertThat(underTest.isPrimaryBouncerStartingDisappearAnimation()).isFalse() val disappearFlow by collectValues(underTest.primaryBouncerStartingDisappearAnimation) underTest.setPrimaryStartDisappearAnimation(null) assertThat(disappearFlow[0]).isNull() // Now issue two in a row to make sure one is not dropped underTest.setPrimaryStartDisappearAnimation(Runnable {}) underTest.setPrimaryStartDisappearAnimation(null) assertThat(disappearFlow[1]).isNotNull() assertThat(disappearFlow[2]).isNull() } } packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt +3 −6 Original line number Diff line number Diff line Loading @@ -105,7 +105,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { mSelectedUserInteractor, faceAuthInteractor, ) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) whenever(repository.isPrimaryBouncerStartingDisappearAnimation()).thenReturn(false) whenever(repository.primaryBouncerShow.value).thenReturn(false) whenever(bouncerView.delegate).thenReturn(bouncerViewDelegate) resources = context.orCreateTestableResources Loading Loading @@ -199,7 +199,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { @Test fun testExpansion_fullyShown() { whenever(repository.panelExpansionAmount.value).thenReturn(0.5f) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) underTest.setPanelExpansion(EXPANSION_VISIBLE) verify(falsingCollector).onBouncerShown() verify(mPrimaryBouncerCallbackInteractor).dispatchFullyShown() Loading @@ -208,7 +207,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { @Test fun testExpansion_fullyHidden() { whenever(repository.panelExpansionAmount.value).thenReturn(0.5f) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) underTest.setPanelExpansion(EXPANSION_HIDDEN) verify(repository).setPrimaryShow(false) verify(falsingCollector).onBouncerHidden() Loading Loading @@ -307,7 +305,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { fun testIsFullShowing() { whenever(repository.primaryBouncerShow.value).thenReturn(true) whenever(repository.panelExpansionAmount.value).thenReturn(EXPANSION_VISIBLE) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) assertThat(underTest.isFullyShowing()).isTrue() whenever(repository.primaryBouncerShow.value).thenReturn(false) assertThat(underTest.isFullyShowing()).isFalse() Loading @@ -333,9 +330,9 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { @Test fun testIsAnimatingAway() { whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(Runnable {}) whenever(repository.isPrimaryBouncerStartingDisappearAnimation()).thenReturn(true) assertThat(underTest.isAnimatingAway()).isTrue() whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) whenever(repository.isPrimaryBouncerStartingDisappearAnimation()).thenReturn(false) assertThat(underTest.isAnimatingAway()).isFalse() } Loading packages/SystemUI/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepository.kt +24 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.bouncer.data.repository import android.annotation.SuppressLint import android.os.Build import android.util.Log import com.android.keyguard.KeyguardSecurityModel Loading Loading @@ -51,7 +52,11 @@ interface KeyguardBouncerRepository { val primaryBouncerShow: StateFlow<Boolean> val primaryBouncerShowingSoon: StateFlow<Boolean> val primaryBouncerStartingToHide: StateFlow<Boolean> val primaryBouncerStartingDisappearAnimation: StateFlow<Runnable?> val primaryBouncerStartingDisappearAnimation: MutableSharedFlow<Runnable?> fun isPrimaryBouncerStartingDisappearAnimation(): Boolean fun isDebuggable(): Boolean /** Determines if we want to instantaneously show the primary bouncer instead of translating. */ val primaryBouncerScrimmed: StateFlow<Boolean> Loading Loading @@ -128,7 +133,7 @@ interface KeyguardBouncerRepository { } @SysUISingleton class KeyguardBouncerRepositoryImpl open class KeyguardBouncerRepositoryImpl @Inject constructor( private val clock: SystemClock, Loading @@ -144,9 +149,19 @@ constructor( override val primaryBouncerShowingSoon = _primaryBouncerShowingSoon.asStateFlow() private val _primaryBouncerStartingToHide = MutableStateFlow(false) override val primaryBouncerStartingToHide = _primaryBouncerStartingToHide.asStateFlow() private val _primaryBouncerDisappearAnimation = MutableStateFlow<Runnable?>(null) @SuppressLint("SharedFlowCreation") override val primaryBouncerStartingDisappearAnimation = _primaryBouncerDisappearAnimation.asStateFlow() MutableSharedFlow<Runnable?>(extraBufferCapacity = 2, replay = 1) override fun isPrimaryBouncerStartingDisappearAnimation(): Boolean { val replayCache = primaryBouncerStartingDisappearAnimation.replayCache return if (!replayCache.isEmpty()) { replayCache.last() != null } else { false } } /** Determines if we want to instantaneously show the primary bouncer instead of translating. */ private val _primaryBouncerScrimmed = MutableStateFlow(false) Loading Loading @@ -177,6 +192,7 @@ constructor( _keyguardAuthenticatedPrimaryAuth.asSharedFlow() /** Whether the user requested to show the bouncer when device is already authenticated */ @SuppressLint("SharedFlowCreation") private val _userRequestedBouncerWhenAlreadyAuthenticated = MutableSharedFlow<Int>() override val userRequestedBouncerWhenAlreadyAuthenticated: Flow<Int> = _userRequestedBouncerWhenAlreadyAuthenticated.asSharedFlow() Loading Loading @@ -226,7 +242,7 @@ constructor( } override fun setPrimaryStartDisappearAnimation(runnable: Runnable?) { _primaryBouncerDisappearAnimation.value = runnable primaryBouncerStartingDisappearAnimation.tryEmit(runnable) } override fun setPanelExpansion(panelExpansion: Float) { Loading Loading @@ -265,9 +281,11 @@ constructor( _lastShownSecurityMode.value = securityMode } override fun isDebuggable() = Build.IS_DEBUGGABLE /** Sets up logs for state flows. */ private fun setUpLogging() { if (!Build.IS_DEBUGGABLE) { if (!isDebuggable()) { return } Loading packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt +7 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.os.Handler import android.os.Trace import android.util.Log import android.view.View import com.android.app.tracing.coroutines.launchTraced as launch import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.DejankUtils Loading Loading @@ -54,7 +55,6 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.map import com.android.app.tracing.coroutines.launchTraced as launch /** * Encapsulates business logic for interacting with the lock-screen primary (pin/pattern/password) Loading Loading @@ -145,7 +145,7 @@ constructor( TAG, "PrimaryBouncerInteractor#show is being called before the " + "primaryBouncerDelegate is set. Let's exit early so we don't " + "set the wrong primaryBouncer state." "set the wrong primaryBouncer state.", ) return false } Loading Loading @@ -197,7 +197,7 @@ constructor( if (isFullyShowing()) { SysUiStatsLog.write( SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN, ) dismissCallbackRegistry.notifyDismissCancelled() } Loading @@ -223,7 +223,7 @@ constructor( fun setPanelExpansion(expansion: Float) { val oldExpansion = repository.panelExpansionAmount.value val expansionChanged = oldExpansion != expansion if (repository.primaryBouncerStartingDisappearAnimation.value == null) { if (!repository.isPrimaryBouncerStartingDisappearAnimation()) { repository.setPanelExpansion(expansion) } Loading Loading @@ -272,7 +272,7 @@ constructor( */ fun setDismissAction( onDismissAction: ActivityStarter.OnDismissAction?, cancelAction: Runnable? cancelAction: Runnable?, ) { repository.bouncerDismissActionModel = if (onDismissAction != null && cancelAction != null) { Loading Loading @@ -344,7 +344,7 @@ constructor( fun isFullyShowing(): Boolean { return (repository.primaryBouncerShowingSoon.value || isBouncerShowing()) && repository.panelExpansionAmount.value == KeyguardBouncerConstants.EXPANSION_VISIBLE && repository.primaryBouncerStartingDisappearAnimation.value == null !repository.isPrimaryBouncerStartingDisappearAnimation() } /** Returns whether bouncer is scrimmed. */ Loading @@ -361,7 +361,7 @@ constructor( /** Return whether bouncer is animating away. */ fun isAnimatingAway(): Boolean { return repository.primaryBouncerStartingDisappearAnimation.value != null return repository.isPrimaryBouncerStartingDisappearAnimation() } /** Return whether bouncer will dismiss with actions */ Loading packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/data/repository/FakeKeyguardBouncerRepository.kt +14 −3 Original line number Diff line number Diff line Loading @@ -23,9 +23,18 @@ class FakeKeyguardBouncerRepository @Inject constructor() : KeyguardBouncerRepos override val primaryBouncerShowingSoon = _primaryBouncerShowingSoon.asStateFlow() private val _primaryBouncerStartingToHide = MutableStateFlow(false) override val primaryBouncerStartingToHide = _primaryBouncerStartingToHide.asStateFlow() private val _primaryBouncerDisappearAnimation = MutableStateFlow<Runnable?>(null) override val primaryBouncerStartingDisappearAnimation = _primaryBouncerDisappearAnimation.asStateFlow() MutableSharedFlow<Runnable?>(extraBufferCapacity = 2, replay = 1) override fun isPrimaryBouncerStartingDisappearAnimation(): Boolean { val replayCache = primaryBouncerStartingDisappearAnimation.replayCache return if (!replayCache.isEmpty()) { replayCache.last() != null } else { false } } private val _primaryBouncerScrimmed = MutableStateFlow(false) override val primaryBouncerScrimmed = _primaryBouncerScrimmed.asStateFlow() private val _panelExpansionAmount = MutableStateFlow(KeyguardBouncerConstants.EXPANSION_HIDDEN) Loading Loading @@ -53,6 +62,8 @@ class FakeKeyguardBouncerRepository @Inject constructor() : KeyguardBouncerRepos MutableStateFlow(KeyguardSecurityModel.SecurityMode.Invalid) override var bouncerDismissActionModel: BouncerDismissActionModel? = null override fun isDebuggable() = true override fun setPrimaryScrimmed(isScrimmed: Boolean) { _primaryBouncerScrimmed.value = isScrimmed } Loading @@ -74,7 +85,7 @@ class FakeKeyguardBouncerRepository @Inject constructor() : KeyguardBouncerRepos } override fun setPrimaryStartDisappearAnimation(runnable: Runnable?) { _primaryBouncerDisappearAnimation.value = runnable primaryBouncerStartingDisappearAnimation.tryEmit(runnable) } override fun setPanelExpansion(panelExpansion: Float) { Loading Loading
packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepositoryTest.kt→packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepositoryTest.kt +94 −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.bouncer.data.repository import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.kosmos.testScope import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq import com.android.systemui.util.time.SystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test Loading @@ -33,18 +51,44 @@ class KeyguardBouncerRepositoryTest : SysuiTestCase() { fun setup() { MockitoAnnotations.initMocks(this) underTest = object : KeyguardBouncerRepositoryImpl( systemClock, testScope.backgroundScope, bouncerLogger, ) ) { override fun isDebuggable(): Boolean = true } } @Test fun changingFlowValueTriggersLogging() = testScope.runTest { underTest.setPrimaryShow(true) runCurrent() Mockito.verify(bouncerLogger) .logChange(eq(""), eq("PrimaryBouncerShow"), value = eq(false), any()) } @Test fun primaryStartDisappearAnimation() = testScope.runTest { assertThat(underTest.isPrimaryBouncerStartingDisappearAnimation()).isFalse() underTest.setPrimaryStartDisappearAnimation(Runnable {}) assertThat(underTest.isPrimaryBouncerStartingDisappearAnimation()).isTrue() underTest.setPrimaryStartDisappearAnimation(null) assertThat(underTest.isPrimaryBouncerStartingDisappearAnimation()).isFalse() val disappearFlow by collectValues(underTest.primaryBouncerStartingDisappearAnimation) underTest.setPrimaryStartDisappearAnimation(null) assertThat(disappearFlow[0]).isNull() // Now issue two in a row to make sure one is not dropped underTest.setPrimaryStartDisappearAnimation(Runnable {}) underTest.setPrimaryStartDisappearAnimation(null) assertThat(disappearFlow[1]).isNotNull() assertThat(disappearFlow[2]).isNull() } }
packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorTest.kt +3 −6 Original line number Diff line number Diff line Loading @@ -105,7 +105,7 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { mSelectedUserInteractor, faceAuthInteractor, ) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) whenever(repository.isPrimaryBouncerStartingDisappearAnimation()).thenReturn(false) whenever(repository.primaryBouncerShow.value).thenReturn(false) whenever(bouncerView.delegate).thenReturn(bouncerViewDelegate) resources = context.orCreateTestableResources Loading Loading @@ -199,7 +199,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { @Test fun testExpansion_fullyShown() { whenever(repository.panelExpansionAmount.value).thenReturn(0.5f) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) underTest.setPanelExpansion(EXPANSION_VISIBLE) verify(falsingCollector).onBouncerShown() verify(mPrimaryBouncerCallbackInteractor).dispatchFullyShown() Loading @@ -208,7 +207,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { @Test fun testExpansion_fullyHidden() { whenever(repository.panelExpansionAmount.value).thenReturn(0.5f) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) underTest.setPanelExpansion(EXPANSION_HIDDEN) verify(repository).setPrimaryShow(false) verify(falsingCollector).onBouncerHidden() Loading Loading @@ -307,7 +305,6 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { fun testIsFullShowing() { whenever(repository.primaryBouncerShow.value).thenReturn(true) whenever(repository.panelExpansionAmount.value).thenReturn(EXPANSION_VISIBLE) whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) assertThat(underTest.isFullyShowing()).isTrue() whenever(repository.primaryBouncerShow.value).thenReturn(false) assertThat(underTest.isFullyShowing()).isFalse() Loading @@ -333,9 +330,9 @@ class PrimaryBouncerInteractorTest : SysuiTestCase() { @Test fun testIsAnimatingAway() { whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(Runnable {}) whenever(repository.isPrimaryBouncerStartingDisappearAnimation()).thenReturn(true) assertThat(underTest.isAnimatingAway()).isTrue() whenever(repository.primaryBouncerStartingDisappearAnimation.value).thenReturn(null) whenever(repository.isPrimaryBouncerStartingDisappearAnimation()).thenReturn(false) assertThat(underTest.isAnimatingAway()).isFalse() } Loading
packages/SystemUI/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepository.kt +24 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.bouncer.data.repository import android.annotation.SuppressLint import android.os.Build import android.util.Log import com.android.keyguard.KeyguardSecurityModel Loading Loading @@ -51,7 +52,11 @@ interface KeyguardBouncerRepository { val primaryBouncerShow: StateFlow<Boolean> val primaryBouncerShowingSoon: StateFlow<Boolean> val primaryBouncerStartingToHide: StateFlow<Boolean> val primaryBouncerStartingDisappearAnimation: StateFlow<Runnable?> val primaryBouncerStartingDisappearAnimation: MutableSharedFlow<Runnable?> fun isPrimaryBouncerStartingDisappearAnimation(): Boolean fun isDebuggable(): Boolean /** Determines if we want to instantaneously show the primary bouncer instead of translating. */ val primaryBouncerScrimmed: StateFlow<Boolean> Loading Loading @@ -128,7 +133,7 @@ interface KeyguardBouncerRepository { } @SysUISingleton class KeyguardBouncerRepositoryImpl open class KeyguardBouncerRepositoryImpl @Inject constructor( private val clock: SystemClock, Loading @@ -144,9 +149,19 @@ constructor( override val primaryBouncerShowingSoon = _primaryBouncerShowingSoon.asStateFlow() private val _primaryBouncerStartingToHide = MutableStateFlow(false) override val primaryBouncerStartingToHide = _primaryBouncerStartingToHide.asStateFlow() private val _primaryBouncerDisappearAnimation = MutableStateFlow<Runnable?>(null) @SuppressLint("SharedFlowCreation") override val primaryBouncerStartingDisappearAnimation = _primaryBouncerDisappearAnimation.asStateFlow() MutableSharedFlow<Runnable?>(extraBufferCapacity = 2, replay = 1) override fun isPrimaryBouncerStartingDisappearAnimation(): Boolean { val replayCache = primaryBouncerStartingDisappearAnimation.replayCache return if (!replayCache.isEmpty()) { replayCache.last() != null } else { false } } /** Determines if we want to instantaneously show the primary bouncer instead of translating. */ private val _primaryBouncerScrimmed = MutableStateFlow(false) Loading Loading @@ -177,6 +192,7 @@ constructor( _keyguardAuthenticatedPrimaryAuth.asSharedFlow() /** Whether the user requested to show the bouncer when device is already authenticated */ @SuppressLint("SharedFlowCreation") private val _userRequestedBouncerWhenAlreadyAuthenticated = MutableSharedFlow<Int>() override val userRequestedBouncerWhenAlreadyAuthenticated: Flow<Int> = _userRequestedBouncerWhenAlreadyAuthenticated.asSharedFlow() Loading Loading @@ -226,7 +242,7 @@ constructor( } override fun setPrimaryStartDisappearAnimation(runnable: Runnable?) { _primaryBouncerDisappearAnimation.value = runnable primaryBouncerStartingDisappearAnimation.tryEmit(runnable) } override fun setPanelExpansion(panelExpansion: Float) { Loading Loading @@ -265,9 +281,11 @@ constructor( _lastShownSecurityMode.value = securityMode } override fun isDebuggable() = Build.IS_DEBUGGABLE /** Sets up logs for state flows. */ private fun setUpLogging() { if (!Build.IS_DEBUGGABLE) { if (!isDebuggable()) { return } Loading
packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt +7 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.os.Handler import android.os.Trace import android.util.Log import android.view.View import com.android.app.tracing.coroutines.launchTraced as launch import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.DejankUtils Loading Loading @@ -54,7 +55,6 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.map import com.android.app.tracing.coroutines.launchTraced as launch /** * Encapsulates business logic for interacting with the lock-screen primary (pin/pattern/password) Loading Loading @@ -145,7 +145,7 @@ constructor( TAG, "PrimaryBouncerInteractor#show is being called before the " + "primaryBouncerDelegate is set. Let's exit early so we don't " + "set the wrong primaryBouncer state." "set the wrong primaryBouncer state.", ) return false } Loading Loading @@ -197,7 +197,7 @@ constructor( if (isFullyShowing()) { SysUiStatsLog.write( SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN, ) dismissCallbackRegistry.notifyDismissCancelled() } Loading @@ -223,7 +223,7 @@ constructor( fun setPanelExpansion(expansion: Float) { val oldExpansion = repository.panelExpansionAmount.value val expansionChanged = oldExpansion != expansion if (repository.primaryBouncerStartingDisappearAnimation.value == null) { if (!repository.isPrimaryBouncerStartingDisappearAnimation()) { repository.setPanelExpansion(expansion) } Loading Loading @@ -272,7 +272,7 @@ constructor( */ fun setDismissAction( onDismissAction: ActivityStarter.OnDismissAction?, cancelAction: Runnable? cancelAction: Runnable?, ) { repository.bouncerDismissActionModel = if (onDismissAction != null && cancelAction != null) { Loading Loading @@ -344,7 +344,7 @@ constructor( fun isFullyShowing(): Boolean { return (repository.primaryBouncerShowingSoon.value || isBouncerShowing()) && repository.panelExpansionAmount.value == KeyguardBouncerConstants.EXPANSION_VISIBLE && repository.primaryBouncerStartingDisappearAnimation.value == null !repository.isPrimaryBouncerStartingDisappearAnimation() } /** Returns whether bouncer is scrimmed. */ Loading @@ -361,7 +361,7 @@ constructor( /** Return whether bouncer is animating away. */ fun isAnimatingAway(): Boolean { return repository.primaryBouncerStartingDisappearAnimation.value != null return repository.isPrimaryBouncerStartingDisappearAnimation() } /** Return whether bouncer will dismiss with actions */ Loading
packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/data/repository/FakeKeyguardBouncerRepository.kt +14 −3 Original line number Diff line number Diff line Loading @@ -23,9 +23,18 @@ class FakeKeyguardBouncerRepository @Inject constructor() : KeyguardBouncerRepos override val primaryBouncerShowingSoon = _primaryBouncerShowingSoon.asStateFlow() private val _primaryBouncerStartingToHide = MutableStateFlow(false) override val primaryBouncerStartingToHide = _primaryBouncerStartingToHide.asStateFlow() private val _primaryBouncerDisappearAnimation = MutableStateFlow<Runnable?>(null) override val primaryBouncerStartingDisappearAnimation = _primaryBouncerDisappearAnimation.asStateFlow() MutableSharedFlow<Runnable?>(extraBufferCapacity = 2, replay = 1) override fun isPrimaryBouncerStartingDisappearAnimation(): Boolean { val replayCache = primaryBouncerStartingDisappearAnimation.replayCache return if (!replayCache.isEmpty()) { replayCache.last() != null } else { false } } private val _primaryBouncerScrimmed = MutableStateFlow(false) override val primaryBouncerScrimmed = _primaryBouncerScrimmed.asStateFlow() private val _panelExpansionAmount = MutableStateFlow(KeyguardBouncerConstants.EXPANSION_HIDDEN) Loading Loading @@ -53,6 +62,8 @@ class FakeKeyguardBouncerRepository @Inject constructor() : KeyguardBouncerRepos MutableStateFlow(KeyguardSecurityModel.SecurityMode.Invalid) override var bouncerDismissActionModel: BouncerDismissActionModel? = null override fun isDebuggable() = true override fun setPrimaryScrimmed(isScrimmed: Boolean) { _primaryBouncerScrimmed.value = isScrimmed } Loading @@ -74,7 +85,7 @@ class FakeKeyguardBouncerRepository @Inject constructor() : KeyguardBouncerRepos } override fun setPrimaryStartDisappearAnimation(runnable: Runnable?) { _primaryBouncerDisappearAnimation.value = runnable primaryBouncerStartingDisappearAnimation.tryEmit(runnable) } override fun setPanelExpansion(panelExpansion: Float) { Loading