diff options
author | 2025-01-09 13:41:01 -0500 | |
---|---|---|
committer | 2025-01-10 14:35:31 -0500 | |
commit | c9c0f6703c7b9f1df899feded854bb60a0da37e0 (patch) | |
tree | 854b3ce52fcebe11d3a55e8af9154f67bfa1e928 | |
parent | af694e918c02d9a644fcdc4836e9297da7e4741a (diff) |
[sb] Expose a top-level `shouldHomeStatusBarBeVisible` flow
When inflating the top-level StatusBarRoot's AndroidView, everything is
visible at first and there is no way to hide it until all of the
view-binders start up.
The fix here is to allow for StatusBarRoot to watch for the top-level
visibility and hide the entire android view. Then when that value
changes, we can update it.
Also, add the case of HUN, which does require the status bar to be
showing.
Test: `adb shell kill com.android.systemui` with the flag on
Test: HomeStatusBarViewModelImplTest
Bug: 364360986
Flag: com.android.systemui.status_bar_root_modernization
Change-Id: I04cb436c1d2b63f4e24ab9588757be5941728c16
5 files changed, 115 insertions, 5 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt index 6feada1c9769..937f333b0065 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt @@ -46,6 +46,8 @@ class FakeHomeStatusBarViewModel( override val isHomeStatusBarAllowedByScene = MutableStateFlow(false) + override val shouldHomeStatusBarBeVisible = MutableStateFlow(false) + override val shouldShowOperatorNameView = MutableStateFlow(false) override val isClockVisible = diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt index e95bc3378423..be4af868b740 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt @@ -575,6 +575,98 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { } @Test + fun shouldHomeStatusBarBeVisible_keyguardNotGone_noHun_false() = + kosmos.runTest { + // Do not transition from keyguard. i.e., we don't call transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isFalse() + } + + @Test + fun shouldHomeStatusBarBeVisible_keyguardNotGone_hun_true() = + kosmos.runTest { + // Keyguard gone + transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + // there is an active HUN + headsUpNotificationRepository.setNotifications( + UnconfinedFakeHeadsUpRowRepository( + key = "key", + pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser), + ) + ) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isTrue() + } + + @Test + fun shouldHomeStatusBarBeVisible_keyguardGone_noHun_notInCamera_true() = + kosmos.runTest { + // Keyguard gone + transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isTrue() + } + + @Test + fun shouldHomeStatusBarBeVisible_keyguardGone_hun_notInCamera_true() = + kosmos.runTest { + // Keyguard gone + transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + // there is an active HUN + headsUpNotificationRepository.setNotifications( + UnconfinedFakeHeadsUpRowRepository( + key = "key", + pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser), + ) + ) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isTrue() + } + + @Test + fun shouldHomeStatusBarBeVisible_keyguardGone_noHun_inCamera_false() = + kosmos.runTest { + // Keyguard gone + transitionKeyguardToGone() + + // Nothing disabled + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + fakeKeyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.OCCLUDED, + testScope = testScope, + ) + kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) + + val latest by collectLastValue(underTest.shouldHomeStatusBarBeVisible) + assertThat(latest).isFalse() + } + + @Test fun isClockVisible_allowedByDisableFlags_visible() = kosmos.runTest { val latest by collectLastValue(underTest.isClockVisible) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt index 057213fa4b18..f1d3b31f43a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarRootModernization.kt @@ -25,6 +25,8 @@ object StatusBarRootModernization { /** Aconfig flag for removing the fragment */ const val FLAG_NAME = Flags.FLAG_STATUS_BAR_ROOT_MODERNIZATION + const val SHOW_DISAMBIGUATION = true + /** A token used for dependency declaration */ val token: FlagToken get() = FlagToken(FLAG_NAME, isEnabled) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt index 71e19188f309..9dc283f8ac5f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.view.isVisible import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.app.tracing.coroutines.launchTraced as launch import com.android.compose.theme.PlatformTheme @@ -39,6 +40,7 @@ import com.android.keyguard.AlphaOptimizedLinearLayout import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.res.R import com.android.systemui.statusbar.chips.ui.compose.OngoingActivityChips +import com.android.systemui.statusbar.core.StatusBarRootModernization import com.android.systemui.statusbar.data.repository.DarkIconDispatcherStore import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor import com.android.systemui.statusbar.featurepods.popups.StatusBarPopupChips @@ -146,6 +148,8 @@ fun StatusBarRoot( Row(Modifier.fillMaxSize()) { val scope = rememberCoroutineScope() + val visible = + statusBarViewModel.shouldHomeStatusBarBeVisible.collectAsStateWithLifecycle(false) AndroidView( factory = { context -> val inflater = LayoutInflater.from(context) @@ -280,7 +284,12 @@ fun StatusBarRoot( } onViewCreated(phoneStatusBarView) phoneStatusBarView - } + }, + update = { view -> + // Show or hide the entire status bar. This is important so that we aren't + // visible when first inflated + view.isVisible = visible.value + }, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt index d9d9a29ee2b6..6ff4354fcc46 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt @@ -80,6 +80,9 @@ import kotlinx.coroutines.flow.stateIn * so that it's all in one place and easily testable outside of the fragment. */ interface HomeStatusBarViewModel { + /** Should the entire status bar be hidden? */ + val shouldHomeStatusBarBeVisible: Flow<Boolean> + /** * True if the device is currently transitioning from lockscreen to occluded and false * otherwise. @@ -271,10 +274,12 @@ constructor( isHomeScreenStatusBarAllowedLegacy } - private val shouldHomeStatusBarBeVisible = - combine(isHomeStatusBarAllowed, keyguardInteractor.isSecureCameraActive) { + override val shouldHomeStatusBarBeVisible = + combine( isHomeStatusBarAllowed, - isSecureCameraActive -> + keyguardInteractor.isSecureCameraActive, + headsUpNotificationInteractor.statusBarHeadsUpStatus, + ) { isHomeStatusBarAllowed, isSecureCameraActive, headsUpState -> // When launching the camera over the lockscreen, the status icons would typically // become visible momentarily before animating out, since we're not yet aware that the // launching camera activity is fullscreen. Even once the activity finishes launching, @@ -282,7 +287,7 @@ constructor( // tells us to hide them. // To ensure that this high-visibility animation is smooth, keep the icons hidden during // a camera launch. See b/257292822. - isHomeStatusBarAllowed && !isSecureCameraActive + headsUpState.isPinned || (isHomeStatusBarAllowed && !isSecureCameraActive) } private val isAnyChipVisible = |