Merge changes I6a6916fd,Ia7fdd0c8,Id2e73b83,If3e00d82,Ia7eb62d6 into tm-qpr-dev

* changes:
  [SB Refactor] Support network names for carrier merged.
  [SB Refactor] Cleanups in the carrier merged connection repo.
  [SB Refactor] Don't update the network name if the subId doesn't match.
  [SB Refactor] Supprt activity in/out for carrier merged connections.
  [SB Refactor] Make demo wifi's activity always non-null.
This commit is contained in:
Caitlin Shkuratov
2023-02-09 16:18:20 +00:00
committed by Android (Google) Code Review
17 changed files with 245 additions and 90 deletions

View File

@@ -48,15 +48,31 @@ sealed interface NetworkNameModel : Diffable<NetworkNameModel> {
* This name has been derived from telephony intents. see * This name has been derived from telephony intents. see
* [android.telephony.TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED] * [android.telephony.TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED]
*/ */
data class Derived(override val name: String) : NetworkNameModel { data class IntentDerived(override val name: String) : NetworkNameModel {
override fun logDiffs(prevVal: NetworkNameModel, row: TableRowLogger) { override fun logDiffs(prevVal: NetworkNameModel, row: TableRowLogger) {
if (prevVal !is Derived || prevVal.name != name) { if (prevVal !is IntentDerived || prevVal.name != name) {
row.logChange(COL_NETWORK_NAME, "Derived($name)") row.logChange(COL_NETWORK_NAME, "IntentDerived($name)")
} }
} }
override fun logFull(row: TableRowLogger) { override fun logFull(row: TableRowLogger) {
row.logChange(COL_NETWORK_NAME, "Derived($name)") row.logChange(COL_NETWORK_NAME, "IntentDerived($name)")
}
}
/**
* This name has been derived from the sim via
* [android.telephony.TelephonyManager.getSimOperatorName].
*/
data class SimDerived(override val name: String) : NetworkNameModel {
override fun logDiffs(prevVal: NetworkNameModel, row: TableRowLogger) {
if (prevVal !is SimDerived || prevVal.name != name) {
row.logChange(COL_NETWORK_NAME, "SimDerived($name)")
}
}
override fun logFull(row: TableRowLogger) {
row.logChange(COL_NETWORK_NAME, "SimDerived($name)")
} }
} }
@@ -84,5 +100,5 @@ fun Intent.toNetworkNameModel(separator: String): NetworkNameModel? {
str.append(spn) str.append(spn)
} }
return if (str.isNotEmpty()) NetworkNameModel.Derived(str.toString()) else null return if (str.isNotEmpty()) NetworkNameModel.IntentDerived(str.toString()) else null
} }

View File

@@ -240,7 +240,7 @@ constructor(
// This is always true here, because we split out disabled states at the data-source level // This is always true here, because we split out disabled states at the data-source level
connection.dataEnabled.value = true connection.dataEnabled.value = true
connection.networkName.value = NetworkNameModel.Derived(state.name) connection.networkName.value = NetworkNameModel.IntentDerived(state.name)
connection.cdmaRoaming.value = state.roaming connection.cdmaRoaming.value = state.roaming
connection.connectionInfo.value = state.toMobileConnectionModel() connection.connectionInfo.value = state.toMobileConnectionModel()
@@ -258,10 +258,13 @@ constructor(
maybeCreateSubscription(subId) maybeCreateSubscription(subId)
carrierMergedSubId = subId carrierMergedSubId = subId
// TODO(b/261029387): until we have a command, use the most recent subId
defaultDataSubId.value = subId
val connection = getRepoForSubId(subId) val connection = getRepoForSubId(subId)
// This is always true here, because we split out disabled states at the data-source level // This is always true here, because we split out disabled states at the data-source level
connection.dataEnabled.value = true connection.dataEnabled.value = true
connection.networkName.value = NetworkNameModel.Derived(CARRIER_MERGED_NAME) connection.networkName.value = NetworkNameModel.IntentDerived(CARRIER_MERGED_NAME)
connection.numberOfLevels.value = event.numberOfLevels connection.numberOfLevels.value = event.numberOfLevels
connection.cdmaRoaming.value = false connection.cdmaRoaming.value = false
connection.connectionInfo.value = event.toMobileConnectionModel() connection.connectionInfo.value = event.toMobileConnectionModel()
@@ -336,7 +339,10 @@ constructor(
} }
private fun FakeWifiEventModel.CarrierMerged.toMobileConnectionModel(): MobileConnectionModel { private fun FakeWifiEventModel.CarrierMerged.toMobileConnectionModel(): MobileConnectionModel {
return createCarrierMergedConnectionModel(this.level) return createCarrierMergedConnectionModel(
this.level,
activity.toMobileDataActivityModel(),
)
} }
private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType { private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType {
@@ -371,5 +377,5 @@ class DemoMobileConnectionRepository(
override val cdmaRoaming = MutableStateFlow(false) override val cdmaRoaming = MutableStateFlow(false)
override val networkName = MutableStateFlow(NetworkNameModel.Derived("demo network")) override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived("demo network"))
} }

View File

@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
import android.telephony.TelephonyManager
import android.util.Log import android.util.Log
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
@@ -37,7 +38,6 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
@@ -54,10 +54,18 @@ import kotlinx.coroutines.flow.stateIn
class CarrierMergedConnectionRepository( class CarrierMergedConnectionRepository(
override val subId: Int, override val subId: Int,
override val tableLogBuffer: TableLogBuffer, override val tableLogBuffer: TableLogBuffer,
defaultNetworkName: NetworkNameModel, private val telephonyManager: TelephonyManager,
@Application private val scope: CoroutineScope, @Application private val scope: CoroutineScope,
val wifiRepository: WifiRepository, val wifiRepository: WifiRepository,
) : MobileConnectionRepository { ) : MobileConnectionRepository {
init {
if (telephonyManager.subscriptionId != subId) {
throw IllegalStateException(
"CarrierMergedRepo: TelephonyManager should be created with subId($subId). " +
"Found ${telephonyManager.subscriptionId} instead."
)
}
}
/** /**
* Outputs the carrier merged network to use, or null if we don't have a valid carrier merged * Outputs the carrier merged network to use, or null if we don't have a valid carrier merged
@@ -87,17 +95,28 @@ class CarrierMergedConnectionRepository(
} }
override val connectionInfo: StateFlow<MobileConnectionModel> = override val connectionInfo: StateFlow<MobileConnectionModel> =
network combine(network, wifiRepository.wifiActivity) { network, activity ->
.map { it.toMobileConnectionModel() } if (network == null) {
MobileConnectionModel()
} else {
createCarrierMergedConnectionModel(network.level, activity)
}
}
.stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectionModel()) .stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectionModel())
// Carrier merged is never roaming. override val cdmaRoaming: StateFlow<Boolean> = MutableStateFlow(ROAMING).asStateFlow()
override val cdmaRoaming: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
// TODO(b/238425913): Fetch the carrier merged network name.
override val networkName: StateFlow<NetworkNameModel> = override val networkName: StateFlow<NetworkNameModel> =
flowOf(defaultNetworkName) network
.stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName) // The SIM operator name should be the same throughout the lifetime of a subId, **but**
// it may not be available when this repo is created because it takes time to load. To
// be safe, we re-fetch it each time the network has changed.
.map { NetworkNameModel.SimDerived(telephonyManager.simOperatorName) }
.stateIn(
scope,
SharingStarted.WhileSubscribed(),
NetworkNameModel.SimDerived(telephonyManager.simOperatorName),
)
override val numberOfLevels: StateFlow<Int> = override val numberOfLevels: StateFlow<Int> =
wifiRepository.wifiNetwork wifiRepository.wifiNetwork
@@ -112,37 +131,24 @@ class CarrierMergedConnectionRepository(
override val dataEnabled: StateFlow<Boolean> = wifiRepository.isWifiEnabled override val dataEnabled: StateFlow<Boolean> = wifiRepository.isWifiEnabled
private fun WifiNetworkModel.CarrierMerged?.toMobileConnectionModel(): MobileConnectionModel {
if (this == null) {
return MobileConnectionModel()
}
return createCarrierMergedConnectionModel(level)
}
companion object { companion object {
/** /**
* Creates an instance of [MobileConnectionModel] that represents a carrier merged network * Creates an instance of [MobileConnectionModel] that represents a carrier merged network
* with the given [level]. * with the given [level] and [activity].
*/ */
fun createCarrierMergedConnectionModel(level: Int): MobileConnectionModel { fun createCarrierMergedConnectionModel(
level: Int,
activity: DataActivityModel,
): MobileConnectionModel {
return MobileConnectionModel( return MobileConnectionModel(
primaryLevel = level, primaryLevel = level,
cdmaLevel = level, cdmaLevel = level,
// A [WifiNetworkModel.CarrierMerged] instance is always connected. dataActivityDirection = activity,
// (A [WifiNetworkModel.Inactive] represents a disconnected network.) // Here and below: These values are always the same for every carrier-merged
dataConnectionState = DataConnectionState.Connected, // connection.
// TODO(b/238425913): This should come from [WifiRepository.wifiActivity].
dataActivityDirection =
DataActivityModel(
hasActivityIn = false,
hasActivityOut = false,
),
resolvedNetworkType = ResolvedNetworkType.CarrierMergedNetworkType, resolvedNetworkType = ResolvedNetworkType.CarrierMergedNetworkType,
// Carrier merged is never roaming dataConnectionState = DataConnectionState.Connected,
isRoaming = false, isRoaming = ROAMING,
// TODO(b/238425913): Verify that these fields never change for carrier merged.
isEmergencyOnly = false, isEmergencyOnly = false,
operatorAlphaShort = null, operatorAlphaShort = null,
isInService = true, isInService = true,
@@ -150,24 +156,27 @@ class CarrierMergedConnectionRepository(
carrierNetworkChangeActive = false, carrierNetworkChangeActive = false,
) )
} }
// Carrier merged is never roaming
private const val ROAMING = false
} }
@SysUISingleton @SysUISingleton
class Factory class Factory
@Inject @Inject
constructor( constructor(
private val telephonyManager: TelephonyManager,
@Application private val scope: CoroutineScope, @Application private val scope: CoroutineScope,
private val wifiRepository: WifiRepository, private val wifiRepository: WifiRepository,
) { ) {
fun build( fun build(
subId: Int, subId: Int,
mobileLogger: TableLogBuffer, mobileLogger: TableLogBuffer,
defaultNetworkName: NetworkNameModel,
): MobileConnectionRepository { ): MobileConnectionRepository {
return CarrierMergedConnectionRepository( return CarrierMergedConnectionRepository(
subId, subId,
mobileLogger, mobileLogger,
defaultNetworkName, telephonyManager.createForSubscriptionId(subId),
scope, scope,
wifiRepository, wifiRepository,
) )

View File

@@ -86,7 +86,7 @@ class FullMobileConnectionRepository(
} }
private val carrierMergedRepo: MobileConnectionRepository by lazy { private val carrierMergedRepo: MobileConnectionRepository by lazy {
carrierMergedRepoFactory.build(subId, tableLogBuffer, defaultNetworkName) carrierMergedRepoFactory.build(subId, tableLogBuffer)
} }
@VisibleForTesting @VisibleForTesting

View File

@@ -61,6 +61,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
@@ -91,7 +92,7 @@ class MobileConnectionRepositoryImpl(
init { init {
if (telephonyManager.subscriptionId != subId) { if (telephonyManager.subscriptionId != subId) {
throw IllegalStateException( throw IllegalStateException(
"TelephonyManager should be created with subId($subId). " + "MobileRepo: TelephonyManager should be created with subId($subId). " +
"Found ${telephonyManager.subscriptionId} instead." "Found ${telephonyManager.subscriptionId} instead."
) )
} }
@@ -267,15 +268,14 @@ class MobileConnectionRepositoryImpl(
override val networkName: StateFlow<NetworkNameModel> = override val networkName: StateFlow<NetworkNameModel> =
broadcastDispatcher broadcastDispatcher
.broadcastFlow(IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED)) { .broadcastFlow(
intent, filter = IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED),
_ -> map = { intent, _ -> intent },
if (intent.getIntExtra(EXTRA_SUBSCRIPTION_ID, INVALID_SUBSCRIPTION_ID) != subId) { )
defaultNetworkName .filter { intent ->
} else { intent.getIntExtra(EXTRA_SUBSCRIPTION_ID, INVALID_SUBSCRIPTION_ID) == subId
intent.toNetworkNameModel(networkNameSeparator) ?: defaultNetworkName
}
} }
.map { intent -> intent.toNetworkNameModel(networkNameSeparator) ?: defaultNetworkName }
.stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName) .stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName)
override val dataEnabled = run { override val dataEnabled = run {

View File

@@ -158,7 +158,7 @@ class MobileIconInteractorImpl(
if ( if (
networkName is NetworkNameModel.Default && connection.operatorAlphaShort != null networkName is NetworkNameModel.Default && connection.operatorAlphaShort != null
) { ) {
NetworkNameModel.Derived(connection.operatorAlphaShort) NetworkNameModel.IntentDerived(connection.operatorAlphaShort)
} else { } else {
networkName networkName
} }

View File

@@ -53,7 +53,7 @@ constructor(
private fun Bundle.activeWifiEvent(): FakeWifiEventModel.Wifi { private fun Bundle.activeWifiEvent(): FakeWifiEventModel.Wifi {
val level = getString("level")?.toInt() val level = getString("level")?.toInt()
val activity = getString("activity")?.toActivity() val activity = getString("activity").toActivity()
val ssid = getString("ssid") val ssid = getString("ssid")
val validated = getString("fully").toBoolean() val validated = getString("fully").toBoolean()
@@ -69,11 +69,12 @@ constructor(
val subId = getString("slot")?.toInt() ?: DEFAULT_CARRIER_MERGED_SUB_ID val subId = getString("slot")?.toInt() ?: DEFAULT_CARRIER_MERGED_SUB_ID
val level = getString("level")?.toInt() ?: 0 val level = getString("level")?.toInt() ?: 0
val numberOfLevels = getString("numlevels")?.toInt() ?: DEFAULT_NUM_LEVELS val numberOfLevels = getString("numlevels")?.toInt() ?: DEFAULT_NUM_LEVELS
val activity = getString("activity").toActivity()
return FakeWifiEventModel.CarrierMerged(subId, level, numberOfLevels) return FakeWifiEventModel.CarrierMerged(subId, level, numberOfLevels, activity)
} }
private fun String.toActivity(): Int = private fun String?.toActivity(): Int =
when (this) { when (this) {
"inout" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT "inout" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT
"in" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN "in" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN

View File

@@ -80,17 +80,14 @@ constructor(
private fun processEnabledWifiState(event: FakeWifiEventModel.Wifi) { private fun processEnabledWifiState(event: FakeWifiEventModel.Wifi) {
_isWifiEnabled.value = true _isWifiEnabled.value = true
_isWifiDefault.value = true _isWifiDefault.value = true
_wifiActivity.value = _wifiActivity.value = event.activity.toWifiDataActivityModel()
event.activity?.toWifiDataActivityModel()
?: DataActivityModel(hasActivityIn = false, hasActivityOut = false)
_wifiNetwork.value = event.toWifiNetworkModel() _wifiNetwork.value = event.toWifiNetworkModel()
} }
private fun processCarrierMergedWifiState(event: FakeWifiEventModel.CarrierMerged) { private fun processCarrierMergedWifiState(event: FakeWifiEventModel.CarrierMerged) {
_isWifiEnabled.value = true _isWifiEnabled.value = true
_isWifiDefault.value = true _isWifiDefault.value = true
// TODO(b/238425913): Support activity in demo mode. _wifiActivity.value = event.activity.toWifiDataActivityModel()
_wifiActivity.value = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
_wifiNetwork.value = event.toCarrierMergedModel() _wifiNetwork.value = event.toCarrierMergedModel()
} }

View File

@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model package com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model
import android.telephony.Annotation
/** /**
* Model for demo wifi commands, ported from [NetworkControllerImpl] * Model for demo wifi commands, ported from [NetworkControllerImpl]
* *
@@ -24,7 +26,7 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model
sealed interface FakeWifiEventModel { sealed interface FakeWifiEventModel {
data class Wifi( data class Wifi(
val level: Int?, val level: Int?,
val activity: Int?, @Annotation.DataActivityType val activity: Int,
val ssid: String?, val ssid: String?,
val validated: Boolean?, val validated: Boolean?,
) : FakeWifiEventModel ) : FakeWifiEventModel
@@ -33,6 +35,7 @@ sealed interface FakeWifiEventModel {
val subscriptionId: Int, val subscriptionId: Int,
val level: Int, val level: Int,
val numberOfLevels: Int, val numberOfLevels: Int,
@Annotation.DataActivityType val activity: Int,
) : FakeWifiEventModel ) : FakeWifiEventModel
object WifiDisabled : FakeWifiEventModel object WifiDisabled : FakeWifiEventModel

View File

@@ -138,7 +138,8 @@ internal class DemoMobileConnectionParameterizedTest(private val testCase: TestC
assertThat(connectionInfo.carrierNetworkChangeActive) assertThat(connectionInfo.carrierNetworkChangeActive)
.isEqualTo(model.carrierNetworkChange) .isEqualTo(model.carrierNetworkChange)
assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming) assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming)
assertThat(conn.networkName.value).isEqualTo(NetworkNameModel.Derived(model.name)) assertThat(conn.networkName.value)
.isEqualTo(NetworkNameModel.IntentDerived(model.name))
// TODO(b/261029387): check these once we start handling them // TODO(b/261029387): check these once we start handling them
assertThat(connectionInfo.isEmergencyOnly).isFalse() assertThat(connectionInfo.isEmergencyOnly).isFalse()

View File

@@ -539,7 +539,8 @@ class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
assertThat(connectionInfo.carrierNetworkChangeActive) assertThat(connectionInfo.carrierNetworkChangeActive)
.isEqualTo(model.carrierNetworkChange) .isEqualTo(model.carrierNetworkChange)
assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming) assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming)
assertThat(conn.networkName.value).isEqualTo(NetworkNameModel.Derived(model.name)) assertThat(conn.networkName.value)
.isEqualTo(NetworkNameModel.IntentDerived(model.name))
// TODO(b/261029387) check these once we start handling them // TODO(b/261029387) check these once we start handling them
assertThat(connectionInfo.isEmergencyOnly).isFalse() assertThat(connectionInfo.isEmergencyOnly).isFalse()
@@ -594,9 +595,11 @@ fun validCarrierMergedEvent(
subId: Int = 1, subId: Int = 1,
level: Int = 1, level: Int = 1,
numberOfLevels: Int = 4, numberOfLevels: Int = 4,
activity: Int = DATA_ACTIVITY_NONE,
): FakeWifiEventModel.CarrierMerged = ): FakeWifiEventModel.CarrierMerged =
FakeWifiEventModel.CarrierMerged( FakeWifiEventModel.CarrierMerged(
subscriptionId = subId, subscriptionId = subId,
level = level, level = level,
numberOfLevels = numberOfLevels, numberOfLevels = numberOfLevels,
activity = activity,
) )

View File

@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
import android.telephony.TelephonyManager
import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
@@ -27,6 +28,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetwork
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@@ -49,6 +51,7 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
private lateinit var wifiRepository: FakeWifiRepository private lateinit var wifiRepository: FakeWifiRepository
@Mock private lateinit var logger: TableLogBuffer @Mock private lateinit var logger: TableLogBuffer
@Mock private lateinit var telephonyManager: TelephonyManager
private val testDispatcher = UnconfinedTestDispatcher() private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher) private val testScope = TestScope(testDispatcher)
@@ -56,13 +59,16 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
@Before @Before
fun setUp() { fun setUp() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
whenever(telephonyManager.subscriptionId).thenReturn(SUB_ID)
whenever(telephonyManager.simOperatorName).thenReturn("")
wifiRepository = FakeWifiRepository() wifiRepository = FakeWifiRepository()
underTest = underTest =
CarrierMergedConnectionRepository( CarrierMergedConnectionRepository(
SUB_ID, SUB_ID,
logger, logger,
NetworkNameModel.Default("name"), telephonyManager,
testScope.backgroundScope, testScope.backgroundScope,
wifiRepository, wifiRepository,
) )
@@ -134,6 +140,44 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun connectionInfo_activity_comesFromWifiActivity() =
testScope.runTest {
var latest: MobileConnectionModel? = null
val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
wifiRepository.setIsWifiEnabled(true)
wifiRepository.setIsWifiDefault(true)
wifiRepository.setWifiNetwork(
WifiNetworkModel.CarrierMerged(
networkId = NET_ID,
subscriptionId = SUB_ID,
level = 3,
)
)
wifiRepository.setWifiActivity(
DataActivityModel(
hasActivityIn = true,
hasActivityOut = false,
)
)
assertThat(latest!!.dataActivityDirection.hasActivityIn).isTrue()
assertThat(latest!!.dataActivityDirection.hasActivityOut).isFalse()
wifiRepository.setWifiActivity(
DataActivityModel(
hasActivityIn = false,
hasActivityOut = true,
)
)
assertThat(latest!!.dataActivityDirection.hasActivityIn).isFalse()
assertThat(latest!!.dataActivityDirection.hasActivityOut).isTrue()
job.cancel()
}
@Test @Test
fun connectionInfo_carrierMergedWifi_wrongSubId_isDefault() = fun connectionInfo_carrierMergedWifi_wrongSubId_isDefault() =
testScope.runTest { testScope.runTest {
@@ -244,6 +288,43 @@ class CarrierMergedConnectionRepositoryTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun networkName_usesSimOperatorNameAsInitial() =
testScope.runTest {
whenever(telephonyManager.simOperatorName).thenReturn("Test SIM name")
var latest: NetworkNameModel? = null
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("Test SIM name"))
job.cancel()
}
@Test
fun networkName_updatesOnNetworkUpdate() =
testScope.runTest {
whenever(telephonyManager.simOperatorName).thenReturn("Test SIM name")
var latest: NetworkNameModel? = null
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("Test SIM name"))
whenever(telephonyManager.simOperatorName).thenReturn("New SIM name")
wifiRepository.setWifiNetwork(
WifiNetworkModel.CarrierMerged(
networkId = NET_ID,
subscriptionId = SUB_ID,
level = 3,
)
)
assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("New SIM name"))
job.cancel()
}
private companion object { private companion object {
const val SUB_ID = 123 const val SUB_ID = 123
const val NET_ID = 456 const val NET_ID = 456

View File

@@ -88,8 +88,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
) )
) )
.thenReturn(mobileRepo) .thenReturn(mobileRepo)
whenever(carrierMergedFactory.build(eq(SUB_ID), any(), eq(DEFAULT_NAME))) whenever(carrierMergedFactory.build(eq(SUB_ID), any())).thenReturn(carrierMergedRepo)
.thenReturn(carrierMergedRepo)
} }
@Test @Test
@@ -127,7 +126,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
assertThat(underTest.activeRepo.value).isEqualTo(mobileRepo) assertThat(underTest.activeRepo.value).isEqualTo(mobileRepo)
assertThat(underTest.connectionInfo.value).isEqualTo(mobileConnectionInfo) assertThat(underTest.connectionInfo.value).isEqualTo(mobileConnectionInfo)
verify(carrierMergedFactory, never()).build(SUB_ID, tableLogBuffer, DEFAULT_NAME) verify(carrierMergedFactory, never()).build(SUB_ID, tableLogBuffer)
} }
@Test @Test
@@ -364,9 +363,10 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
fun connectionInfo_logging_notCarrierMerged_getsUpdates() = fun connectionInfo_logging_notCarrierMerged_getsUpdates() =
testScope.runTest { testScope.runTest {
// SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
val telephonyManager = mock<TelephonyManager>() val telephonyManager =
mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
createRealMobileRepo(telephonyManager) createRealMobileRepo(telephonyManager)
createRealCarrierMergedRepo(FakeWifiRepository()) createRealCarrierMergedRepo(telephonyManager, FakeWifiRepository())
initializeRepo(startingIsCarrierMerged = false) initializeRepo(startingIsCarrierMerged = false)
@@ -401,9 +401,11 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
fun connectionInfo_logging_carrierMerged_getsUpdates() = fun connectionInfo_logging_carrierMerged_getsUpdates() =
testScope.runTest { testScope.runTest {
// SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
createRealMobileRepo(mock()) val telephonyManager =
mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
createRealMobileRepo(telephonyManager)
val wifiRepository = FakeWifiRepository() val wifiRepository = FakeWifiRepository()
createRealCarrierMergedRepo(wifiRepository) createRealCarrierMergedRepo(telephonyManager, wifiRepository)
initializeRepo(startingIsCarrierMerged = true) initializeRepo(startingIsCarrierMerged = true)
@@ -441,11 +443,12 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
fun connectionInfo_logging_updatesWhenCarrierMergedUpdates() = fun connectionInfo_logging_updatesWhenCarrierMergedUpdates() =
testScope.runTest { testScope.runTest {
// SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
val telephonyManager = mock<TelephonyManager>() val telephonyManager =
mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
createRealMobileRepo(telephonyManager) createRealMobileRepo(telephonyManager)
val wifiRepository = FakeWifiRepository() val wifiRepository = FakeWifiRepository()
createRealCarrierMergedRepo(wifiRepository) createRealCarrierMergedRepo(telephonyManager, wifiRepository)
initializeRepo(startingIsCarrierMerged = false) initializeRepo(startingIsCarrierMerged = false)
@@ -516,11 +519,12 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
fun connectionInfo_logging_doesNotLogUpdatesForNotActiveRepo() = fun connectionInfo_logging_doesNotLogUpdatesForNotActiveRepo() =
testScope.runTest { testScope.runTest {
// SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
val telephonyManager = mock<TelephonyManager>() val telephonyManager =
mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
createRealMobileRepo(telephonyManager) createRealMobileRepo(telephonyManager)
val wifiRepository = FakeWifiRepository() val wifiRepository = FakeWifiRepository()
createRealCarrierMergedRepo(wifiRepository) createRealCarrierMergedRepo(telephonyManager, wifiRepository)
// WHEN isCarrierMerged = false // WHEN isCarrierMerged = false
initializeRepo(startingIsCarrierMerged = false) initializeRepo(startingIsCarrierMerged = false)
@@ -617,6 +621,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
} }
private fun createRealCarrierMergedRepo( private fun createRealCarrierMergedRepo(
telephonyManager: TelephonyManager,
wifiRepository: FakeWifiRepository, wifiRepository: FakeWifiRepository,
): CarrierMergedConnectionRepository { ): CarrierMergedConnectionRepository {
wifiRepository.setIsWifiEnabled(true) wifiRepository.setIsWifiEnabled(true)
@@ -625,12 +630,11 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
CarrierMergedConnectionRepository( CarrierMergedConnectionRepository(
SUB_ID, SUB_ID,
tableLogBuffer, tableLogBuffer,
defaultNetworkName = NetworkNameModel.Default("default"), telephonyManager,
testScope.backgroundScope, testScope.backgroundScope,
wifiRepository, wifiRepository,
) )
whenever(carrierMergedFactory.build(eq(SUB_ID), any(), eq(DEFAULT_NAME))) whenever(carrierMergedFactory.build(eq(SUB_ID), any())).thenReturn(realRepo)
.thenReturn(realRepo)
return realRepo return realRepo
} }

View File

@@ -24,7 +24,6 @@ import android.telephony.ServiceState
import android.telephony.ServiceState.STATE_IN_SERVICE import android.telephony.ServiceState.STATE_IN_SERVICE
import android.telephony.ServiceState.STATE_OUT_OF_SERVICE import android.telephony.ServiceState.STATE_OUT_OF_SERVICE
import android.telephony.SignalStrength import android.telephony.SignalStrength
import android.telephony.SubscriptionInfo
import android.telephony.TelephonyCallback import android.telephony.TelephonyCallback
import android.telephony.TelephonyCallback.DataActivityListener import android.telephony.TelephonyCallback.DataActivityListener
import android.telephony.TelephonyCallback.ServiceStateListener import android.telephony.TelephonyCallback.ServiceStateListener
@@ -556,16 +555,51 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
} }
@Test @Test
fun `network name - broadcast not for this sub id - returns default`() = fun `network name - broadcast not for this sub id - keeps old value`() =
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {
var latest: NetworkNameModel? = null var latest: NetworkNameModel? = null
val job = underTest.networkName.onEach { latest = it }.launchIn(this) val job = underTest.networkName.onEach { latest = it }.launchIn(this)
val intent = spnIntent(subId = 101) val intent = spnIntent()
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver -> fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(context, intent) receiver.onReceive(context, intent)
} }
assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
// WHEN an intent with a different subId is sent
val wrongSubIntent = spnIntent(subId = 101)
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(context, wrongSubIntent)
}
// THEN the previous intent's name is still used
assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
job.cancel()
}
@Test
fun `network name - broadcast has no data - updates to default`() =
runBlocking(IMMEDIATE) {
var latest: NetworkNameModel? = null
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
val intent = spnIntent()
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(context, intent)
}
assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
val intentWithoutInfo =
spnIntent(
showSpn = false,
showPlmn = false,
)
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(context, intentWithoutInfo)
}
assertThat(latest).isEqualTo(DEFAULT_NAME) assertThat(latest).isEqualTo(DEFAULT_NAME)
@@ -573,7 +607,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
} }
@Test @Test
fun `network name - operatorAlphaShort - tracked`() = fun `operatorAlphaShort - tracked`() =
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {
var latest: String? = null var latest: String? = null
@@ -703,8 +737,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
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
private val SUB_1 =
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
private val DEFAULT_NAME = NetworkNameModel.Default("default name") private val DEFAULT_NAME = NetworkNameModel.Default("default name")
private const val SEP = "-" private const val SEP = "-"

View File

@@ -94,6 +94,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
@Before @Before
fun setUp() { fun setUp() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
whenever(telephonyManager.simOperatorName).thenReturn("")
// Set up so the individual connection repositories // Set up so the individual connection repositories
whenever(telephonyManager.createForSubscriptionId(anyInt())).thenAnswer { invocation -> whenever(telephonyManager.createForSubscriptionId(anyInt())).thenAnswer { invocation ->
@@ -141,6 +142,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
) )
carrierMergedFactory = carrierMergedFactory =
CarrierMergedConnectionRepository.Factory( CarrierMergedConnectionRepository.Factory(
telephonyManager,
scope, scope,
wifiRepository, wifiRepository,
) )

View File

@@ -45,7 +45,7 @@ class FakeMobileIconInteractor(
private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G) private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G)
override val networkTypeIconGroup = _iconGroup override val networkTypeIconGroup = _iconGroup
override val networkName = MutableStateFlow(NetworkNameModel.Derived("demo mode")) override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived("demo mode"))
private val _isEmergencyOnly = MutableStateFlow(false) private val _isEmergencyOnly = MutableStateFlow(false)
override val isEmergencyOnly = _isEmergencyOnly override val isEmergencyOnly = _isEmergencyOnly

View File

@@ -531,7 +531,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
) )
yield() yield()
assertThat(latest).isEqualTo(NetworkNameModel.Derived(testOperatorName)) assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived(testOperatorName))
// Default network name, operator name is null, uses the default // Default network name, operator name is null, uses the default
connectionRepository.setConnectionInfo(MobileConnectionModel(operatorAlphaShort = null)) connectionRepository.setConnectionInfo(MobileConnectionModel(operatorAlphaShort = null))
@@ -575,6 +575,6 @@ class MobileIconInteractorTest : SysuiTestCase() {
private const val SUB_1_ID = 1 private const val SUB_1_ID = 1
private val DEFAULT_NAME = NetworkNameModel.Default("test default name") private val DEFAULT_NAME = NetworkNameModel.Default("test default name")
private val DERIVED_NAME = NetworkNameModel.Derived("test derived name") private val DERIVED_NAME = NetworkNameModel.IntentDerived("test derived name")
} }
} }