Merge "[Sb refactor] Add dataEnabled tracking to mobile repos" into tm-qpr-dev
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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")
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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].
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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,
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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(
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
@@ -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(
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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)
|
||||||
|
|
||||||
@@ -137,6 +149,6 @@ constructor(
|
|||||||
defaultMobileIconMapping,
|
defaultMobileIconMapping,
|
||||||
defaultMobileIconGroup,
|
defaultMobileIconGroup,
|
||||||
mobileMappingsProxy,
|
mobileMappingsProxy,
|
||||||
mobileSubscriptionRepo.getRepoForSubId(subId),
|
mobileConnectionsRepo.getRepoForSubId(subId),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View model for the state of a single mobile icon. Each [MobileIconViewModel] will keep watch over
|
* View model for the state of a single mobile icon. Each [MobileIconViewModel] will keep watch over
|
||||||
@@ -59,12 +58,18 @@ constructor(
|
|||||||
|
|
||||||
/** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */
|
/** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */
|
||||||
var networkTypeIcon: Flow<Icon?> =
|
var networkTypeIcon: Flow<Icon?> =
|
||||||
iconInteractor.networkTypeIconGroup.map {
|
combine(iconInteractor.networkTypeIconGroup, iconInteractor.isDataEnabled) {
|
||||||
|
networkTypeIconGroup,
|
||||||
|
isDataEnabled ->
|
||||||
|
if (!isDataEnabled) {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
val desc =
|
val desc =
|
||||||
if (it.dataContentDescription != 0)
|
if (networkTypeIconGroup.dataContentDescription != 0)
|
||||||
ContentDescription.Resource(it.dataContentDescription)
|
ContentDescription.Resource(networkTypeIconGroup.dataContentDescription)
|
||||||
else null
|
else null
|
||||||
Icon.Resource(it.dataType, desc)
|
Icon.Resource(networkTypeIconGroup.dataType, desc)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tint: Flow<Int> = flowOf(Color.CYAN)
|
var tint: Flow<Int> = flowOf(Color.CYAN)
|
||||||
|
|||||||
@@ -24,7 +24,14 @@ class FakeMobileConnectionRepository : MobileConnectionRepository {
|
|||||||
private val _subscriptionsModelFlow = MutableStateFlow(MobileSubscriptionModel())
|
private val _subscriptionsModelFlow = MutableStateFlow(MobileSubscriptionModel())
|
||||||
override val subscriptionModelFlow: Flow<MobileSubscriptionModel> = _subscriptionsModelFlow
|
override val subscriptionModelFlow: Flow<MobileSubscriptionModel> = _subscriptionsModelFlow
|
||||||
|
|
||||||
|
private val _dataEnabled = MutableStateFlow(true)
|
||||||
|
override val dataEnabled = _dataEnabled
|
||||||
|
|
||||||
fun setMobileSubscriptionModel(model: MobileSubscriptionModel) {
|
fun setMobileSubscriptionModel(model: MobileSubscriptionModel) {
|
||||||
_subscriptionsModelFlow.value = model
|
_subscriptionsModelFlow.value = model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setDataEnabled(enabled: Boolean) {
|
||||||
|
_dataEnabled.value = enabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class FakeMobileConnectionsRepository : MobileConnectionsRepository {
|
|||||||
_activeMobileDataSubscriptionId.value = subId
|
_activeMobileDataSubscriptionId.value = subId
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setMobileConnectionRepositoryForId(subId: Int, repo: MobileConnectionRepository) {
|
fun setMobileConnectionRepositoryMap(connections: Map<Int, MobileConnectionRepository>) {
|
||||||
subIdRepos[subId] = repo
|
connections.forEach { entry -> subIdRepos[entry.key] = entry.value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,16 +20,20 @@ import android.telephony.CellSignalStrengthCdma
|
|||||||
import android.telephony.ServiceState
|
import android.telephony.ServiceState
|
||||||
import android.telephony.SignalStrength
|
import android.telephony.SignalStrength
|
||||||
import android.telephony.SubscriptionInfo
|
import android.telephony.SubscriptionInfo
|
||||||
import android.telephony.SubscriptionManager
|
|
||||||
import android.telephony.TelephonyCallback
|
import android.telephony.TelephonyCallback
|
||||||
import android.telephony.TelephonyCallback.ServiceStateListener
|
import android.telephony.TelephonyCallback.ServiceStateListener
|
||||||
import android.telephony.TelephonyDisplayInfo
|
import android.telephony.TelephonyDisplayInfo
|
||||||
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA
|
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA
|
||||||
import android.telephony.TelephonyManager
|
import android.telephony.TelephonyManager
|
||||||
|
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.NETWORK_TYPE_LTE
|
import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
|
||||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
|
||||||
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
|
||||||
@@ -59,7 +63,6 @@ import org.mockito.MockitoAnnotations
|
|||||||
class MobileConnectionRepositoryTest : SysuiTestCase() {
|
class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||||
private lateinit var underTest: MobileConnectionRepositoryImpl
|
private lateinit var underTest: MobileConnectionRepositoryImpl
|
||||||
|
|
||||||
@Mock private lateinit var subscriptionManager: SubscriptionManager
|
|
||||||
@Mock private lateinit var telephonyManager: TelephonyManager
|
@Mock private lateinit var telephonyManager: TelephonyManager
|
||||||
@Mock private lateinit var logger: ConnectivityPipelineLogger
|
@Mock private lateinit var logger: ConnectivityPipelineLogger
|
||||||
|
|
||||||
@@ -148,16 +151,61 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFlowForSubId_dataConnectionState() =
|
fun testFlowForSubId_dataConnectionState_connected() =
|
||||||
runBlocking(IMMEDIATE) {
|
runBlocking(IMMEDIATE) {
|
||||||
var latest: MobileSubscriptionModel? = null
|
var latest: MobileSubscriptionModel? = null
|
||||||
val job = underTest.subscriptionModelFlow.onEach { latest = it }.launchIn(this)
|
val job = underTest.subscriptionModelFlow.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
val callback =
|
val callback =
|
||||||
getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
|
getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
|
||||||
callback.onDataConnectionStateChanged(100, 200 /* unused */)
|
callback.onDataConnectionStateChanged(DATA_CONNECTED, 200 /* unused */)
|
||||||
|
|
||||||
assertThat(latest?.dataConnectionState).isEqualTo(100)
|
assertThat(latest?.dataConnectionState).isEqualTo(DataConnectionState.Connected)
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFlowForSubId_dataConnectionState_connecting() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
var latest: MobileSubscriptionModel? = null
|
||||||
|
val job = underTest.subscriptionModelFlow.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
val callback =
|
||||||
|
getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
|
||||||
|
callback.onDataConnectionStateChanged(DATA_CONNECTING, 200 /* unused */)
|
||||||
|
|
||||||
|
assertThat(latest?.dataConnectionState).isEqualTo(DataConnectionState.Connecting)
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFlowForSubId_dataConnectionState_disconnected() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
var latest: MobileSubscriptionModel? = null
|
||||||
|
val job = underTest.subscriptionModelFlow.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
val callback =
|
||||||
|
getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
|
||||||
|
callback.onDataConnectionStateChanged(DATA_DISCONNECTED, 200 /* unused */)
|
||||||
|
|
||||||
|
assertThat(latest?.dataConnectionState).isEqualTo(DataConnectionState.Disconnected)
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testFlowForSubId_dataConnectionState_disconnecting() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
var latest: MobileSubscriptionModel? = null
|
||||||
|
val job = underTest.subscriptionModelFlow.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
val callback =
|
||||||
|
getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
|
||||||
|
callback.onDataConnectionStateChanged(DATA_DISCONNECTING, 200 /* unused */)
|
||||||
|
|
||||||
|
assertThat(latest?.dataConnectionState).isEqualTo(DataConnectionState.Disconnecting)
|
||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
@@ -241,6 +289,32 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun dataEnabled_isEnabled() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
whenever(telephonyManager.isDataConnectionAllowed).thenReturn(true)
|
||||||
|
|
||||||
|
var latest: Boolean? = null
|
||||||
|
val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isTrue()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun dataEnabled_isDisabled() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false)
|
||||||
|
|
||||||
|
var latest: Boolean? = null
|
||||||
|
val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isFalse()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
private fun getTelephonyCallbacks(): List<TelephonyCallback> {
|
private fun getTelephonyCallbacks(): List<TelephonyCallback> {
|
||||||
val callbackCaptor = argumentCaptor<TelephonyCallback>()
|
val callbackCaptor = argumentCaptor<TelephonyCallback>()
|
||||||
Mockito.verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture())
|
Mockito.verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture())
|
||||||
|
|||||||
@@ -22,19 +22,22 @@ import com.android.settingslib.mobile.TelephonyIcons
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
class FakeMobileIconInteractor : MobileIconInteractor {
|
class FakeMobileIconInteractor : MobileIconInteractor {
|
||||||
private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.UNKNOWN)
|
private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G)
|
||||||
override val networkTypeIconGroup = _iconGroup
|
override val networkTypeIconGroup = _iconGroup
|
||||||
|
|
||||||
private val _isEmergencyOnly = MutableStateFlow<Boolean>(false)
|
private val _isEmergencyOnly = MutableStateFlow(false)
|
||||||
override val isEmergencyOnly = _isEmergencyOnly
|
override val isEmergencyOnly = _isEmergencyOnly
|
||||||
|
|
||||||
private val _level = MutableStateFlow<Int>(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
|
private val _isDataEnabled = MutableStateFlow(true)
|
||||||
|
override val isDataEnabled = _isDataEnabled
|
||||||
|
|
||||||
|
private val _level = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
|
||||||
override val level = _level
|
override val level = _level
|
||||||
|
|
||||||
private val _numberOfLevels = MutableStateFlow<Int>(4)
|
private val _numberOfLevels = MutableStateFlow(4)
|
||||||
override val numberOfLevels = _numberOfLevels
|
override val numberOfLevels = _numberOfLevels
|
||||||
|
|
||||||
private val _cutOut = MutableStateFlow<Boolean>(false)
|
private val _cutOut = MutableStateFlow(false)
|
||||||
override val cutOut = _cutOut
|
override val cutOut = _cutOut
|
||||||
|
|
||||||
fun setIconGroup(group: SignalIcon.MobileIconGroup) {
|
fun setIconGroup(group: SignalIcon.MobileIconGroup) {
|
||||||
@@ -45,6 +48,10 @@ class FakeMobileIconInteractor : MobileIconInteractor {
|
|||||||
_isEmergencyOnly.value = emergency
|
_isEmergencyOnly.value = emergency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setIsDataEnabled(enabled: Boolean) {
|
||||||
|
_isDataEnabled.value = enabled
|
||||||
|
}
|
||||||
|
|
||||||
fun setLevel(level: Int) {
|
fun setLevel(level: Int) {
|
||||||
_level.value = level
|
_level.value = level
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
|
|||||||
import android.telephony.SubscriptionInfo
|
import android.telephony.SubscriptionInfo
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
|
||||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
|
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
|
||||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
|
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
|
||||||
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
|
||||||
@@ -41,7 +42,7 @@ import org.mockito.MockitoAnnotations
|
|||||||
class MobileIconsInteractorTest : SysuiTestCase() {
|
class MobileIconsInteractorTest : SysuiTestCase() {
|
||||||
private lateinit var underTest: MobileIconsInteractor
|
private lateinit var underTest: MobileIconsInteractor
|
||||||
private val userSetupRepository = FakeUserSetupRepository()
|
private val userSetupRepository = FakeUserSetupRepository()
|
||||||
private val subscriptionsRepository = FakeMobileConnectionsRepository()
|
private val connectionsRepository = FakeMobileConnectionsRepository()
|
||||||
private val mobileMappingsProxy = FakeMobileMappingsProxy()
|
private val mobileMappingsProxy = FakeMobileMappingsProxy()
|
||||||
private val scope = CoroutineScope(IMMEDIATE)
|
private val scope = CoroutineScope(IMMEDIATE)
|
||||||
|
|
||||||
@@ -50,9 +51,20 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
|
connectionsRepository.setMobileConnectionRepositoryMap(
|
||||||
|
mapOf(
|
||||||
|
SUB_1_ID to CONNECTION_1,
|
||||||
|
SUB_2_ID to CONNECTION_2,
|
||||||
|
SUB_3_ID to CONNECTION_3,
|
||||||
|
SUB_4_ID to CONNECTION_4,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID)
|
||||||
|
|
||||||
underTest =
|
underTest =
|
||||||
MobileIconsInteractorImpl(
|
MobileIconsInteractorImpl(
|
||||||
subscriptionsRepository,
|
connectionsRepository,
|
||||||
carrierConfigTracker,
|
carrierConfigTracker,
|
||||||
mobileMappingsProxy,
|
mobileMappingsProxy,
|
||||||
userSetupRepository,
|
userSetupRepository,
|
||||||
@@ -76,7 +88,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_nonOpportunistic_updatesWithMultipleSubs() =
|
fun filteredSubscriptions_nonOpportunistic_updatesWithMultipleSubs() =
|
||||||
runBlocking(IMMEDIATE) {
|
runBlocking(IMMEDIATE) {
|
||||||
subscriptionsRepository.setSubscriptions(listOf(SUB_1, SUB_2))
|
connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_2))
|
||||||
|
|
||||||
var latest: List<SubscriptionInfo>? = null
|
var latest: List<SubscriptionInfo>? = null
|
||||||
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
|
||||||
@@ -89,8 +101,8 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_3() =
|
fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_3() =
|
||||||
runBlocking(IMMEDIATE) {
|
runBlocking(IMMEDIATE) {
|
||||||
subscriptionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
|
connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
|
||||||
subscriptionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
||||||
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
.thenReturn(false)
|
.thenReturn(false)
|
||||||
|
|
||||||
@@ -106,8 +118,8 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_4() =
|
fun filteredSubscriptions_bothOpportunistic_configFalse_showsActive_4() =
|
||||||
runBlocking(IMMEDIATE) {
|
runBlocking(IMMEDIATE) {
|
||||||
subscriptionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
|
connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP))
|
||||||
subscriptionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID)
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID)
|
||||||
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
.thenReturn(false)
|
.thenReturn(false)
|
||||||
|
|
||||||
@@ -123,8 +135,8 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_active_1() =
|
fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_active_1() =
|
||||||
runBlocking(IMMEDIATE) {
|
runBlocking(IMMEDIATE) {
|
||||||
subscriptionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP))
|
connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP))
|
||||||
subscriptionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID)
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID)
|
||||||
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
.thenReturn(true)
|
.thenReturn(true)
|
||||||
|
|
||||||
@@ -141,8 +153,8 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_nonActive_1() =
|
fun filteredSubscriptions_oneOpportunistic_configTrue_showsPrimary_nonActive_1() =
|
||||||
runBlocking(IMMEDIATE) {
|
runBlocking(IMMEDIATE) {
|
||||||
subscriptionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP))
|
connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP))
|
||||||
subscriptionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID)
|
||||||
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
|
||||||
.thenReturn(true)
|
.thenReturn(true)
|
||||||
|
|
||||||
@@ -162,10 +174,12 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
private const val SUB_1_ID = 1
|
private const val SUB_1_ID = 1
|
||||||
private val SUB_1 =
|
private val SUB_1 =
|
||||||
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
|
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
|
||||||
|
private val CONNECTION_1 = FakeMobileConnectionRepository()
|
||||||
|
|
||||||
private const val SUB_2_ID = 2
|
private const val SUB_2_ID = 2
|
||||||
private val SUB_2 =
|
private val SUB_2 =
|
||||||
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) }
|
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) }
|
||||||
|
private val CONNECTION_2 = FakeMobileConnectionRepository()
|
||||||
|
|
||||||
private const val SUB_3_ID = 3
|
private const val SUB_3_ID = 3
|
||||||
private val SUB_3_OPP =
|
private val SUB_3_OPP =
|
||||||
@@ -173,6 +187,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
whenever(it.subscriptionId).thenReturn(SUB_3_ID)
|
whenever(it.subscriptionId).thenReturn(SUB_3_ID)
|
||||||
whenever(it.isOpportunistic).thenReturn(true)
|
whenever(it.isOpportunistic).thenReturn(true)
|
||||||
}
|
}
|
||||||
|
private val CONNECTION_3 = FakeMobileConnectionRepository()
|
||||||
|
|
||||||
private const val SUB_4_ID = 4
|
private const val SUB_4_ID = 4
|
||||||
private val SUB_4_OPP =
|
private val SUB_4_OPP =
|
||||||
@@ -180,5 +195,6 @@ class MobileIconsInteractorTest : SysuiTestCase() {
|
|||||||
whenever(it.subscriptionId).thenReturn(SUB_4_ID)
|
whenever(it.subscriptionId).thenReturn(SUB_4_ID)
|
||||||
whenever(it.isOpportunistic).thenReturn(true)
|
whenever(it.isOpportunistic).thenReturn(true)
|
||||||
}
|
}
|
||||||
|
private val CONNECTION_4 = FakeMobileConnectionRepository()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.settingslib.graph.SignalDrawable
|
import com.android.settingslib.graph.SignalDrawable
|
||||||
import com.android.settingslib.mobile.TelephonyIcons
|
import com.android.settingslib.mobile.TelephonyIcons.THREE_G
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.common.shared.model.ContentDescription
|
||||||
|
import com.android.systemui.common.shared.model.Icon
|
||||||
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor
|
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
@@ -27,6 +29,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import kotlinx.coroutines.yield
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
@@ -44,7 +47,7 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
|||||||
interactor.apply {
|
interactor.apply {
|
||||||
setLevel(1)
|
setLevel(1)
|
||||||
setCutOut(false)
|
setCutOut(false)
|
||||||
setIconGroup(TelephonyIcons.THREE_G)
|
setIconGroup(THREE_G)
|
||||||
setIsEmergencyOnly(false)
|
setIsEmergencyOnly(false)
|
||||||
setNumberOfLevels(4)
|
setNumberOfLevels(4)
|
||||||
}
|
}
|
||||||
@@ -62,6 +65,60 @@ class MobileIconViewModelTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun networkType_dataEnabled_groupIsRepresented() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
val expected =
|
||||||
|
Icon.Resource(
|
||||||
|
THREE_G.dataType,
|
||||||
|
ContentDescription.Resource(THREE_G.dataContentDescription)
|
||||||
|
)
|
||||||
|
interactor.setIconGroup(THREE_G)
|
||||||
|
|
||||||
|
var latest: Icon? = null
|
||||||
|
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(expected)
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun networkType_nullWhenDisabled() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
interactor.setIconGroup(THREE_G)
|
||||||
|
interactor.setIsDataEnabled(false)
|
||||||
|
var latest: Icon? = null
|
||||||
|
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun networkType_null_changeToDisabled() =
|
||||||
|
runBlocking(IMMEDIATE) {
|
||||||
|
val expected =
|
||||||
|
Icon.Resource(
|
||||||
|
THREE_G.dataType,
|
||||||
|
ContentDescription.Resource(THREE_G.dataContentDescription)
|
||||||
|
)
|
||||||
|
interactor.setIconGroup(THREE_G)
|
||||||
|
interactor.setIsDataEnabled(true)
|
||||||
|
var latest: Icon? = null
|
||||||
|
val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(expected)
|
||||||
|
|
||||||
|
interactor.setIsDataEnabled(false)
|
||||||
|
yield()
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val IMMEDIATE = Dispatchers.Main.immediate
|
private val IMMEDIATE = Dispatchers.Main.immediate
|
||||||
private const val SUB_1_ID = 1
|
private const val SUB_1_ID = 1
|
||||||
|
|||||||
Reference in New Issue
Block a user