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

Commit 48309d47 authored by Evan Laird's avatar Evan Laird
Browse files

[sb] operator name view model for home status bar

This implements a StatusBarOperatorNameViewModel and Binder which mimic
the old behavior of the operator name view.

Test: HomeStatusBarViewModelImplTest
Test: StatusBarOperatorNameViewModelTest
Test: manual
Bug: 364360986
Flag: com.android.systemui.status_bar_root_modernization
Change-Id: Iee34f1972fe0feef8e35a543fdc3ccf57861ff69
parent 298f1eb2
Loading
Loading
Loading
Loading
+118 −4
Original line number Diff line number Diff line
@@ -21,13 +21,25 @@ import android.app.StatusBarManager.DISABLE_CLOCK
import android.app.StatusBarManager.DISABLE_NONE
import android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS
import android.app.StatusBarManager.DISABLE_SYSTEM_INFO
import android.telephony.CarrierConfigManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
import com.android.systemui.statusbar.pipeline.airplane.data.repository.airplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.data.repository.fake
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
import com.android.systemui.statusbar.pipeline.mobile.data.repository.carrierConfigRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.configWithOverride
import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.fakeMobileIconsInteractor
import com.android.systemui.statusbar.pipeline.shared.connectivityConstants
import com.android.systemui.statusbar.pipeline.shared.fake
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
@@ -45,7 +57,7 @@ class CollapsedStatusBarInteractorTest : SysuiTestCase() {

    @Test
    fun visibilityViaDisableFlags_allDisabled() =
        testScope.runTest {
        kosmos.runTest {
            val latest by collectLastValue(underTest.visibilityViaDisableFlags)

            disableFlagsRepo.disableFlags.value =
@@ -62,7 +74,7 @@ class CollapsedStatusBarInteractorTest : SysuiTestCase() {

    @Test
    fun visibilityViaDisableFlags_allEnabled() =
        testScope.runTest {
        kosmos.runTest {
            val latest by collectLastValue(underTest.visibilityViaDisableFlags)

            disableFlagsRepo.disableFlags.value =
@@ -75,7 +87,7 @@ class CollapsedStatusBarInteractorTest : SysuiTestCase() {

    @Test
    fun visibilityViaDisableFlags_animateFalse() =
        testScope.runTest {
        kosmos.runTest {
            val latest by collectLastValue(underTest.visibilityViaDisableFlags)

            disableFlagsRepo.disableFlags.value =
@@ -86,7 +98,7 @@ class CollapsedStatusBarInteractorTest : SysuiTestCase() {

    @Test
    fun visibilityViaDisableFlags_animateTrue() =
        testScope.runTest {
        kosmos.runTest {
            val latest by collectLastValue(underTest.visibilityViaDisableFlags)

            disableFlagsRepo.disableFlags.value =
@@ -94,4 +106,106 @@ class CollapsedStatusBarInteractorTest : SysuiTestCase() {

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

    @Test
    fun shouldShowOperatorName_trueIfCarrierConfigSaysSoAndDeviceHasData() =
        kosmos.runTest {
            // GIVEN default data subId is 1
            fakeMobileIconsInteractor.defaultDataSubId.value = 1
            // GIVEN Config is enabled
            carrierConfigRepository.fake.configsById[1] =
                SystemUiCarrierConfig(
                    1,
                    configWithOverride(
                        CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL,
                        true,
                    ),
                )

            // GIVEN airplane mode is off
            airplaneModeRepository.fake.isAirplaneMode.value = false

            // GIVEN hasDataCapabilities is true
            connectivityConstants.fake.hasDataCapabilities = true

            val latest by collectLastValue(underTest.shouldShowOperatorName)

            // THEN we should show the operator name
            assertThat(latest).isTrue()
        }

    @Test
    fun shouldShowOperatorName_falseNoDataCapabilities() =
        kosmos.runTest {
            // GIVEN default data subId is 1
            fakeMobileIconsInteractor.defaultDataSubId.value = 1
            // GIVEN Config is enabled
            carrierConfigRepository.fake.configsById[1] =
                SystemUiCarrierConfig(
                    1,
                    configWithOverride(
                        CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL,
                        true,
                    ),
                )

            // GIVEN airplane mode is off
            airplaneModeRepository.fake.isAirplaneMode.value = true

            // WHEN hasDataCapabilities is false
            connectivityConstants.fake.hasDataCapabilities = false

            val latest by collectLastValue(underTest.shouldShowOperatorName)

            // THEN we should not show the operator name
            assertThat(latest).isFalse()
        }

    @Test
    fun shouldShowOperatorName_falseWhenConfigIsOff() =
        kosmos.runTest {
            // GIVEN default data subId is 1
            fakeMobileIconsInteractor.defaultDataSubId.value = 1
            // GIVEN airplane mode is off
            airplaneModeRepository.fake.isAirplaneMode.value = false

            // WHEN Config is disabled
            carrierConfigRepository.fake.configsById[1] =
                SystemUiCarrierConfig(
                    1,
                    configWithOverride(
                        CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL,
                        false,
                    ),
                )

            val latest by collectLastValue(underTest.shouldShowOperatorName)

            // THEN we should not show the operator name
            assertThat(latest).isFalse()
        }

    @Test
    fun shouldShowOperatorName_falseIfAirplaneMode() =
        kosmos.runTest {
            // GIVEN default data subId is 1
            fakeMobileIconsInteractor.defaultDataSubId.value = 1
            // GIVEN Config is enabled
            carrierConfigRepository.fake.configsById[1] =
                SystemUiCarrierConfig(
                    1,
                    configWithOverride(
                        CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL,
                        true,
                    ),
                )

            // WHEN airplane mode is on
            airplaneModeRepository.fake.isAirplaneMode.value = true

            val latest by collectLastValue(underTest.shouldShowOperatorName)

            // THEN we should not show the operator name
            assertThat(latest).isFalse()
        }
}
+6 −2
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 * Copyright (C) 2024 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.
@@ -27,7 +27,9 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow

class FakeHomeStatusBarViewModel : HomeStatusBarViewModel {
class FakeHomeStatusBarViewModel(
    override val operatorNameViewModel: StatusBarOperatorNameViewModel
) : HomeStatusBarViewModel {
    private val areNotificationLightsOut = MutableStateFlow(false)

    override val isTransitioningFromLockscreenToOccluded = MutableStateFlow(false)
@@ -41,6 +43,8 @@ class FakeHomeStatusBarViewModel : HomeStatusBarViewModel {

    override val isHomeStatusBarAllowedByScene = MutableStateFlow(false)

    override val shouldShowOperatorNameView = MutableStateFlow(false)

    override val isClockVisible =
        MutableStateFlow(
            HomeStatusBarViewModel.VisibilityModel(
+67 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataS
import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
import com.android.systemui.statusbar.phone.data.repository.fakeDarkIconRepository
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setCollapsedStatusBarInteractorShowOperatorName
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -499,6 +500,72 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
            assertThat(latest).isTrue()
        }

    @Test
    fun shouldShowOperatorNameView_allowedByInteractor_allowedByDisableFlags_visible() =
        kosmos.runTest {
            kosmos.setCollapsedStatusBarInteractorShowOperatorName(true)

            val latest by collectLastValue(underTest.shouldShowOperatorNameView)
            transitionKeyguardToGone()

            fakeDisableFlagsRepository.disableFlags.value =
                DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)

            assertThat(latest).isTrue()
        }

    @Test
    fun shouldShowOperatorNameView_disAllowedByInteractor_allowedByDisableFlags_notVisible() =
        kosmos.runTest {
            kosmos.setCollapsedStatusBarInteractorShowOperatorName(false)

            transitionKeyguardToGone()

            fakeDisableFlagsRepository.disableFlags.value =
                DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE)

            val latest by collectLastValue(underTest.shouldShowOperatorNameView)

            assertThat(latest).isFalse()
        }

    @Test
    fun shouldShowOperatorNameView_allowedByInteractor_disallowedByDisableFlags_notVisible() =
        kosmos.runTest {
            kosmos.setCollapsedStatusBarInteractorShowOperatorName(true)

            val latest by collectLastValue(underTest.shouldShowOperatorNameView)
            transitionKeyguardToGone()

            fakeDisableFlagsRepository.disableFlags.value =
                DisableFlagsModel(DISABLE_SYSTEM_INFO, DISABLE2_NONE)

            assertThat(latest).isFalse()
        }

    @Test
    fun shouldShowOperatorNameView_allowedByInteractor_hunPinned_false() =
        kosmos.runTest {
            kosmos.setCollapsedStatusBarInteractorShowOperatorName(false)

            transitionKeyguardToGone()

            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.shouldShowOperatorNameView)

            assertThat(latest).isFalse()
        }

    @Test
    fun isClockVisible_allowedByDisableFlags_visible() =
        kosmos.runTest {
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.fakeMobileIconsInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class StatusBarOperatorNameViewModelTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val Kosmos.underTest by Kosmos.Fixture { kosmos.statusBarOperatorNameViewModel }

    @Test
    fun operatorName_tracksDefaultDataCarrierName() =
        kosmos.runTest {
            val intr1 = fakeMobileIconsInteractor.getMobileConnectionInteractorForSubId(1)
            val intr2 = fakeMobileIconsInteractor.getMobileConnectionInteractorForSubId(2)
            val invalidIntr = fakeMobileIconsInteractor.getMobileConnectionInteractorForSubId(-1)

            // GIVEN default data subId is 1
            fakeMobileIconsInteractor.defaultDataSubId.value = 1

            intr1.carrierName.value = "Test Name 1"
            intr2.carrierName.value = "Test Name 2"
            invalidIntr.carrierName.value = "default network name"

            val latest by collectLastValue(underTest.operatorName)

            assertThat(latest).isEqualTo("Test Name 1")

            fakeMobileIconsInteractor.defaultDataSubId.value = 2

            assertThat(latest).isEqualTo("Test Name 2")

            fakeMobileIconsInteractor.defaultDataSubId.value = -1

            assertThat(latest).isEqualTo("default network name")
        }
}
+5 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ import com.android.systemui.statusbar.pipeline.satellite.data.RealDeviceBasedSat
import com.android.systemui.statusbar.pipeline.satellite.data.prod.DeviceBasedSatelliteRepositoryImpl
import com.android.systemui.statusbar.pipeline.satellite.ui.viewmodel.DeviceBasedSatelliteViewModel
import com.android.systemui.statusbar.pipeline.satellite.ui.viewmodel.DeviceBasedSatelliteViewModelImpl
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstantsImpl
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
import com.android.systemui.statusbar.pipeline.shared.ui.binder.HomeStatusBarViewBinder
@@ -108,6 +110,9 @@ abstract class StatusBarPipelineModule {
        impl: DeviceBasedSatelliteViewModelImpl
    ): DeviceBasedSatelliteViewModel

    @Binds
    abstract fun connectivityConstants(impl: ConnectivityConstantsImpl): ConnectivityConstants

    @Binds abstract fun wifiRepository(impl: WifiRepositorySwitcher): WifiRepository

    @Binds abstract fun wifiInteractor(impl: WifiInteractorImpl): WifiInteractor
Loading