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

Commit 690bb603 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[SB][Chips] Hide chips on lockscreen when ChipsModernization is enabled

We already have a flow for this, just need to hook it up to Compose
land.

Fixes: 397506204
Bug: 372657935
Flag: com.android.systemui.status_bar_chips_modernization
Test: With ChipsModernization on, trigger chip then go to lockscreen ->
verify it's not there
Test: atest HomeStatusBarViewModelImplTest

Change-Id: If0ff461bd1c2353632bf3ba3124f054cddbd4795
parent 1d4e1ab1
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationSt
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
import com.android.systemui.statusbar.phone.domain.interactor.IsAreaDark
import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.ChipsVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import kotlinx.coroutines.flow.Flow
@@ -52,7 +53,10 @@ class FakeHomeStatusBarViewModel(
    override val primaryOngoingActivityChip: MutableStateFlow<OngoingActivityChipModel> =
        MutableStateFlow(OngoingActivityChipModel.Inactive())

    override val ongoingActivityChips = MutableStateFlow(MultipleOngoingActivityChipsModel())
    override val ongoingActivityChips =
        MutableStateFlow(
            ChipsVisibilityModel(MultipleOngoingActivityChipsModel(), areChipsAllowed = false)
        )

    override val ongoingActivityChipsLegacy =
        MutableStateFlow(MultipleOngoingActivityChipsModelLegacy())
+136 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import com.android.systemui.statusbar.chips.mediaprojection.domain.model.MediaPr
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.shareToAppChipViewModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsCallChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsScreenRecordChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsShareToAppChip
import com.android.systemui.statusbar.core.StatusBarRootModernization
@@ -88,6 +89,7 @@ import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
import com.android.systemui.statusbar.phone.data.repository.fakeDarkIconRepository
import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.addOngoingCallState
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarIconBlockList
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarInteractorShowOperatorName
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
@@ -787,6 +789,140 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
            assertThat(latest).isTrue()
        }

    @Test
    @EnableChipsModernization
    fun ongoingActivityChips_statusBarHidden_noSecureCamera_noHun_notAllowed() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingActivityChips)

            // home status bar not allowed
            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
            kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, taskInfo = null)

            assertThat(latest!!.areChipsAllowed).isFalse()
        }

    @Test
    @EnableChipsModernization
    fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_noHun_isAllowed() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingActivityChips)

            transitionKeyguardToGone()

            assertThat(latest!!.areChipsAllowed).isTrue()
        }

    @Test
    @EnableChipsModernization
    fun ongoingActivityChips_statusBarNotHidden_secureCamera_noHun_notAllowed() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingActivityChips)

            fakeKeyguardTransitionRepository.sendTransitionSteps(
                from = KeyguardState.LOCKSCREEN,
                to = KeyguardState.OCCLUDED,
                testScope = testScope,
            )
            kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)

            assertThat(latest!!.areChipsAllowed).isFalse()
        }

    @Test
    @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
    @EnableChipsModernization
    fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOff_notAllowed() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingActivityChips)

            transitionKeyguardToGone()

            headsUpNotificationRepository.setNotifications(
                UnconfinedFakeHeadsUpRowRepository(
                    key = "key",
                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
                )
            )

            assertThat(latest!!.areChipsAllowed).isFalse()
        }

    @Test
    @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
    @EnableChipsModernization
    fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOff_isAllowed() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingActivityChips)

            transitionKeyguardToGone()

            headsUpNotificationRepository.setNotifications(
                UnconfinedFakeHeadsUpRowRepository(
                    key = "key",
                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
                )
            )

            assertThat(latest!!.areChipsAllowed).isTrue()
        }

    @Test
    @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
    @EnableChipsModernization
    fun ongoingActivityChips_tatusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_isAllowed() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingActivityChips)

            transitionKeyguardToGone()

            headsUpNotificationRepository.setNotifications(
                UnconfinedFakeHeadsUpRowRepository(
                    key = "key",
                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
                )
            )

            assertThat(latest!!.areChipsAllowed).isTrue()
        }

    @Test
    @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
    @EnableChipsModernization
    fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOn_isAllowed() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingActivityChips)

            transitionKeyguardToGone()

            headsUpNotificationRepository.setNotifications(
                UnconfinedFakeHeadsUpRowRepository(
                    key = "key",
                    pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
                )
            )

            assertThat(latest!!.areChipsAllowed).isTrue()
        }

    @Test
    @EnableFlags(StatusBarNotifChips.FLAG_NAME)
    @EnableChipsModernization
    fun ongoingActivityChips_followsChipsViewModel() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingActivityChips)
            transitionKeyguardToGone()

            screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording

            assertIsScreenRecordChip(latest!!.chips.active[0])

            addOngoingCallState(key = "call")

            assertIsScreenRecordChip(latest!!.chips.active[0])
            assertIsCallChip(latest!!.chips.active[1], "call")
        }

    @Test
    fun isClockVisible_allowedByDisableFlags_visible() =
        kosmos.runTest {
+7 −5
Original line number Diff line number Diff line
@@ -196,16 +196,18 @@ fun StatusBarRoot(

                                setContent {
                                    PlatformTheme {
                                        val chips by
                                        val chipsVisibilityModel by
                                            statusBarViewModel.ongoingActivityChips
                                                .collectAsStateWithLifecycle()
                                        if (chipsVisibilityModel.areChipsAllowed) {
                                            OngoingActivityChips(
                                            chips = chips,
                                                chips = chipsVisibilityModel.chips,
                                                iconViewStore = iconViewStore,
                                            )
                                        }
                                    }
                                }
                            }

                        // Add the composable container for ongoingActivityChips before the
                        // notification_icon_area to maintain the same ordering for ongoing activity
+27 −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.statusbar.pipeline.shared.ui.model

import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel

data class ChipsVisibilityModel(
    val chips: MultipleOngoingActivityChipsModel,
    /**
     * True if the chips are allowed to be shown and false otherwise (e.g. if we're on lockscreen).
     */
    val areChipsAllowed: Boolean,
)
+18 −4
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernizat
import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewModel
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.HomeStatusBarIconBlockListInteractor
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.HomeStatusBarInteractor
import com.android.systemui.statusbar.pipeline.shared.ui.model.ChipsVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import dagger.assisted.Assisted
@@ -125,7 +126,7 @@ interface HomeStatusBarViewModel : Activatable {
    val primaryOngoingActivityChip: StateFlow<OngoingActivityChipModel>

    /** All supported activity chips, whether they are currently active or not. */
    val ongoingActivityChips: StateFlow<MultipleOngoingActivityChipsModel>
    val ongoingActivityChips: StateFlow<ChipsVisibilityModel>

    /**
     * The multiple ongoing activity chips that should be shown on the left-hand side of the status
@@ -252,8 +253,6 @@ constructor(

    override val primaryOngoingActivityChip = ongoingActivityChipsViewModel.primaryChip

    override val ongoingActivityChips = ongoingActivityChipsViewModel.chips

    override val ongoingActivityChipsLegacy = ongoingActivityChipsViewModel.chipsLegacy

    override val popupChips
@@ -415,9 +414,24 @@ constructor(
            isHomeStatusBarAllowed && !isSecureCameraActive && !hideStartSideContentForHeadsUp
        }

    override val ongoingActivityChips =
        combine(ongoingActivityChipsViewModel.chips, canShowOngoingActivityChips) { chips, canShow
                ->
                ChipsVisibilityModel(chips, areChipsAllowed = canShow)
            }
            .stateIn(
                bgScope,
                SharingStarted.WhileSubscribed(),
                initialValue =
                    ChipsVisibilityModel(
                        chips = MultipleOngoingActivityChipsModel(),
                        areChipsAllowed = false,
                    ),
            )

    private val hasOngoingActivityChips =
        if (StatusBarChipsModernization.isEnabled) {
            ongoingActivityChips.map { it.active.any { chip -> !chip.isHidden } }
            ongoingActivityChips.map { it.chips.active.any { chip -> !chip.isHidden } }
        } else if (StatusBarNotifChips.isEnabled) {
            ongoingActivityChipsLegacy.map { it.primary is OngoingActivityChipModel.Active }
        } else {