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

Commit 30131318 authored by Evan Laird's avatar Evan Laird Committed by Automerger Merge Worker
Browse files

Merge "[Sb refactor] Add `dataEnabled` tracking to mobile repos" into tm-qpr-dev am: 10e2996b

parents c2f7a291 10e2996b
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.mobile.data.model

import android.telephony.TelephonyManager.DATA_CONNECTED
import android.telephony.TelephonyManager.DATA_CONNECTING
import android.telephony.TelephonyManager.DATA_DISCONNECTED
import android.telephony.TelephonyManager.DATA_DISCONNECTING
import android.telephony.TelephonyManager.DataState

/** Internal enum representation of the telephony data connection states */
enum class DataConnectionState(@DataState val dataState: Int) {
    Connected(DATA_CONNECTED),
    Connecting(DATA_CONNECTING),
    Disconnected(DATA_DISCONNECTED),
    Disconnecting(DATA_DISCONNECTING),
}

fun @receiver:DataState Int.toDataConnectionType(): DataConnectionState =
    when (this) {
        DATA_CONNECTED -> DataConnectionState.Connected
        DATA_CONNECTING -> DataConnectionState.Connecting
        DATA_DISCONNECTED -> DataConnectionState.Disconnected
        DATA_DISCONNECTING -> DataConnectionState.Disconnecting
        else -> throw IllegalArgumentException("unknown data state received")
    }
+4 −3
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.telephony.TelephonyCallback.SignalStrengthsListener
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Disconnected

/**
 * Data class containing all of the relevant information for a particular line of service, known as
@@ -49,14 +50,14 @@ data class MobileSubscriptionModel(
    @IntRange(from = 0, to = 4)
    val primaryLevel: Int = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,

    /** Comes directly from [DataConnectionStateListener.onDataConnectionStateChanged] */
    val dataConnectionState: Int? = null,
    /** Mapped from [DataConnectionStateListener.onDataConnectionStateChanged] */
    val dataConnectionState: DataConnectionState = Disconnected,

    /** From [DataActivityListener.onDataActivity]. See [TelephonyManager] for the values */
    @DataActivityType val dataActivityDirection: Int? = null,

    /** From [CarrierNetworkListener.onCarrierNetworkChange] */
    val carrierNetworkChangeActive: Boolean? = null,
    val carrierNetworkChangeActive: Boolean = false,

    /**
     * From [DisplayInfoListener.onDisplayInfoChanged].
+20 −4
Original line number Diff line number Diff line
@@ -31,7 +31,9 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.pipeline.mobile.data.model.DefaultNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.OverrideNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
import java.lang.IllegalStateException
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -42,7 +44,7 @@ import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn

/**
@@ -62,13 +64,15 @@ interface MobileConnectionRepository {
     * listener + model.
     */
    val subscriptionModelFlow: Flow<MobileSubscriptionModel>
    /** Observable tracking [TelephonyManager.isDataConnectionAllowed] */
    val dataEnabled: Flow<Boolean>
}

@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@OptIn(ExperimentalCoroutinesApi::class)
class MobileConnectionRepositoryImpl(
    private val subId: Int,
    telephonyManager: TelephonyManager,
    private val telephonyManager: TelephonyManager,
    bgDispatcher: CoroutineDispatcher,
    logger: ConnectivityPipelineLogger,
    scope: CoroutineScope,
@@ -127,7 +131,8 @@ class MobileConnectionRepositoryImpl(
                            dataState: Int,
                            networkType: Int
                        ) {
                            state = state.copy(dataConnectionState = dataState)
                            state =
                                state.copy(dataConnectionState = dataState.toDataConnectionType())
                            trySend(state)
                        }

@@ -160,10 +165,21 @@ class MobileConnectionRepositoryImpl(
                telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback)
                awaitClose { telephonyManager.unregisterTelephonyCallback(callback) }
            }
            .onEach { logger.logOutputChange("mobileSubscriptionModel", it.toString()) }
            .logOutputChange(logger, "MobileSubscriptionModel")
            .stateIn(scope, SharingStarted.WhileSubscribed(), state)
    }

    /**
     * There are a few cases where we will need to poll [TelephonyManager] so we can update some
     * internal state where callbacks aren't provided. Any of those events should be merged into
     * this flow, which can be used to trigger the polling.
     */
    private val telephonyPollingEvent: Flow<Unit> = subscriptionModelFlow.map {}

    override val dataEnabled: Flow<Boolean> = telephonyPollingEvent.map { dataConnectionAllowed() }

    private fun dataConnectionAllowed(): Boolean = telephonyManager.isDataConnectionAllowed

    class Factory
    @Inject
    constructor(
+5 −0
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map

interface MobileIconInteractor {
    /** Observable for the data enabled state of this connection */
    val isDataEnabled: Flow<Boolean>

    /** Observable for RAT type (network type) indicator */
    val networkTypeIconGroup: Flow<MobileIconGroup>

@@ -54,6 +57,8 @@ class MobileIconInteractorImpl(
) : MobileIconInteractor {
    private val mobileStatusInfo = connectionRepository.subscriptionModelFlow

    override val isDataEnabled: Flow<Boolean> = connectionRepository.dataEnabled

    /** Observable for the current RAT indicator icon ([MobileIconGroup]) */
    override val networkTypeIconGroup: Flow<MobileIconGroup> =
        combine(
+18 −6
Original line number Diff line number Diff line
@@ -23,12 +23,14 @@ import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
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.mobile.util.MobileMappingsProxy
import com.android.systemui.util.CarrierConfigTracker
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -47,28 +49,38 @@ import kotlinx.coroutines.flow.stateIn
 * icon
 */
interface MobileIconsInteractor {
    /** List of subscriptions, potentially filtered for CBRS */
    val filteredSubscriptions: Flow<List<SubscriptionInfo>>
    /** The icon mapping from network type to [MobileIconGroup] for the default subscription */
    val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>>
    /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */
    val defaultMobileIconGroup: Flow<MobileIconGroup>
    /** True once the user has been set up */
    val isUserSetup: Flow<Boolean>
    /**
     * Vends out a [MobileIconInteractor] tracking the [MobileConnectionRepository] for the given
     * subId. Will throw if the ID is invalid
     */
    fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor
}

@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class MobileIconsInteractorImpl
@Inject
constructor(
    private val mobileSubscriptionRepo: MobileConnectionsRepository,
    private val mobileConnectionsRepo: MobileConnectionsRepository,
    private val carrierConfigTracker: CarrierConfigTracker,
    private val mobileMappingsProxy: MobileMappingsProxy,
    userSetupRepo: UserSetupRepository,
    @Application private val scope: CoroutineScope,
) : MobileIconsInteractor {
    private val activeMobileDataSubscriptionId =
        mobileSubscriptionRepo.activeMobileDataSubscriptionId
        mobileConnectionsRepo.activeMobileDataSubscriptionId

    private val unfilteredSubscriptions: Flow<List<SubscriptionInfo>> =
        mobileSubscriptionRepo.subscriptionsFlow
        mobileConnectionsRepo.subscriptionsFlow

    /**
     * Generally, SystemUI wants to show iconography for each subscription that is listed by
@@ -119,13 +131,13 @@ constructor(
     * subscription Id. This mapping is the same for every subscription.
     */
    override val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>> =
        mobileSubscriptionRepo.defaultDataSubRatConfig
        mobileConnectionsRepo.defaultDataSubRatConfig
            .map { mobileMappingsProxy.mapIconSets(it) }
            .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = mapOf())

    /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */
    override val defaultMobileIconGroup: StateFlow<MobileIconGroup> =
        mobileSubscriptionRepo.defaultDataSubRatConfig
        mobileConnectionsRepo.defaultDataSubRatConfig
            .map { mobileMappingsProxy.getDefaultIcons(it) }
            .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = TelephonyIcons.G)

@@ -137,6 +149,6 @@ constructor(
            defaultMobileIconMapping,
            defaultMobileIconGroup,
            mobileMappingsProxy,
            mobileSubscriptionRepo.getRepoForSubId(subId),
            mobileConnectionsRepo.getRepoForSubId(subId),
        )
}
Loading