Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/DataConnectionState.kt 0 → 100644 +40 −0 Original line number Original line 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") } packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileSubscriptionModel.kt +4 −3 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.telephony.TelephonyCallback.SignalStrengthsListener import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyManager import android.telephony.TelephonyManager import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN 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 * Data class containing all of the relevant information for a particular line of service, known as Loading @@ -49,14 +50,14 @@ data class MobileSubscriptionModel( @IntRange(from = 0, to = 4) @IntRange(from = 0, to = 4) val primaryLevel: Int = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, val primaryLevel: Int = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, /** Comes directly from [DataConnectionStateListener.onDataConnectionStateChanged] */ /** Mapped from [DataConnectionStateListener.onDataConnectionStateChanged] */ val dataConnectionState: Int? = null, val dataConnectionState: DataConnectionState = Disconnected, /** From [DataActivityListener.onDataActivity]. See [TelephonyManager] for the values */ /** From [DataActivityListener.onDataActivity]. See [TelephonyManager] for the values */ @DataActivityType val dataActivityDirection: Int? = null, @DataActivityType val dataActivityDirection: Int? = null, /** From [CarrierNetworkListener.onCarrierNetworkChange] */ /** From [CarrierNetworkListener.onCarrierNetworkChange] */ val carrierNetworkChangeActive: Boolean? = null, val carrierNetworkChangeActive: Boolean = false, /** /** * From [DisplayInfoListener.onDisplayInfoChanged]. * From [DisplayInfoListener.onDisplayInfoChanged]. Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt +20 −4 Original line number Original line Diff line number Diff line Loading @@ -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.DefaultNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel 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.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 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange import java.lang.IllegalStateException import java.lang.IllegalStateException import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher Loading @@ -42,7 +44,7 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn /** /** Loading @@ -62,13 +64,15 @@ interface MobileConnectionRepository { * listener + model. * listener + model. */ */ val subscriptionModelFlow: Flow<MobileSubscriptionModel> val subscriptionModelFlow: Flow<MobileSubscriptionModel> /** Observable tracking [TelephonyManager.isDataConnectionAllowed] */ val dataEnabled: Flow<Boolean> } } @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class) class MobileConnectionRepositoryImpl( class MobileConnectionRepositoryImpl( private val subId: Int, private val subId: Int, telephonyManager: TelephonyManager, private val telephonyManager: TelephonyManager, bgDispatcher: CoroutineDispatcher, bgDispatcher: CoroutineDispatcher, logger: ConnectivityPipelineLogger, logger: ConnectivityPipelineLogger, scope: CoroutineScope, scope: CoroutineScope, Loading Loading @@ -127,7 +131,8 @@ class MobileConnectionRepositoryImpl( dataState: Int, dataState: Int, networkType: Int networkType: Int ) { ) { state = state.copy(dataConnectionState = dataState) state = state.copy(dataConnectionState = dataState.toDataConnectionType()) trySend(state) trySend(state) } } Loading Loading @@ -160,10 +165,21 @@ class MobileConnectionRepositoryImpl( telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback) telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback) awaitClose { telephonyManager.unregisterTelephonyCallback(callback) } awaitClose { telephonyManager.unregisterTelephonyCallback(callback) } } } .onEach { logger.logOutputChange("mobileSubscriptionModel", it.toString()) } .logOutputChange(logger, "MobileSubscriptionModel") .stateIn(scope, SharingStarted.WhileSubscribed(), state) .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 class Factory @Inject @Inject constructor( constructor( Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt +5 −0 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,9 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map interface MobileIconInteractor { interface MobileIconInteractor { /** Observable for the data enabled state of this connection */ val isDataEnabled: Flow<Boolean> /** Observable for RAT type (network type) indicator */ /** Observable for RAT type (network type) indicator */ val networkTypeIconGroup: Flow<MobileIconGroup> val networkTypeIconGroup: Flow<MobileIconGroup> Loading @@ -54,6 +57,8 @@ class MobileIconInteractorImpl( ) : MobileIconInteractor { ) : MobileIconInteractor { private val mobileStatusInfo = connectionRepository.subscriptionModelFlow private val mobileStatusInfo = connectionRepository.subscriptionModelFlow override val isDataEnabled: Flow<Boolean> = connectionRepository.dataEnabled /** Observable for the current RAT indicator icon ([MobileIconGroup]) */ /** Observable for the current RAT indicator icon ([MobileIconGroup]) */ override val networkTypeIconGroup: Flow<MobileIconGroup> = override val networkTypeIconGroup: Flow<MobileIconGroup> = combine( combine( Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt +18 −6 Original line number Original line Diff line number Diff line Loading @@ -23,12 +23,14 @@ import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.TelephonyIcons import com.android.settingslib.mobile.TelephonyIcons import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application 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.MobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy import com.android.systemui.util.CarrierConfigTracker import com.android.systemui.util.CarrierConfigTracker import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow Loading @@ -47,28 +49,38 @@ import kotlinx.coroutines.flow.stateIn * icon * icon */ */ interface MobileIconsInteractor { interface MobileIconsInteractor { /** List of subscriptions, potentially filtered for CBRS */ val filteredSubscriptions: Flow<List<SubscriptionInfo>> val filteredSubscriptions: Flow<List<SubscriptionInfo>> /** The icon mapping from network type to [MobileIconGroup] for the default subscription */ val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>> val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>> /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */ val defaultMobileIconGroup: Flow<MobileIconGroup> val defaultMobileIconGroup: Flow<MobileIconGroup> /** True once the user has been set up */ val isUserSetup: Flow<Boolean> 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 fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor } } @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton @SysUISingleton class MobileIconsInteractorImpl class MobileIconsInteractorImpl @Inject @Inject constructor( constructor( private val mobileSubscriptionRepo: MobileConnectionsRepository, private val mobileConnectionsRepo: MobileConnectionsRepository, private val carrierConfigTracker: CarrierConfigTracker, private val carrierConfigTracker: CarrierConfigTracker, private val mobileMappingsProxy: MobileMappingsProxy, private val mobileMappingsProxy: MobileMappingsProxy, userSetupRepo: UserSetupRepository, userSetupRepo: UserSetupRepository, @Application private val scope: CoroutineScope, @Application private val scope: CoroutineScope, ) : MobileIconsInteractor { ) : MobileIconsInteractor { private val activeMobileDataSubscriptionId = private val activeMobileDataSubscriptionId = mobileSubscriptionRepo.activeMobileDataSubscriptionId mobileConnectionsRepo.activeMobileDataSubscriptionId private val unfilteredSubscriptions: Flow<List<SubscriptionInfo>> = private val unfilteredSubscriptions: Flow<List<SubscriptionInfo>> = mobileSubscriptionRepo.subscriptionsFlow mobileConnectionsRepo.subscriptionsFlow /** /** * Generally, SystemUI wants to show iconography for each subscription that is listed by * Generally, SystemUI wants to show iconography for each subscription that is listed by Loading Loading @@ -119,13 +131,13 @@ constructor( * subscription Id. This mapping is the same for every subscription. * subscription Id. This mapping is the same for every subscription. */ */ override val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>> = override val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>> = mobileSubscriptionRepo.defaultDataSubRatConfig mobileConnectionsRepo.defaultDataSubRatConfig .map { mobileMappingsProxy.mapIconSets(it) } .map { mobileMappingsProxy.mapIconSets(it) } .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = mapOf()) .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = mapOf()) /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */ /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */ override val defaultMobileIconGroup: StateFlow<MobileIconGroup> = override val defaultMobileIconGroup: StateFlow<MobileIconGroup> = mobileSubscriptionRepo.defaultDataSubRatConfig mobileConnectionsRepo.defaultDataSubRatConfig .map { mobileMappingsProxy.getDefaultIcons(it) } .map { mobileMappingsProxy.getDefaultIcons(it) } .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = TelephonyIcons.G) .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = TelephonyIcons.G) Loading @@ -137,6 +149,6 @@ constructor( defaultMobileIconMapping, defaultMobileIconMapping, defaultMobileIconGroup, defaultMobileIconGroup, mobileMappingsProxy, mobileMappingsProxy, mobileSubscriptionRepo.getRepoForSubId(subId), mobileConnectionsRepo.getRepoForSubId(subId), ) ) } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/DataConnectionState.kt 0 → 100644 +40 −0 Original line number Original line 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") }
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileSubscriptionModel.kt +4 −3 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.telephony.TelephonyCallback.SignalStrengthsListener import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyManager import android.telephony.TelephonyManager import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN 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 * Data class containing all of the relevant information for a particular line of service, known as Loading @@ -49,14 +50,14 @@ data class MobileSubscriptionModel( @IntRange(from = 0, to = 4) @IntRange(from = 0, to = 4) val primaryLevel: Int = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, val primaryLevel: Int = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, /** Comes directly from [DataConnectionStateListener.onDataConnectionStateChanged] */ /** Mapped from [DataConnectionStateListener.onDataConnectionStateChanged] */ val dataConnectionState: Int? = null, val dataConnectionState: DataConnectionState = Disconnected, /** From [DataActivityListener.onDataActivity]. See [TelephonyManager] for the values */ /** From [DataActivityListener.onDataActivity]. See [TelephonyManager] for the values */ @DataActivityType val dataActivityDirection: Int? = null, @DataActivityType val dataActivityDirection: Int? = null, /** From [CarrierNetworkListener.onCarrierNetworkChange] */ /** From [CarrierNetworkListener.onCarrierNetworkChange] */ val carrierNetworkChangeActive: Boolean? = null, val carrierNetworkChangeActive: Boolean = false, /** /** * From [DisplayInfoListener.onDisplayInfoChanged]. * From [DisplayInfoListener.onDisplayInfoChanged]. Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionRepository.kt +20 −4 Original line number Original line Diff line number Diff line Loading @@ -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.DefaultNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileSubscriptionModel 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.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 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange import java.lang.IllegalStateException import java.lang.IllegalStateException import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher Loading @@ -42,7 +44,7 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn /** /** Loading @@ -62,13 +64,15 @@ interface MobileConnectionRepository { * listener + model. * listener + model. */ */ val subscriptionModelFlow: Flow<MobileSubscriptionModel> val subscriptionModelFlow: Flow<MobileSubscriptionModel> /** Observable tracking [TelephonyManager.isDataConnectionAllowed] */ val dataEnabled: Flow<Boolean> } } @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class) class MobileConnectionRepositoryImpl( class MobileConnectionRepositoryImpl( private val subId: Int, private val subId: Int, telephonyManager: TelephonyManager, private val telephonyManager: TelephonyManager, bgDispatcher: CoroutineDispatcher, bgDispatcher: CoroutineDispatcher, logger: ConnectivityPipelineLogger, logger: ConnectivityPipelineLogger, scope: CoroutineScope, scope: CoroutineScope, Loading Loading @@ -127,7 +131,8 @@ class MobileConnectionRepositoryImpl( dataState: Int, dataState: Int, networkType: Int networkType: Int ) { ) { state = state.copy(dataConnectionState = dataState) state = state.copy(dataConnectionState = dataState.toDataConnectionType()) trySend(state) trySend(state) } } Loading Loading @@ -160,10 +165,21 @@ class MobileConnectionRepositoryImpl( telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback) telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback) awaitClose { telephonyManager.unregisterTelephonyCallback(callback) } awaitClose { telephonyManager.unregisterTelephonyCallback(callback) } } } .onEach { logger.logOutputChange("mobileSubscriptionModel", it.toString()) } .logOutputChange(logger, "MobileSubscriptionModel") .stateIn(scope, SharingStarted.WhileSubscribed(), state) .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 class Factory @Inject @Inject constructor( constructor( Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt +5 −0 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,9 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map interface MobileIconInteractor { interface MobileIconInteractor { /** Observable for the data enabled state of this connection */ val isDataEnabled: Flow<Boolean> /** Observable for RAT type (network type) indicator */ /** Observable for RAT type (network type) indicator */ val networkTypeIconGroup: Flow<MobileIconGroup> val networkTypeIconGroup: Flow<MobileIconGroup> Loading @@ -54,6 +57,8 @@ class MobileIconInteractorImpl( ) : MobileIconInteractor { ) : MobileIconInteractor { private val mobileStatusInfo = connectionRepository.subscriptionModelFlow private val mobileStatusInfo = connectionRepository.subscriptionModelFlow override val isDataEnabled: Flow<Boolean> = connectionRepository.dataEnabled /** Observable for the current RAT indicator icon ([MobileIconGroup]) */ /** Observable for the current RAT indicator icon ([MobileIconGroup]) */ override val networkTypeIconGroup: Flow<MobileIconGroup> = override val networkTypeIconGroup: Flow<MobileIconGroup> = combine( combine( Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt +18 −6 Original line number Original line Diff line number Diff line Loading @@ -23,12 +23,14 @@ import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.mobile.TelephonyIcons import com.android.settingslib.mobile.TelephonyIcons import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application 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.MobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy import com.android.systemui.util.CarrierConfigTracker import com.android.systemui.util.CarrierConfigTracker import javax.inject.Inject import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow Loading @@ -47,28 +49,38 @@ import kotlinx.coroutines.flow.stateIn * icon * icon */ */ interface MobileIconsInteractor { interface MobileIconsInteractor { /** List of subscriptions, potentially filtered for CBRS */ val filteredSubscriptions: Flow<List<SubscriptionInfo>> val filteredSubscriptions: Flow<List<SubscriptionInfo>> /** The icon mapping from network type to [MobileIconGroup] for the default subscription */ val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>> val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>> /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */ val defaultMobileIconGroup: Flow<MobileIconGroup> val defaultMobileIconGroup: Flow<MobileIconGroup> /** True once the user has been set up */ val isUserSetup: Flow<Boolean> 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 fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor } } @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @OptIn(ExperimentalCoroutinesApi::class) @SysUISingleton @SysUISingleton class MobileIconsInteractorImpl class MobileIconsInteractorImpl @Inject @Inject constructor( constructor( private val mobileSubscriptionRepo: MobileConnectionsRepository, private val mobileConnectionsRepo: MobileConnectionsRepository, private val carrierConfigTracker: CarrierConfigTracker, private val carrierConfigTracker: CarrierConfigTracker, private val mobileMappingsProxy: MobileMappingsProxy, private val mobileMappingsProxy: MobileMappingsProxy, userSetupRepo: UserSetupRepository, userSetupRepo: UserSetupRepository, @Application private val scope: CoroutineScope, @Application private val scope: CoroutineScope, ) : MobileIconsInteractor { ) : MobileIconsInteractor { private val activeMobileDataSubscriptionId = private val activeMobileDataSubscriptionId = mobileSubscriptionRepo.activeMobileDataSubscriptionId mobileConnectionsRepo.activeMobileDataSubscriptionId private val unfilteredSubscriptions: Flow<List<SubscriptionInfo>> = private val unfilteredSubscriptions: Flow<List<SubscriptionInfo>> = mobileSubscriptionRepo.subscriptionsFlow mobileConnectionsRepo.subscriptionsFlow /** /** * Generally, SystemUI wants to show iconography for each subscription that is listed by * Generally, SystemUI wants to show iconography for each subscription that is listed by Loading Loading @@ -119,13 +131,13 @@ constructor( * subscription Id. This mapping is the same for every subscription. * subscription Id. This mapping is the same for every subscription. */ */ override val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>> = override val defaultMobileIconMapping: StateFlow<Map<String, MobileIconGroup>> = mobileSubscriptionRepo.defaultDataSubRatConfig mobileConnectionsRepo.defaultDataSubRatConfig .map { mobileMappingsProxy.mapIconSets(it) } .map { mobileMappingsProxy.mapIconSets(it) } .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = mapOf()) .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = mapOf()) /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */ /** If there is no mapping in [defaultMobileIconMapping], then use this default icon group */ override val defaultMobileIconGroup: StateFlow<MobileIconGroup> = override val defaultMobileIconGroup: StateFlow<MobileIconGroup> = mobileSubscriptionRepo.defaultDataSubRatConfig mobileConnectionsRepo.defaultDataSubRatConfig .map { mobileMappingsProxy.getDefaultIcons(it) } .map { mobileMappingsProxy.getDefaultIcons(it) } .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = TelephonyIcons.G) .stateIn(scope, SharingStarted.WhileSubscribed(), initialValue = TelephonyIcons.G) Loading @@ -137,6 +149,6 @@ constructor( defaultMobileIconMapping, defaultMobileIconMapping, defaultMobileIconGroup, defaultMobileIconGroup, mobileMappingsProxy, mobileMappingsProxy, mobileSubscriptionRepo.getRepoForSubId(subId), mobileConnectionsRepo.getRepoForSubId(subId), ) ) } }