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

Commit 2def6f9a authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[SB Refactor] Migrate mobile's `state.visible` to the new pipeline.

StatusBarMobileView uses `MobileIconState.visible` to determine its
visibility status. Following all the inputs to `visible`, then
`visible = hasMobileData && !airplaneMode && !forceHiddenByTuning`. This
CL implements that boolean logic.

Bug: 238425913
Fixes: 267786582
Test: manual: turn on airplane mode and verify mobile triangle is hidden
every where. Turn off airplane mode and verify triangle re-appears.
Test: `adb shell pm enable com.android.systemui/.tuner.TunerActivity`
then Settings > System > System UI Tuner > Status bar > Toggle the
mobile
on/off and see the mobile icon toggle as well
Test: atest MobileIconViewModelTest

Change-Id: I5986ba477ba5172480ab4a5f7b9900259a8466ea
parent 83e77635
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -111,6 +111,9 @@ interface MobileIconInteractor {

    /** Based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL], either 4 or 5 */
    val numberOfLevels: StateFlow<Int>

    /** See [MobileIconsInteractor.isForceHidden]. */
    val isForceHidden: Flow<Boolean>
}

/** Interactor for a single mobile connection. This connection _should_ have one subscription ID */
@@ -126,6 +129,7 @@ class MobileIconInteractorImpl(
    defaultMobileIconGroup: StateFlow<MobileIconGroup>,
    defaultDataSubId: StateFlow<Int>,
    override val isDefaultConnectionFailed: StateFlow<Boolean>,
    override val isForceHidden: Flow<Boolean>,
    connectionRepository: MobileConnectionRepository,
) : MobileIconInteractor {
    private val connectionInfo = connectionRepository.connectionInfo
+14 −1
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConn
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.util.CarrierConfigTracker
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -45,8 +47,8 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.transformLatest

@@ -91,6 +93,10 @@ interface MobileIconsInteractor {
    val isDefaultConnectionFailed: StateFlow<Boolean>
    /** True once the user has been set up */
    val isUserSetup: StateFlow<Boolean>

    /** True if we're configured to force-hide the mobile icons and false otherwise. */
    val isForceHidden: Flow<Boolean>

    /**
     * Vends out a [MobileIconInteractor] tracking the [MobileConnectionRepository] for the given
     * subId. Will throw if the ID is invalid
@@ -108,6 +114,7 @@ constructor(
    private val carrierConfigTracker: CarrierConfigTracker,
    private val logger: ConnectivityPipelineLogger,
    @MobileSummaryLog private val tableLogger: TableLogBuffer,
    connectivityRepository: ConnectivityRepository,
    userSetupRepo: UserSetupRepository,
    @Application private val scope: CoroutineScope,
) : MobileIconsInteractor {
@@ -291,6 +298,11 @@ constructor(

    override val isUserSetup: StateFlow<Boolean> = userSetupRepo.isUserSetupFlow

    override val isForceHidden: Flow<Boolean> =
        connectivityRepository.forceHiddenSlots
            .map { it.contains(ConnectivitySlot.MOBILE) }
            .stateIn(scope, SharingStarted.WhileSubscribed(), false)

    /** Vends out new [MobileIconInteractor] for a particular subId */
    override fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor =
        MobileIconInteractorImpl(
@@ -303,6 +315,7 @@ constructor(
            defaultMobileIconGroup,
            defaultDataSubId,
            isDefaultConnectionFailed,
            isForceHidden,
            mobileConnectionsRepo.getRepoForSubId(subId),
        )

+3 −2
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ object MobileIconBinder {
                    }
                }

                launch { viewModel.isVisible.collect { isVisible -> view.isVisible = isVisible } }

                // Set the icon for the triangle
                launch {
                    viewModel.icon.distinctUntilChanged().collect { icon ->
@@ -153,8 +155,7 @@ object MobileIconBinder {

        return object : ModernStatusBarViewBinding {
            override fun getShouldIconBeVisible(): Boolean {
                // If this view model exists, then the icon should be visible.
                return true
                return viewModel.isVisible.value
            }

            override fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int) {
+24 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.settingslib.graph.SignalDrawable
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel
@@ -42,6 +43,8 @@ import kotlinx.coroutines.flow.stateIn
/** Common interface for all of the location-based mobile icon view models. */
interface MobileIconViewModelCommon {
    val subscriptionId: Int
    /** True if this view should be visible at all. */
    val isVisible: StateFlow<Boolean>
    val icon: Flow<SignalIconModel>
    val contentDescription: Flow<ContentDescription>
    val roaming: Flow<Boolean>
@@ -71,6 +74,7 @@ class MobileIconViewModel
constructor(
    override val subscriptionId: Int,
    iconInteractor: MobileIconInteractor,
    airplaneModeInteractor: AirplaneModeInteractor,
    constants: ConnectivityConstants,
    scope: CoroutineScope,
) : MobileIconViewModelCommon {
@@ -78,6 +82,26 @@ constructor(
    private val showExclamationMark: Flow<Boolean> =
        iconInteractor.isDefaultDataEnabled.mapLatest { !it }

    override val isVisible: StateFlow<Boolean> =
        if (!constants.hasDataCapabilities) {
                flowOf(false)
            } else {
                combine(
                    airplaneModeInteractor.isAirplaneMode,
                    iconInteractor.isForceHidden,
                ) { isAirplaneMode, isForceHidden ->
                    !isAirplaneMode && !isForceHidden
                }
            }
            .distinctUntilChanged()
            .logDiffsForTable(
                iconInteractor.tableLogBuffer,
                columnPrefix = "",
                columnName = "visible",
                initialValue = false,
            )
            .stateIn(scope, SharingStarted.WhileSubscribed(), false)

    override val icon: Flow<SignalIconModel> = run {
        val initial = SignalIconModel.createEmptyState(iconInteractor.numberOfLevels.value)
        combine(
+7 −0
Original line number Diff line number Diff line
@@ -17,9 +17,11 @@
package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel

import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.statusbar.phone.StatusBarLocation
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
@@ -39,6 +41,7 @@ class MobileIconsViewModel
constructor(
    val subscriptionIdsFlow: StateFlow<List<Int>>,
    private val interactor: MobileIconsInteractor,
    private val airplaneModeInteractor: AirplaneModeInteractor,
    private val logger: ConnectivityPipelineLogger,
    private val constants: ConnectivityConstants,
    @Application private val scope: CoroutineScope,
@@ -56,6 +59,7 @@ constructor(
                ?: MobileIconViewModel(
                        subId,
                        interactor.createMobileConnectionInteractorForSubId(subId),
                        airplaneModeInteractor,
                        constants,
                        scope,
                    )
@@ -73,10 +77,12 @@ constructor(
        subIdsToRemove.forEach { mobileIconSubIdCache.remove(it) }
    }

    @SysUISingleton
    class Factory
    @Inject
    constructor(
        private val interactor: MobileIconsInteractor,
        private val airplaneModeInteractor: AirplaneModeInteractor,
        private val logger: ConnectivityPipelineLogger,
        private val constants: ConnectivityConstants,
        @Application private val scope: CoroutineScope,
@@ -86,6 +92,7 @@ constructor(
            return MobileIconsViewModel(
                subscriptionIdsFlow,
                interactor,
                airplaneModeInteractor,
                logger,
                constants,
                scope,
Loading