Add a SubscriptionModel

We currently only need 2 bits from `SubscriptionInfo`: subscriptionId
and isOpportunistic. This CL moves those into a `SubscriptionModel`
class and updates all of the usages.

Test: existing tests
Bug: 249790009
Change-Id: I87686213e68b199b7d4c998f02d6687dcb276a27
This commit is contained in:
Evan Laird
2022-12-03 01:33:43 -05:00
parent 9014672cd8
commit bee622f1eb
13 changed files with 124 additions and 113 deletions

View File

@@ -0,0 +1,32 @@
/*
* 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
/**
* SystemUI representation of [SubscriptionInfo]. Currently we only use two fields on the
* subscriptions themselves: subscriptionId and isOpportunistic. Any new fields that we need can be
* added below and provided in the repository classes
*/
data class SubscriptionModel(
val subscriptionId: Int,
/**
* True if the subscription that this model represents has [SubscriptionInfo.isOpportunistic].
* Opportunistic networks are networks with limited coverage, and we use this bit to determine
* filtering in certain cases. See [MobileIconsInteractor] for the filtering logic
*/
val isOpportunistic: Boolean = false,
)

View File

@@ -17,10 +17,10 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository
import android.provider.Settings
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
@@ -30,7 +30,7 @@ import kotlinx.coroutines.flow.StateFlow
*/
interface MobileConnectionsRepository {
/** Observable list of current mobile subscriptions */
val subscriptionsFlow: StateFlow<List<SubscriptionInfo>>
val subscriptions: StateFlow<List<SubscriptionModel>>
/** Observable for the subscriptionId of the current mobile data connection */
val activeMobileDataSubscriptionId: StateFlow<Int>

View File

@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository
import android.os.Bundle
import android.telephony.SubscriptionInfo
import androidx.annotation.VisibleForTesting
import com.android.settingslib.SignalIcon
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -25,6 +24,7 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
import javax.inject.Inject
@@ -109,14 +109,10 @@ constructor(
}
.stateIn(scope, SharingStarted.WhileSubscribed(), realRepository)
override val subscriptionsFlow: StateFlow<List<SubscriptionInfo>> =
override val subscriptions: StateFlow<List<SubscriptionModel>> =
activeRepo
.flatMapLatest { it.subscriptionsFlow }
.stateIn(
scope,
SharingStarted.WhileSubscribed(),
realRepository.subscriptionsFlow.value
)
.flatMapLatest { it.subscriptions }
.stateIn(scope, SharingStarted.WhileSubscribed(), realRepository.subscriptions.value)
override val activeMobileDataSubscriptionId: StateFlow<Int> =
activeRepo

View File

@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository.demo
import android.content.Context
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import android.util.Log
import com.android.settingslib.SignalIcon
@@ -29,6 +28,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectio
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
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.demo.model.FakeNetworkEventModel
@@ -62,16 +62,16 @@ constructor(
private var demoCommandJob: Job? = null
private val connectionRepoCache = mutableMapOf<Int, DemoMobileConnectionRepository>()
private val subscriptionInfoCache = mutableMapOf<Int, SubscriptionInfo>()
private val subscriptionInfoCache = mutableMapOf<Int, SubscriptionModel>()
val demoModeFinishedEvent = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
private val _subscriptions = MutableStateFlow<List<SubscriptionInfo>>(listOf())
override val subscriptionsFlow =
private val _subscriptions = MutableStateFlow<List<SubscriptionModel>>(listOf())
override val subscriptions =
_subscriptions
.onEach { infos -> dropUnusedReposFromCache(infos) }
.stateIn(scope, SharingStarted.WhileSubscribed(), _subscriptions.value)
private fun dropUnusedReposFromCache(newInfos: List<SubscriptionInfo>) {
private fun dropUnusedReposFromCache(newInfos: List<SubscriptionModel>) {
// Remove any connection repository from the cache that isn't in the new set of IDs. They
// will get garbage collected once their subscribers go away
val currentValidSubscriptionIds = newInfos.map { it.subscriptionId }
@@ -85,37 +85,17 @@ constructor(
private fun maybeCreateSubscription(subId: Int) {
if (!subscriptionInfoCache.containsKey(subId)) {
createSubscriptionForSubId(subId, subId).also { subscriptionInfoCache[subId] = it }
SubscriptionModel(subscriptionId = subId, isOpportunistic = false).also {
subscriptionInfoCache[subId] = it
}
_subscriptions.value = subscriptionInfoCache.values.toList()
}
}
/** Mimics the old NetworkControllerImpl for now */
private fun createSubscriptionForSubId(subId: Int, slotIndex: Int): SubscriptionInfo {
return SubscriptionInfo(
subId,
"",
slotIndex,
"",
"",
0,
0,
"",
0,
null,
null,
null,
"",
false,
null,
null,
)
}
// TODO(b/261029387): add a command for this value
override val activeMobileDataSubscriptionId =
subscriptionsFlow
subscriptions
.mapLatest { infos ->
// For now, active is just the first in the list
infos.firstOrNull()?.subscriptionId ?: INVALID_SUBSCRIPTION_ID
@@ -123,7 +103,7 @@ constructor(
.stateIn(
scope,
SharingStarted.WhileSubscribed(),
subscriptionsFlow.value.firstOrNull()?.subscriptionId ?: INVALID_SUBSCRIPTION_ID
subscriptions.value.firstOrNull()?.subscriptionId ?: INVALID_SUBSCRIPTION_ID
)
/** Demo mode doesn't currently support modifications to the mobile mappings */

View File

@@ -45,6 +45,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
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.util.MobileMappingsProxy
@@ -93,7 +94,7 @@ constructor(
* [SubscriptionInfo]. We probably only need the [SubscriptionInfo.getSubscriptionId] of each
* info object, but for now we keep track of the infos themselves.
*/
override val subscriptionsFlow: StateFlow<List<SubscriptionInfo>> =
override val subscriptions: StateFlow<List<SubscriptionModel>> =
conflatedCallbackFlow {
val callback =
object : SubscriptionManager.OnSubscriptionsChangedListener() {
@@ -109,7 +110,7 @@ constructor(
awaitClose { subscriptionManager.removeOnSubscriptionsChangedListener(callback) }
}
.mapLatest { fetchSubscriptionsList() }
.mapLatest { fetchSubscriptionsList().map { it.toSubscriptionModel() } }
.onEach { infos -> dropUnusedReposFromCache(infos) }
.stateIn(scope, started = SharingStarted.WhileSubscribed(), listOf())
@@ -239,7 +240,7 @@ constructor(
.stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectivityModel())
private fun isValidSubId(subId: Int): Boolean {
subscriptionsFlow.value.forEach {
subscriptions.value.forEach {
if (it.subscriptionId == subId) {
return true
}
@@ -258,7 +259,7 @@ constructor(
)
}
private fun dropUnusedReposFromCache(newInfos: List<SubscriptionInfo>) {
private fun dropUnusedReposFromCache(newInfos: List<SubscriptionModel>) {
// Remove any connection repository from the cache that isn't in the new set of IDs. They
// will get garbage collected once their subscribers go away
val currentValidSubscriptionIds = newInfos.map { it.subscriptionId }
@@ -272,4 +273,10 @@ constructor(
private suspend fun fetchSubscriptionsList(): List<SubscriptionInfo> =
withContext(bgDispatcher) { subscriptionManager.completeActiveSubscriptionInfoList }
private fun SubscriptionInfo.toSubscriptionModel(): SubscriptionModel =
SubscriptionModel(
subscriptionId = subscriptionId,
isOpportunistic = isOpportunistic,
)
}

View File

@@ -17,13 +17,13 @@
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
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.model.SubscriptionModel
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
@@ -52,7 +52,7 @@ import kotlinx.coroutines.flow.stateIn
*/
interface MobileIconsInteractor {
/** List of subscriptions, potentially filtered for CBRS */
val filteredSubscriptions: Flow<List<SubscriptionInfo>>
val filteredSubscriptions: Flow<List<SubscriptionModel>>
/** True if the active mobile data subscription has data enabled */
val activeDataConnectionHasDataEnabled: StateFlow<Boolean>
/** The icon mapping from network type to [MobileIconGroup] for the default subscription */
@@ -100,8 +100,8 @@ constructor(
.flatMapLatest { it?.dataEnabled ?: flowOf(false) }
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
private val unfilteredSubscriptions: Flow<List<SubscriptionInfo>> =
mobileConnectionsRepo.subscriptionsFlow
private val unfilteredSubscriptions: Flow<List<SubscriptionModel>> =
mobileConnectionsRepo.subscriptions
/**
* Generally, SystemUI wants to show iconography for each subscription that is listed by
@@ -116,7 +116,7 @@ constructor(
* [CarrierConfigManager.KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN],
* and by checking which subscription is opportunistic, or which one is active.
*/
override val filteredSubscriptions: Flow<List<SubscriptionInfo>> =
override val filteredSubscriptions: Flow<List<SubscriptionModel>> =
combine(unfilteredSubscriptions, activeMobileDataSubscriptionId) { unfilteredSubs, activeId
->
// Based on the old logic,

View File

@@ -56,8 +56,8 @@ constructor(
private val statusBarPipelineFlags: StatusBarPipelineFlags,
) : CoreStartable {
private val mobileSubIds: Flow<List<Int>> =
interactor.filteredSubscriptions.mapLatest { infos ->
infos.map { subscriptionInfo -> subscriptionInfo.subscriptionId }
interactor.filteredSubscriptions.mapLatest { subscriptions ->
subscriptions.map { subscriptionModel -> subscriptionModel.subscriptionId }
}
/**

View File

@@ -16,13 +16,13 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
import com.android.settingslib.SignalIcon
import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
import kotlinx.coroutines.flow.MutableStateFlow
@@ -47,8 +47,8 @@ class FakeMobileConnectionsRepository(mobileMappings: MobileMappingsProxy) :
LTE_ADVANCED_KEY to TelephonyIcons.NR_5G,
)
private val _subscriptionsFlow = MutableStateFlow<List<SubscriptionInfo>>(listOf())
override val subscriptionsFlow = _subscriptionsFlow
private val _subscriptions = MutableStateFlow<List<SubscriptionModel>>(listOf())
override val subscriptions = _subscriptions
private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId
@@ -74,8 +74,8 @@ class FakeMobileConnectionsRepository(mobileMappings: MobileMappingsProxy) :
private val _defaultMobileIconGroup = MutableStateFlow(DEFAULT_ICON)
override val defaultMobileIconGroup = _defaultMobileIconGroup
fun setSubscriptions(subs: List<SubscriptionInfo>) {
_subscriptionsFlow.value = subs
fun setSubscriptions(subs: List<SubscriptionModel>) {
_subscriptions.value = subs
}
fun setDefaultDataSubId(id: Int) {

View File

@@ -24,6 +24,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoModeMobileConnectionDataSource
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
@@ -158,15 +159,15 @@ class MobileRepositorySwitcherTest : SysuiTestCase() {
whenever(subscriptionManager.completeActiveSubscriptionInfoList)
.thenReturn(listOf(SUB_1, SUB_2))
var latest: List<SubscriptionInfo>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
// The real subscriptions has 2 subs
whenever(subscriptionManager.completeActiveSubscriptionInfoList)
.thenReturn(listOf(SUB_1, SUB_2))
getSubscriptionCallback().onSubscriptionsChanged()
assertThat(latest).isEqualTo(listOf(SUB_1, SUB_2))
assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
// Demo mode turns on, and we should see only the demo subscriptions
startDemoMode()
@@ -179,7 +180,7 @@ class MobileRepositorySwitcherTest : SysuiTestCase() {
finishDemoMode()
assertThat(latest).isEqualTo(listOf(SUB_1, SUB_2))
assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
job.cancel()
}
@@ -214,9 +215,11 @@ class MobileRepositorySwitcherTest : SysuiTestCase() {
private const val SUB_1_ID = 1
private val SUB_1 =
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
private val MODEL_1 = SubscriptionModel(subscriptionId = SUB_1_ID)
private const val SUB_2_ID = 2
private val SUB_2 =
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) }
private val MODEL_2 = SubscriptionModel(subscriptionId = SUB_2_ID)
}
}

View File

@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository.demo
import android.telephony.SubscriptionInfo
import android.telephony.TelephonyManager.DATA_ACTIVITY_INOUT
import android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID
import androidx.test.filters.SmallTest
@@ -25,6 +24,7 @@ import com.android.settingslib.mobile.TelephonyIcons.THREE_G
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.MobileDisabled
import com.android.systemui.util.mockito.mock
@@ -73,8 +73,8 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun `network event - create new subscription`() =
testScope.runTest {
var latest: List<SubscriptionInfo>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
assertThat(latest).isEmpty()
@@ -89,8 +89,8 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun `network event - reuses subscription when same Id`() =
testScope.runTest {
var latest: List<SubscriptionInfo>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
assertThat(latest).isEmpty()
@@ -111,8 +111,8 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun `multiple subscriptions`() =
testScope.runTest {
var latest: List<SubscriptionInfo>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
fakeNetworkEventFlow.value = validMobileEvent(subId = 1)
fakeNetworkEventFlow.value = validMobileEvent(subId = 2)
@@ -125,8 +125,8 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun `mobile disabled event - disables connection - subId specified - single conn`() =
testScope.runTest {
var latest: List<SubscriptionInfo>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
@@ -140,8 +140,8 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun `mobile disabled event - disables connection - subId not specified - single conn`() =
testScope.runTest {
var latest: List<SubscriptionInfo>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
@@ -155,8 +155,8 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun `mobile disabled event - disables connection - subId specified - multiple conn`() =
testScope.runTest {
var latest: List<SubscriptionInfo>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
fakeNetworkEventFlow.value = validMobileEvent(subId = 2, level = 1)
@@ -171,8 +171,8 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun `mobile disabled event - subId not specified - multiple conn - ignores command`() =
testScope.runTest {
var latest: List<SubscriptionInfo>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
fakeNetworkEventFlow.value = validMobileEvent(subId = 1, level = 1)
fakeNetworkEventFlow.value = validMobileEvent(subId = 2, level = 1)
@@ -190,7 +190,7 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
var currentEvent: FakeNetworkEventModel = validMobileEvent(subId = 1)
var connections: List<DemoMobileConnectionRepository>? = null
val job =
underTest.subscriptionsFlow
underTest.subscriptions
.onEach { infos ->
connections =
infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }
@@ -222,7 +222,7 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
var connection2: DemoMobileConnectionRepository? = null
var connections: List<DemoMobileConnectionRepository>? = null
val job =
underTest.subscriptionsFlow
underTest.subscriptions
.onEach { infos ->
connections =
infos.map { info -> underTest.getRepoForSubId(info.subscriptionId) }

View File

@@ -32,6 +32,7 @@ import androidx.test.filters.SmallTest
import com.android.internal.telephony.PhoneConstants
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.util.mockito.any
@@ -99,21 +100,21 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun testSubscriptions_initiallyEmpty() =
runBlocking(IMMEDIATE) {
assertThat(underTest.subscriptionsFlow.value).isEqualTo(listOf<SubscriptionInfo>())
assertThat(underTest.subscriptions.value).isEqualTo(listOf<SubscriptionModel>())
}
@Test
fun testSubscriptions_listUpdates() =
runBlocking(IMMEDIATE) {
var latest: List<SubscriptionInfo>? = null
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
whenever(subscriptionManager.completeActiveSubscriptionInfoList)
.thenReturn(listOf(SUB_1, SUB_2))
getSubscriptionCallback().onSubscriptionsChanged()
assertThat(latest).isEqualTo(listOf(SUB_1, SUB_2))
assertThat(latest).isEqualTo(listOf(MODEL_1, MODEL_2))
job.cancel()
}
@@ -121,9 +122,9 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun testSubscriptions_removingSub_updatesList() =
runBlocking(IMMEDIATE) {
var latest: List<SubscriptionInfo>? = null
var latest: List<SubscriptionModel>? = null
val job = underTest.subscriptionsFlow.onEach { latest = it }.launchIn(this)
val job = underTest.subscriptions.onEach { latest = it }.launchIn(this)
// WHEN 2 networks show up
whenever(subscriptionManager.completeActiveSubscriptionInfoList)
@@ -136,7 +137,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
getSubscriptionCallback().onSubscriptionsChanged()
// THEN the subscriptions list represents the newest change
assertThat(latest).isEqualTo(listOf(SUB_2))
assertThat(latest).isEqualTo(listOf(MODEL_2))
job.cancel()
}
@@ -166,7 +167,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun testConnectionRepository_validSubId_isCached() =
runBlocking(IMMEDIATE) {
val job = underTest.subscriptionsFlow.launchIn(this)
val job = underTest.subscriptions.launchIn(this)
whenever(subscriptionManager.completeActiveSubscriptionInfoList)
.thenReturn(listOf(SUB_1))
@@ -183,7 +184,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun testConnectionCache_clearsInvalidSubscriptions() =
runBlocking(IMMEDIATE) {
val job = underTest.subscriptionsFlow.launchIn(this)
val job = underTest.subscriptions.launchIn(this)
whenever(subscriptionManager.completeActiveSubscriptionInfoList)
.thenReturn(listOf(SUB_1, SUB_2))
@@ -209,7 +210,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
@Test
fun testConnectionRepository_invalidSubId_throws() =
runBlocking(IMMEDIATE) {
val job = underTest.subscriptionsFlow.launchIn(this)
val job = underTest.subscriptions.launchIn(this)
assertThrows(IllegalArgumentException::class.java) {
underTest.getRepoForSubId(SUB_1_ID)
@@ -375,10 +376,12 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
private const val SUB_1_ID = 1
private val SUB_1 =
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
private val MODEL_1 = SubscriptionModel(subscriptionId = SUB_1_ID)
private const val SUB_2_ID = 2
private val SUB_2 =
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) }
private val MODEL_2 = SubscriptionModel(subscriptionId = SUB_2_ID)
private const val NET_ID = 123
private val NETWORK = mock<Network>().apply { whenever(getNetId()).thenReturn(NET_ID) }

View File

@@ -16,14 +16,15 @@
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
import android.telephony.SubscriptionInfo
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO
import android.telephony.TelephonyManager.NETWORK_TYPE_GSM
import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
import android.telephony.TelephonyManager.NETWORK_TYPE_UMTS
import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
class FakeMobileIconsInteractor(mobileMappings: MobileMappingsProxy) : MobileIconsInteractor {
@@ -47,8 +48,8 @@ class FakeMobileIconsInteractor(mobileMappings: MobileMappingsProxy) : MobileIco
override val isDefaultConnectionFailed = MutableStateFlow(false)
private val _filteredSubscriptions = MutableStateFlow<List<SubscriptionInfo>>(listOf())
override val filteredSubscriptions = _filteredSubscriptions
private val _filteredSubscriptions = MutableStateFlow<List<SubscriptionModel>>(listOf())
override val filteredSubscriptions: Flow<List<SubscriptionModel>> = _filteredSubscriptions
private val _activeDataConnectionHasDataEnabled = MutableStateFlow(false)
override val activeDataConnectionHasDataEnabled = _activeDataConnectionHasDataEnabled

View File

@@ -16,17 +16,16 @@
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
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.FakeUserSetupRepository
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.util.CarrierConfigTracker
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
@@ -79,10 +78,10 @@ class MobileIconsInteractorTest : SysuiTestCase() {
@Test
fun filteredSubscriptions_default() =
runBlocking(IMMEDIATE) {
var latest: List<SubscriptionInfo>? = null
var latest: List<SubscriptionModel>? = null
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
assertThat(latest).isEqualTo(listOf<SubscriptionInfo>())
assertThat(latest).isEqualTo(listOf<SubscriptionModel>())
job.cancel()
}
@@ -92,7 +91,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
runBlocking(IMMEDIATE) {
connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_2))
var latest: List<SubscriptionInfo>? = null
var latest: List<SubscriptionModel>? = null
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
assertThat(latest).isEqualTo(listOf(SUB_1, SUB_2))
@@ -108,7 +107,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
.thenReturn(false)
var latest: List<SubscriptionInfo>? = null
var latest: List<SubscriptionModel>? = null
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
// Filtered subscriptions should show the active one when the config is false
@@ -125,7 +124,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
.thenReturn(false)
var latest: List<SubscriptionInfo>? = null
var latest: List<SubscriptionModel>? = null
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
// Filtered subscriptions should show the active one when the config is false
@@ -142,7 +141,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
.thenReturn(true)
var latest: List<SubscriptionInfo>? = null
var latest: List<SubscriptionModel>? = null
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
// Filtered subscriptions should show the primary (non-opportunistic) if the config is
@@ -160,7 +159,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault)
.thenReturn(true)
var latest: List<SubscriptionInfo>? = null
var latest: List<SubscriptionModel>? = null
val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this)
// Filtered subscriptions should show the primary (non-opportunistic) if the config is
@@ -260,29 +259,19 @@ class MobileIconsInteractorTest : SysuiTestCase() {
private val IMMEDIATE = Dispatchers.Main.immediate
private const val SUB_1_ID = 1
private val SUB_1 =
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
private val SUB_1 = SubscriptionModel(subscriptionId = SUB_1_ID)
private val CONNECTION_1 = FakeMobileConnectionRepository(SUB_1_ID)
private const val SUB_2_ID = 2
private val SUB_2 =
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_2_ID) }
private val SUB_2 = SubscriptionModel(subscriptionId = SUB_2_ID)
private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID)
private const val SUB_3_ID = 3
private val SUB_3_OPP =
mock<SubscriptionInfo>().also {
whenever(it.subscriptionId).thenReturn(SUB_3_ID)
whenever(it.isOpportunistic).thenReturn(true)
}
private val SUB_3_OPP = SubscriptionModel(subscriptionId = SUB_3_ID, isOpportunistic = true)
private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID)
private const val SUB_4_ID = 4
private val SUB_4_OPP =
mock<SubscriptionInfo>().also {
whenever(it.subscriptionId).thenReturn(SUB_4_ID)
whenever(it.isOpportunistic).thenReturn(true)
}
private val SUB_4_OPP = SubscriptionModel(subscriptionId = SUB_4_ID, isOpportunistic = true)
private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID)
}
}