Loading packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -2070,3 +2070,13 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "hub_edit_mode_transition" namespace: "systemui" description: "Fix hub to edit mode transition issues" bug: "411422599" metadata { purpose: PURPOSE_BUGFIX } } packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt +57 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.domain.interactor.communalSceneInteractor import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.shared.model.EditModeState import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository Loading @@ -61,6 +62,7 @@ import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakefulnessState import com.android.systemui.testKosmos import com.google.common.truth.Truth import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest Loading @@ -71,6 +73,7 @@ import org.mockito.Mockito.reset import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(ParameterizedAndroidJunit4::class) class FromAlternateBouncerTransitionInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { Loading Loading @@ -148,6 +151,60 @@ class FromAlternateBouncerTransitionInteractorTest(flags: FlagsParameterization) .startedTransition(from = KeyguardState.ALTERNATE_BOUNCER, to = KeyguardState.GONE) } @Test @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR, Flags.FLAG_HUB_EDIT_MODE_TRANSITION) @DisableSceneContainer fun transitionToGone_whenEnteringHubEditMode_flagOff_transitionToGone() = kosmos.runTest { transitionRepository.transitionTo( from = KeyguardState.LOCKSCREEN, to = KeyguardState.ALTERNATE_BOUNCER, ) reset(transitionRepository) fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null) fakeKeyguardRepository.setKeyguardOccluded(true) runCurrent() assertThat(transitionRepository).noTransitionsStarted() communalSceneInteractor.setEditModeState(EditModeState.STARTING) fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(true) runCurrent() fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null) runCurrent() assertThat(transitionRepository) .startedTransition(from = KeyguardState.ALTERNATE_BOUNCER, to = KeyguardState.GONE) } @Test @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) @EnableFlags(Flags.FLAG_HUB_EDIT_MODE_TRANSITION) @DisableSceneContainer fun transitionToGone_whenEnteringHubEditMode_flagOn_doNothing() = kosmos.runTest { transitionRepository.transitionTo( from = KeyguardState.LOCKSCREEN, to = KeyguardState.ALTERNATE_BOUNCER, ) reset(transitionRepository) fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null) fakeKeyguardRepository.setKeyguardOccluded(true) runCurrent() assertThat(transitionRepository).noTransitionsStarted() communalSceneInteractor.setEditModeState(EditModeState.STARTING) fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(true) runCurrent() fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null) runCurrent() assertThat(transitionRepository).noTransitionsStarted() } @Test fun noTransition_keyguardNotOccluded_biometricAuthenticated() = testScope.runTest { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt +46 −0 Original line number Diff line number Diff line Loading @@ -16,11 +16,13 @@ package com.android.systemui.keyguard.domain.interactor import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.FLAG_HUB_EDIT_MODE_TRANSITION import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository Loading @@ -29,6 +31,7 @@ import com.android.systemui.communal.domain.interactor.communalSceneInteractor import com.android.systemui.communal.domain.interactor.setCommunalV2Available import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.shared.model.EditModeState import com.android.systemui.coroutines.collectValues import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository Loading @@ -48,6 +51,7 @@ import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.testKosmos import com.google.common.truth.Truth import junit.framework.Assert.assertEquals import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest Loading @@ -58,6 +62,7 @@ import org.mockito.Mockito.reset import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(ParameterizedAndroidJunit4::class) class FromPrimaryBouncerTransitionInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { Loading Loading @@ -217,6 +222,47 @@ class FromPrimaryBouncerTransitionInteractorTest(flags: FlagsParameterization) : ) } @Test @EnableFlags(FLAG_HUB_EDIT_MODE_TRANSITION) @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableSceneContainer fun testPrimaryBouncerToGone_whenEnteringHubEditMode_flagOn_doNothing() = kosmos.runTest { underTest.start() transitionRepository.transitionTo( from = KeyguardState.LOCKSCREEN, to = KeyguardState.PRIMARY_BOUNCER, ) runCurrent() reset(transitionRepository) communalSceneInteractor.setEditModeState(EditModeState.STARTING) fakeKeyguardRepository.setKeyguardGoingAway(true) runCurrent() assertThat(transitionRepository).noTransitionsStarted() } @Test @DisableFlags(FLAG_HUB_EDIT_MODE_TRANSITION, FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableSceneContainer fun testPrimaryBouncerToGone_whenEnteringHubEditMode_flagOff_transitionToGone() = kosmos.runTest { underTest.start() transitionRepository.transitionTo( from = KeyguardState.LOCKSCREEN, to = KeyguardState.PRIMARY_BOUNCER, ) communalSceneInteractor.setEditModeState(EditModeState.STARTING) fakeKeyguardRepository.setKeyguardGoingAway(true) runCurrent() assertThat(transitionRepository) .startedTransition(from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.GONE) } @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableSceneContainer Loading packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt +9 −8 Original line number Diff line number Diff line Loading @@ -59,7 +59,6 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach Loading Loading @@ -118,7 +117,9 @@ constructor( ), communalInteractor.editModeOpen, ) .filter { it } /** Emits when the hub has transitioned out, and edit mode is ready to transition in. */ val hubTransitionOut = canShowEditMode // Only widgets are editable. override val communalContent: Flow<List<CommunalContentModel>> = Loading packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +45 −23 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import androidx.lifecycle.lifecycleScope import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.theme.PlatformTheme import com.android.internal.logging.UiEventLogger import com.android.systemui.Flags import com.android.systemui.Flags.communalEditWidgetsActivityFinishFix import com.android.systemui.communal.shared.log.CommunalUiEvent import com.android.systemui.communal.shared.model.CommunalScenes Loading @@ -53,6 +54,7 @@ import com.android.systemui.log.dagger.CommunalLog import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.settings.UserTracker import javax.inject.Inject import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.flow.first /** An Activity for editing the widgets that appear in hub mode. */ Loading Loading @@ -176,6 +178,9 @@ constructor( if (communalEditWidgetsActivityFinishFix()) ActivityControllerImpl(this) else NopActivityController() // Completes when the activity UI is rendered and ready for the hub to edit mode transition. private val readyDeferred = CompletableDeferred<Unit>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loading Loading @@ -212,7 +217,14 @@ constructor( // Handle scene change to show the activity and animate in its content private fun listenForTransitionAndChangeScene() { lifecycleScope.launch { communalViewModel.canShowEditMode.collect { if (Flags.hubEditModeTransition()) { // Wait for the edit mode activity to be ready underneath the hub before starting // the hub to edit mode transition. readyDeferred.await() } else { communalViewModel.canShowEditMode.first { it } } if (!SceneContainerFlag.isEnabled) { communalViewModel.changeScene( scene = CommunalScenes.Blank, Loading @@ -220,11 +232,16 @@ constructor( transitionKey = CommunalTransitionKeys.ToEditMode, keyguardState = KeyguardState.GONE, ) // wait till transitioned to Blank scene, then animate in communal content in // edit mode // Wait for scene change to BLANK. communalViewModel.currentScene.first { it == CommunalScenes.Blank } } if (Flags.hubEditModeTransition()) { // Wait for hub to fully transition out. communalViewModel.hubTransitionOut.first { it } } // Wait for dream to exit, if we were previously dreaming. keyguardInteractor.isDreaming.first { !it } Loading @@ -241,7 +258,6 @@ constructor( } } } } private fun onOpenWidgetPicker() { lifecycleScope.launch { Loading Loading @@ -348,6 +364,12 @@ constructor( uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_EDIT_MODE_SHOWN) } override fun onResume() { super.onResume() readyDeferred.complete(Unit) } override fun onStop() { super.onStop() communalViewModel.setEditActivityShowing(false) Loading Loading
packages/SystemUI/aconfig/systemui.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -2070,3 +2070,13 @@ flag { purpose: PURPOSE_BUGFIX } } flag { name: "hub_edit_mode_transition" namespace: "systemui" description: "Fix hub to edit mode transition issues" bug: "411422599" metadata { purpose: PURPOSE_BUGFIX } }
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt +57 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.android.systemui.communal.domain.interactor.communalInteractor import com.android.systemui.communal.domain.interactor.communalSceneInteractor import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.shared.model.EditModeState import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository Loading @@ -61,6 +62,7 @@ import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakefulnessState import com.android.systemui.testKosmos import com.google.common.truth.Truth import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest Loading @@ -71,6 +73,7 @@ import org.mockito.Mockito.reset import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(ParameterizedAndroidJunit4::class) class FromAlternateBouncerTransitionInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { Loading Loading @@ -148,6 +151,60 @@ class FromAlternateBouncerTransitionInteractorTest(flags: FlagsParameterization) .startedTransition(from = KeyguardState.ALTERNATE_BOUNCER, to = KeyguardState.GONE) } @Test @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR, Flags.FLAG_HUB_EDIT_MODE_TRANSITION) @DisableSceneContainer fun transitionToGone_whenEnteringHubEditMode_flagOff_transitionToGone() = kosmos.runTest { transitionRepository.transitionTo( from = KeyguardState.LOCKSCREEN, to = KeyguardState.ALTERNATE_BOUNCER, ) reset(transitionRepository) fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null) fakeKeyguardRepository.setKeyguardOccluded(true) runCurrent() assertThat(transitionRepository).noTransitionsStarted() communalSceneInteractor.setEditModeState(EditModeState.STARTING) fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(true) runCurrent() fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null) runCurrent() assertThat(transitionRepository) .startedTransition(from = KeyguardState.ALTERNATE_BOUNCER, to = KeyguardState.GONE) } @Test @DisableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR) @EnableFlags(Flags.FLAG_HUB_EDIT_MODE_TRANSITION) @DisableSceneContainer fun transitionToGone_whenEnteringHubEditMode_flagOn_doNothing() = kosmos.runTest { transitionRepository.transitionTo( from = KeyguardState.LOCKSCREEN, to = KeyguardState.ALTERNATE_BOUNCER, ) reset(transitionRepository) fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null) fakeKeyguardRepository.setKeyguardOccluded(true) runCurrent() assertThat(transitionRepository).noTransitionsStarted() communalSceneInteractor.setEditModeState(EditModeState.STARTING) fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(true) runCurrent() fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null) runCurrent() assertThat(transitionRepository).noTransitionsStarted() } @Test fun noTransition_keyguardNotOccluded_biometricAuthenticated() = testScope.runTest { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt +46 −0 Original line number Diff line number Diff line Loading @@ -16,11 +16,13 @@ package com.android.systemui.keyguard.domain.interactor import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2 import com.android.systemui.Flags.FLAG_HUB_EDIT_MODE_TRANSITION import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository Loading @@ -29,6 +31,7 @@ import com.android.systemui.communal.domain.interactor.communalSceneInteractor import com.android.systemui.communal.domain.interactor.setCommunalV2Available import com.android.systemui.communal.domain.interactor.setCommunalV2ConfigEnabled import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.shared.model.EditModeState import com.android.systemui.coroutines.collectValues import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository Loading @@ -48,6 +51,7 @@ import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.testKosmos import com.google.common.truth.Truth import junit.framework.Assert.assertEquals import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest Loading @@ -58,6 +62,7 @@ import org.mockito.Mockito.reset import platform.test.runner.parameterized.ParameterizedAndroidJunit4 import platform.test.runner.parameterized.Parameters @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(ParameterizedAndroidJunit4::class) class FromPrimaryBouncerTransitionInteractorTest(flags: FlagsParameterization) : SysuiTestCase() { Loading Loading @@ -217,6 +222,47 @@ class FromPrimaryBouncerTransitionInteractorTest(flags: FlagsParameterization) : ) } @Test @EnableFlags(FLAG_HUB_EDIT_MODE_TRANSITION) @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableSceneContainer fun testPrimaryBouncerToGone_whenEnteringHubEditMode_flagOn_doNothing() = kosmos.runTest { underTest.start() transitionRepository.transitionTo( from = KeyguardState.LOCKSCREEN, to = KeyguardState.PRIMARY_BOUNCER, ) runCurrent() reset(transitionRepository) communalSceneInteractor.setEditModeState(EditModeState.STARTING) fakeKeyguardRepository.setKeyguardGoingAway(true) runCurrent() assertThat(transitionRepository).noTransitionsStarted() } @Test @DisableFlags(FLAG_HUB_EDIT_MODE_TRANSITION, FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableSceneContainer fun testPrimaryBouncerToGone_whenEnteringHubEditMode_flagOff_transitionToGone() = kosmos.runTest { underTest.start() transitionRepository.transitionTo( from = KeyguardState.LOCKSCREEN, to = KeyguardState.PRIMARY_BOUNCER, ) communalSceneInteractor.setEditModeState(EditModeState.STARTING) fakeKeyguardRepository.setKeyguardGoingAway(true) runCurrent() assertThat(transitionRepository) .startedTransition(from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.GONE) } @Test @EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR) @DisableSceneContainer Loading
packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt +9 −8 Original line number Diff line number Diff line Loading @@ -59,7 +59,6 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach Loading Loading @@ -118,7 +117,9 @@ constructor( ), communalInteractor.editModeOpen, ) .filter { it } /** Emits when the hub has transitioned out, and edit mode is ready to transition in. */ val hubTransitionOut = canShowEditMode // Only widgets are editable. override val communalContent: Flow<List<CommunalContentModel>> = Loading
packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +45 −23 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import androidx.lifecycle.lifecycleScope import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.theme.PlatformTheme import com.android.internal.logging.UiEventLogger import com.android.systemui.Flags import com.android.systemui.Flags.communalEditWidgetsActivityFinishFix import com.android.systemui.communal.shared.log.CommunalUiEvent import com.android.systemui.communal.shared.model.CommunalScenes Loading @@ -53,6 +54,7 @@ import com.android.systemui.log.dagger.CommunalLog import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.settings.UserTracker import javax.inject.Inject import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.flow.first /** An Activity for editing the widgets that appear in hub mode. */ Loading Loading @@ -176,6 +178,9 @@ constructor( if (communalEditWidgetsActivityFinishFix()) ActivityControllerImpl(this) else NopActivityController() // Completes when the activity UI is rendered and ready for the hub to edit mode transition. private val readyDeferred = CompletableDeferred<Unit>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loading Loading @@ -212,7 +217,14 @@ constructor( // Handle scene change to show the activity and animate in its content private fun listenForTransitionAndChangeScene() { lifecycleScope.launch { communalViewModel.canShowEditMode.collect { if (Flags.hubEditModeTransition()) { // Wait for the edit mode activity to be ready underneath the hub before starting // the hub to edit mode transition. readyDeferred.await() } else { communalViewModel.canShowEditMode.first { it } } if (!SceneContainerFlag.isEnabled) { communalViewModel.changeScene( scene = CommunalScenes.Blank, Loading @@ -220,11 +232,16 @@ constructor( transitionKey = CommunalTransitionKeys.ToEditMode, keyguardState = KeyguardState.GONE, ) // wait till transitioned to Blank scene, then animate in communal content in // edit mode // Wait for scene change to BLANK. communalViewModel.currentScene.first { it == CommunalScenes.Blank } } if (Flags.hubEditModeTransition()) { // Wait for hub to fully transition out. communalViewModel.hubTransitionOut.first { it } } // Wait for dream to exit, if we were previously dreaming. keyguardInteractor.isDreaming.first { !it } Loading @@ -241,7 +258,6 @@ constructor( } } } } private fun onOpenWidgetPicker() { lifecycleScope.launch { Loading Loading @@ -348,6 +364,12 @@ constructor( uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_EDIT_MODE_SHOWN) } override fun onResume() { super.onResume() readyDeferred.complete(Unit) } override fun onStop() { super.onStop() communalViewModel.setEditActivityShowing(false) Loading