1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod 18 19 import android.content.BroadcastReceiver 20 import android.content.Context 21 import android.content.Intent 22 import android.net.ConnectivityManager 23 import android.net.ConnectivityManager.NetworkCallback 24 import android.platform.test.annotations.DisableFlags 25 import android.platform.test.annotations.EnableFlags 26 import android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WLAN 27 import android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN 28 import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL 29 import android.telephony.CarrierConfigManager.KEY_SHOW_5G_SLICE_ICON_BOOL 30 import android.telephony.NetworkRegistrationInfo 31 import android.telephony.NetworkRegistrationInfo.DOMAIN_PS 32 import android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_DENIED 33 import android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME 34 import android.telephony.ServiceState 35 import android.telephony.ServiceState.STATE_IN_SERVICE 36 import android.telephony.ServiceState.STATE_OUT_OF_SERVICE 37 import android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX 38 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET 39 import android.telephony.TelephonyCallback 40 import android.telephony.TelephonyCallback.CarrierRoamingNtnModeListener 41 import android.telephony.TelephonyCallback.DataActivityListener 42 import android.telephony.TelephonyCallback.DisplayInfoListener 43 import android.telephony.TelephonyCallback.ServiceStateListener 44 import android.telephony.TelephonyDisplayInfo 45 import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA 46 import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE 47 import android.telephony.TelephonyManager 48 import android.telephony.TelephonyManager.DATA_ACTIVITY_DORMANT 49 import android.telephony.TelephonyManager.DATA_ACTIVITY_IN 50 import android.telephony.TelephonyManager.DATA_ACTIVITY_INOUT 51 import android.telephony.TelephonyManager.DATA_ACTIVITY_NONE 52 import android.telephony.TelephonyManager.DATA_ACTIVITY_OUT 53 import android.telephony.TelephonyManager.DATA_CONNECTED 54 import android.telephony.TelephonyManager.DATA_CONNECTING 55 import android.telephony.TelephonyManager.DATA_DISCONNECTED 56 import android.telephony.TelephonyManager.DATA_DISCONNECTING 57 import android.telephony.TelephonyManager.DATA_HANDOVER_IN_PROGRESS 58 import android.telephony.TelephonyManager.DATA_SUSPENDED 59 import android.telephony.TelephonyManager.DATA_UNKNOWN 60 import android.telephony.TelephonyManager.ERI_OFF 61 import android.telephony.TelephonyManager.ERI_ON 62 import android.telephony.TelephonyManager.EXTRA_CARRIER_ID 63 import android.telephony.TelephonyManager.EXTRA_DATA_SPN 64 import android.telephony.TelephonyManager.EXTRA_PLMN 65 import android.telephony.TelephonyManager.EXTRA_SHOW_PLMN 66 import android.telephony.TelephonyManager.EXTRA_SHOW_SPN 67 import android.telephony.TelephonyManager.EXTRA_SPN 68 import android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID 69 import android.telephony.TelephonyManager.NETWORK_TYPE_LTE 70 import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN 71 import androidx.test.ext.junit.runners.AndroidJUnit4 72 import androidx.test.filters.SmallTest 73 import com.android.settingslib.mobile.MobileMappings 74 import com.android.systemui.Flags 75 import com.android.systemui.SysuiTestCase 76 import com.android.systemui.coroutines.collectLastValue 77 import com.android.systemui.flags.FakeFeatureFlagsClassic 78 import com.android.systemui.flags.Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO 79 import com.android.systemui.log.table.TableLogBuffer 80 import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger 81 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState 82 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel 83 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType 84 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType 85 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType 86 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType 87 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel 88 import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig 89 import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.configWithOverride 90 import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig 91 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS 92 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.signalStrength 93 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.telephonyDisplayInfo 94 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy 95 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel 96 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel 97 import com.android.systemui.util.mockito.mock 98 import com.android.systemui.util.mockito.whenever 99 import com.android.systemui.util.mockito.withArgCaptor 100 import com.google.common.truth.Truth.assertThat 101 import kotlinx.coroutines.ExperimentalCoroutinesApi 102 import kotlinx.coroutines.flow.MutableStateFlow 103 import kotlinx.coroutines.flow.launchIn 104 import kotlinx.coroutines.flow.onEach 105 import kotlinx.coroutines.test.TestScope 106 import kotlinx.coroutines.test.UnconfinedTestDispatcher 107 import kotlinx.coroutines.test.runTest 108 import org.junit.Before 109 import org.junit.Test 110 import org.junit.runner.RunWith 111 import org.mockito.Mock 112 import org.mockito.Mockito.verify 113 import org.mockito.MockitoAnnotations 114 import org.mockito.kotlin.any 115 import org.mockito.kotlin.argumentCaptor 116 117 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") 118 @OptIn(ExperimentalCoroutinesApi::class) 119 @SmallTest 120 @RunWith(AndroidJUnit4::class) 121 class MobileConnectionRepositoryTest : SysuiTestCase() { 122 private lateinit var underTest: MobileConnectionRepositoryImpl 123 124 private val flags = <lambda>null125 FakeFeatureFlagsClassic().also { it.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) } 126 127 @Mock private lateinit var connectivityManager: ConnectivityManager 128 @Mock private lateinit var telephonyManager: TelephonyManager 129 @Mock private lateinit var logger: MobileInputLogger 130 @Mock private lateinit var tableLogger: TableLogBuffer 131 @Mock private lateinit var context: Context 132 133 private val mobileMappings = FakeMobileMappingsProxy() 134 private val systemUiCarrierConfig = 135 SystemUiCarrierConfig( 136 SUB_1_ID, 137 createTestConfig(), 138 ) 139 140 private val testDispatcher = UnconfinedTestDispatcher() 141 private val testScope = TestScope(testDispatcher) 142 143 private val subscriptionModel: MutableStateFlow<SubscriptionModel?> = 144 MutableStateFlow( 145 SubscriptionModel( 146 subscriptionId = SUB_1_ID, 147 carrierName = DEFAULT_NAME, 148 profileClass = PROFILE_CLASS_UNSET, 149 ) 150 ) 151 152 @Before setUpnull153 fun setUp() { 154 MockitoAnnotations.initMocks(this) 155 whenever(telephonyManager.subscriptionId).thenReturn(SUB_1_ID) 156 157 underTest = 158 MobileConnectionRepositoryImpl( 159 SUB_1_ID, 160 context, 161 subscriptionModel, 162 DEFAULT_NAME_MODEL, 163 SEP, 164 connectivityManager, 165 telephonyManager, 166 systemUiCarrierConfig, 167 fakeBroadcastDispatcher, 168 mobileMappings, 169 testDispatcher, 170 logger, 171 tableLogger, 172 flags, 173 testScope.backgroundScope, 174 ) 175 } 176 177 @Test emergencyOnlynull178 fun emergencyOnly() = 179 testScope.runTest { 180 var latest: Boolean? = null 181 val job = underTest.isEmergencyOnly.onEach { latest = it }.launchIn(this) 182 183 val serviceState = ServiceState() 184 serviceState.isEmergencyOnly = true 185 186 getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState) 187 188 assertThat(latest).isEqualTo(true) 189 190 job.cancel() 191 } 192 193 @Test emergencyOnly_togglesnull194 fun emergencyOnly_toggles() = 195 testScope.runTest { 196 var latest: Boolean? = null 197 val job = underTest.isEmergencyOnly.onEach { latest = it }.launchIn(this) 198 199 val callback = getTelephonyCallbackForType<ServiceStateListener>() 200 callback.onServiceStateChanged(ServiceState().also { it.isEmergencyOnly = true }) 201 assertThat(latest).isTrue() 202 203 callback.onServiceStateChanged(ServiceState().also { it.isEmergencyOnly = false }) 204 205 assertThat(latest).isFalse() 206 207 job.cancel() 208 } 209 210 @Test cdmaLevelUpdatesnull211 fun cdmaLevelUpdates() = 212 testScope.runTest { 213 var latest: Int? = null 214 val job = underTest.cdmaLevel.onEach { latest = it }.launchIn(this) 215 216 val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>() 217 var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true) 218 callback.onSignalStrengthsChanged(strength) 219 220 assertThat(latest).isEqualTo(2) 221 222 // gsmLevel updates, no change to cdmaLevel 223 strength = signalStrength(gsmLevel = 3, cdmaLevel = 2, isGsm = true) 224 callback.onSignalStrengthsChanged(strength) 225 226 assertThat(latest).isEqualTo(2) 227 228 job.cancel() 229 } 230 231 @Test gsmLevelUpdatesnull232 fun gsmLevelUpdates() = 233 testScope.runTest { 234 var latest: Int? = null 235 val job = underTest.primaryLevel.onEach { latest = it }.launchIn(this) 236 237 val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>() 238 var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true) 239 callback.onSignalStrengthsChanged(strength) 240 241 assertThat(latest).isEqualTo(1) 242 243 strength = signalStrength(gsmLevel = 3, cdmaLevel = 2, isGsm = true) 244 callback.onSignalStrengthsChanged(strength) 245 246 assertThat(latest).isEqualTo(3) 247 248 job.cancel() 249 } 250 251 @Test isGsmnull252 fun isGsm() = 253 testScope.runTest { 254 var latest: Boolean? = null 255 val job = underTest.isGsm.onEach { latest = it }.launchIn(this) 256 257 val callback = getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>() 258 var strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = true) 259 callback.onSignalStrengthsChanged(strength) 260 261 assertThat(latest).isTrue() 262 263 strength = signalStrength(gsmLevel = 1, cdmaLevel = 2, isGsm = false) 264 callback.onSignalStrengthsChanged(strength) 265 266 assertThat(latest).isFalse() 267 268 job.cancel() 269 } 270 271 @Test dataConnectionState_connectednull272 fun dataConnectionState_connected() = 273 testScope.runTest { 274 var latest: DataConnectionState? = null 275 val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this) 276 277 val callback = 278 getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>() 279 callback.onDataConnectionStateChanged(DATA_CONNECTED, 200 /* unused */) 280 281 assertThat(latest).isEqualTo(DataConnectionState.Connected) 282 283 job.cancel() 284 } 285 286 @Test dataConnectionState_connectingnull287 fun dataConnectionState_connecting() = 288 testScope.runTest { 289 var latest: DataConnectionState? = null 290 val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this) 291 292 val callback = 293 getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>() 294 callback.onDataConnectionStateChanged(DATA_CONNECTING, 200 /* unused */) 295 296 assertThat(latest).isEqualTo(DataConnectionState.Connecting) 297 298 job.cancel() 299 } 300 301 @Test dataConnectionState_disconnectednull302 fun dataConnectionState_disconnected() = 303 testScope.runTest { 304 var latest: DataConnectionState? = null 305 val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this) 306 307 val callback = 308 getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>() 309 callback.onDataConnectionStateChanged(DATA_DISCONNECTED, 200 /* unused */) 310 311 assertThat(latest).isEqualTo(DataConnectionState.Disconnected) 312 313 job.cancel() 314 } 315 316 @Test dataConnectionState_disconnectingnull317 fun dataConnectionState_disconnecting() = 318 testScope.runTest { 319 var latest: DataConnectionState? = null 320 val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this) 321 322 val callback = 323 getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>() 324 callback.onDataConnectionStateChanged(DATA_DISCONNECTING, 200 /* unused */) 325 326 assertThat(latest).isEqualTo(DataConnectionState.Disconnecting) 327 328 job.cancel() 329 } 330 331 @Test dataConnectionState_suspendednull332 fun dataConnectionState_suspended() = 333 testScope.runTest { 334 var latest: DataConnectionState? = null 335 val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this) 336 337 val callback = 338 getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>() 339 callback.onDataConnectionStateChanged(DATA_SUSPENDED, 200 /* unused */) 340 341 assertThat(latest).isEqualTo(DataConnectionState.Suspended) 342 343 job.cancel() 344 } 345 346 @Test dataConnectionState_handoverInProgressnull347 fun dataConnectionState_handoverInProgress() = 348 testScope.runTest { 349 var latest: DataConnectionState? = null 350 val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this) 351 352 val callback = 353 getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>() 354 callback.onDataConnectionStateChanged(DATA_HANDOVER_IN_PROGRESS, 200 /* unused */) 355 356 assertThat(latest).isEqualTo(DataConnectionState.HandoverInProgress) 357 358 job.cancel() 359 } 360 361 @Test dataConnectionState_unknownnull362 fun dataConnectionState_unknown() = 363 testScope.runTest { 364 var latest: DataConnectionState? = null 365 val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this) 366 367 val callback = 368 getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>() 369 callback.onDataConnectionStateChanged(DATA_UNKNOWN, 200 /* unused */) 370 371 assertThat(latest).isEqualTo(DataConnectionState.Unknown) 372 373 job.cancel() 374 } 375 376 @Test dataConnectionState_invalidnull377 fun dataConnectionState_invalid() = 378 testScope.runTest { 379 var latest: DataConnectionState? = null 380 val job = underTest.dataConnectionState.onEach { latest = it }.launchIn(this) 381 382 val callback = 383 getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>() 384 callback.onDataConnectionStateChanged(45, 200 /* unused */) 385 386 assertThat(latest).isEqualTo(DataConnectionState.Invalid) 387 388 job.cancel() 389 } 390 391 @Test dataActivitynull392 fun dataActivity() = 393 testScope.runTest { 394 var latest: DataActivityModel? = null 395 val job = underTest.dataActivityDirection.onEach { latest = it }.launchIn(this) 396 397 val callback = getTelephonyCallbackForType<DataActivityListener>() 398 callback.onDataActivity(DATA_ACTIVITY_INOUT) 399 400 assertThat(latest).isEqualTo(DATA_ACTIVITY_INOUT.toMobileDataActivityModel()) 401 402 job.cancel() 403 } 404 405 @Test carrierId_initialValueCapturednull406 fun carrierId_initialValueCaptured() = 407 testScope.runTest { 408 whenever(telephonyManager.simCarrierId).thenReturn(1234) 409 410 var latest: Int? = null 411 val job = underTest.carrierId.onEach { latest = it }.launchIn(this) 412 413 assertThat(latest).isEqualTo(1234) 414 415 job.cancel() 416 } 417 418 @Test carrierId_updatesOnBroadcastnull419 fun carrierId_updatesOnBroadcast() = 420 testScope.runTest { 421 whenever(telephonyManager.simCarrierId).thenReturn(1234) 422 423 var latest: Int? = null 424 val job = underTest.carrierId.onEach { latest = it }.launchIn(this) 425 426 fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( 427 context, 428 carrierIdIntent(carrierId = 4321), 429 ) 430 431 assertThat(latest).isEqualTo(4321) 432 433 job.cancel() 434 } 435 436 @Test carrierNetworkChangenull437 fun carrierNetworkChange() = 438 testScope.runTest { 439 var latest: Boolean? = null 440 val job = underTest.carrierNetworkChangeActive.onEach { latest = it }.launchIn(this) 441 442 val callback = getTelephonyCallbackForType<TelephonyCallback.CarrierNetworkListener>() 443 callback.onCarrierNetworkChange(true) 444 445 assertThat(latest).isEqualTo(true) 446 447 job.cancel() 448 } 449 450 @Test networkType_defaultnull451 fun networkType_default() = 452 testScope.runTest { 453 var latest: ResolvedNetworkType? = null 454 val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this) 455 456 val expected = UnknownNetworkType 457 458 assertThat(latest).isEqualTo(expected) 459 460 job.cancel() 461 } 462 463 @Test networkType_unknown_hasCorrectKeynull464 fun networkType_unknown_hasCorrectKey() = 465 testScope.runTest { 466 var latest: ResolvedNetworkType? = null 467 val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this) 468 469 val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>() 470 val ti = 471 telephonyDisplayInfo( 472 networkType = NETWORK_TYPE_UNKNOWN, 473 overrideNetworkType = NETWORK_TYPE_UNKNOWN, 474 ) 475 476 callback.onDisplayInfoChanged(ti) 477 478 val expected = UnknownNetworkType 479 assertThat(latest).isEqualTo(expected) 480 assertThat(latest!!.lookupKey).isEqualTo(MobileMappings.toIconKey(NETWORK_TYPE_UNKNOWN)) 481 482 job.cancel() 483 } 484 485 @Test networkType_updatesUsingDefaultnull486 fun networkType_updatesUsingDefault() = 487 testScope.runTest { 488 var latest: ResolvedNetworkType? = null 489 val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this) 490 491 val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>() 492 val overrideType = OVERRIDE_NETWORK_TYPE_NONE 493 val type = NETWORK_TYPE_LTE 494 val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = overrideType) 495 callback.onDisplayInfoChanged(ti) 496 497 val expected = DefaultNetworkType(mobileMappings.toIconKey(type)) 498 assertThat(latest).isEqualTo(expected) 499 500 job.cancel() 501 } 502 503 @Test networkType_updatesUsingOverridenull504 fun networkType_updatesUsingOverride() = 505 testScope.runTest { 506 var latest: ResolvedNetworkType? = null 507 val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this) 508 509 val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>() 510 val type = OVERRIDE_NETWORK_TYPE_LTE_CA 511 val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = type) 512 callback.onDisplayInfoChanged(ti) 513 514 val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type)) 515 assertThat(latest).isEqualTo(expected) 516 517 job.cancel() 518 } 519 520 @Test networkType_unknownNetworkWithOverride_usesOverrideKeynull521 fun networkType_unknownNetworkWithOverride_usesOverrideKey() = 522 testScope.runTest { 523 var latest: ResolvedNetworkType? = null 524 val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this) 525 526 val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>() 527 val unknown = NETWORK_TYPE_UNKNOWN 528 val type = OVERRIDE_NETWORK_TYPE_LTE_CA 529 val ti = telephonyDisplayInfo(unknown, type) 530 callback.onDisplayInfoChanged(ti) 531 532 val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type)) 533 assertThat(latest).isEqualTo(expected) 534 535 job.cancel() 536 } 537 538 @Test dataEnabled_initial_falsenull539 fun dataEnabled_initial_false() = 540 testScope.runTest { 541 whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false) 542 543 assertThat(underTest.dataEnabled.value).isFalse() 544 } 545 546 @Test isDataEnabled_tracksTelephonyCallbacknull547 fun isDataEnabled_tracksTelephonyCallback() = 548 testScope.runTest { 549 var latest: Boolean? = null 550 val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this) 551 552 whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false) 553 assertThat(underTest.dataEnabled.value).isFalse() 554 555 val callback = getTelephonyCallbackForType<TelephonyCallback.DataEnabledListener>() 556 557 callback.onDataEnabledChanged(true, 1) 558 assertThat(latest).isTrue() 559 560 callback.onDataEnabledChanged(false, 1) 561 assertThat(latest).isFalse() 562 563 job.cancel() 564 } 565 566 @Test numberOfLevels_isDefaultnull567 fun numberOfLevels_isDefault() = 568 testScope.runTest { 569 var latest: Int? = null 570 val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this) 571 572 assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS) 573 574 job.cancel() 575 } 576 577 @Test roaming_cdma_queriesTelephonyManagernull578 fun roaming_cdma_queriesTelephonyManager() = 579 testScope.runTest { 580 var latest: Boolean? = null 581 val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this) 582 583 val cb = getTelephonyCallbackForType<ServiceStateListener>() 584 585 // CDMA roaming is off, GSM roaming is on 586 whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF) 587 cb.onServiceStateChanged(ServiceState().also { it.roaming = true }) 588 589 assertThat(latest).isFalse() 590 591 // CDMA roaming is on, GSM roaming is off 592 whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_ON) 593 cb.onServiceStateChanged(ServiceState().also { it.roaming = false }) 594 595 assertThat(latest).isTrue() 596 597 job.cancel() 598 } 599 600 /** 601 * [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber] returns -1 if the service is 602 * not running or if there is an error while retrieving the cdma ERI 603 */ 604 @Test cdmaRoaming_ignoresNegativeOnenull605 fun cdmaRoaming_ignoresNegativeOne() = 606 testScope.runTest { 607 var latest: Boolean? = null 608 val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this) 609 610 val serviceState = ServiceState() 611 serviceState.roaming = false 612 613 val cb = getTelephonyCallbackForType<ServiceStateListener>() 614 615 // CDMA roaming is unavailable (-1), GSM roaming is off 616 whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(-1) 617 cb.onServiceStateChanged(serviceState) 618 619 assertThat(latest).isFalse() 620 621 job.cancel() 622 } 623 624 @Test roaming_gsm_queriesDisplayInfo_viaDisplayInfonull625 fun roaming_gsm_queriesDisplayInfo_viaDisplayInfo() = 626 testScope.runTest { 627 // GIVEN flag is true 628 flags.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) 629 630 // Re-create the repository, because the flag is read at init 631 underTest = 632 MobileConnectionRepositoryImpl( 633 SUB_1_ID, 634 context, 635 subscriptionModel, 636 DEFAULT_NAME_MODEL, 637 SEP, 638 connectivityManager, 639 telephonyManager, 640 systemUiCarrierConfig, 641 fakeBroadcastDispatcher, 642 mobileMappings, 643 testDispatcher, 644 logger, 645 tableLogger, 646 flags, 647 testScope.backgroundScope, 648 ) 649 650 var latest: Boolean? = null 651 val job = underTest.isRoaming.onEach { latest = it }.launchIn(this) 652 653 val cb = getTelephonyCallbackForType<DisplayInfoListener>() 654 655 // CDMA roaming is off, GSM roaming is off 656 whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF) 657 cb.onDisplayInfoChanged( 658 TelephonyDisplayInfo(NETWORK_TYPE_LTE, NETWORK_TYPE_UNKNOWN, false, false, false) 659 ) 660 661 assertThat(latest).isFalse() 662 663 // CDMA roaming is off, GSM roaming is on 664 cb.onDisplayInfoChanged( 665 TelephonyDisplayInfo(NETWORK_TYPE_LTE, NETWORK_TYPE_UNKNOWN, true, false, false) 666 ) 667 668 assertThat(latest).isTrue() 669 670 job.cancel() 671 } 672 673 @Test roaming_gsm_queriesDisplayInfo_viaServiceStatenull674 fun roaming_gsm_queriesDisplayInfo_viaServiceState() = 675 testScope.runTest { 676 // GIVEN flag is false 677 flags.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, false) 678 679 // Re-create the repository, because the flag is read at init 680 underTest = 681 MobileConnectionRepositoryImpl( 682 SUB_1_ID, 683 context, 684 subscriptionModel, 685 DEFAULT_NAME_MODEL, 686 SEP, 687 connectivityManager, 688 telephonyManager, 689 systemUiCarrierConfig, 690 fakeBroadcastDispatcher, 691 mobileMappings, 692 testDispatcher, 693 logger, 694 tableLogger, 695 flags, 696 testScope.backgroundScope, 697 ) 698 699 var latest: Boolean? = null 700 val job = underTest.isRoaming.onEach { latest = it }.launchIn(this) 701 702 val cb = getTelephonyCallbackForType<ServiceStateListener>() 703 704 // CDMA roaming is off, GSM roaming is off 705 whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF) 706 cb.onServiceStateChanged(ServiceState().also { it.roaming = false }) 707 708 assertThat(latest).isFalse() 709 710 // CDMA roaming is off, GSM roaming is on 711 cb.onServiceStateChanged(ServiceState().also { it.roaming = true }) 712 713 assertThat(latest).isTrue() 714 715 job.cancel() 716 } 717 718 @Test activity_updatesFromCallbacknull719 fun activity_updatesFromCallback() = 720 testScope.runTest { 721 var latest: DataActivityModel? = null 722 val job = underTest.dataActivityDirection.onEach { latest = it }.launchIn(this) 723 724 assertThat(latest) 725 .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false)) 726 727 val cb = getTelephonyCallbackForType<DataActivityListener>() 728 cb.onDataActivity(DATA_ACTIVITY_IN) 729 assertThat(latest) 730 .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = false)) 731 732 cb.onDataActivity(DATA_ACTIVITY_OUT) 733 assertThat(latest) 734 .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = true)) 735 736 cb.onDataActivity(DATA_ACTIVITY_INOUT) 737 assertThat(latest) 738 .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = true)) 739 740 cb.onDataActivity(DATA_ACTIVITY_NONE) 741 assertThat(latest) 742 .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false)) 743 744 cb.onDataActivity(DATA_ACTIVITY_DORMANT) 745 assertThat(latest) 746 .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false)) 747 748 cb.onDataActivity(1234) 749 assertThat(latest) 750 .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false)) 751 752 job.cancel() 753 } 754 755 @Test networkNameForSubId_updatesnull756 fun networkNameForSubId_updates() = 757 testScope.runTest { 758 var latest: NetworkNameModel? = null 759 val job = underTest.carrierName.onEach { latest = it }.launchIn(this) 760 761 subscriptionModel.value = 762 SubscriptionModel( 763 subscriptionId = SUB_1_ID, 764 carrierName = DEFAULT_NAME, 765 profileClass = PROFILE_CLASS_UNSET, 766 ) 767 768 assertThat(latest?.name).isEqualTo(DEFAULT_NAME) 769 770 val updatedName = "Derived Carrier" 771 subscriptionModel.value = 772 SubscriptionModel( 773 subscriptionId = SUB_1_ID, 774 carrierName = updatedName, 775 profileClass = PROFILE_CLASS_UNSET, 776 ) 777 778 assertThat(latest?.name).isEqualTo(updatedName) 779 780 job.cancel() 781 } 782 783 @Test networkNameForSubId_defaultWhenSubscriptionModelNullnull784 fun networkNameForSubId_defaultWhenSubscriptionModelNull() = 785 testScope.runTest { 786 var latest: NetworkNameModel? = null 787 val job = underTest.carrierName.onEach { latest = it }.launchIn(this) 788 789 subscriptionModel.value = null 790 791 assertThat(latest?.name).isEqualTo(DEFAULT_NAME) 792 793 job.cancel() 794 } 795 796 @Test networkName_defaultnull797 fun networkName_default() = 798 testScope.runTest { 799 var latest: NetworkNameModel? = null 800 val job = underTest.networkName.onEach { latest = it }.launchIn(this) 801 802 assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL) 803 804 job.cancel() 805 } 806 807 @Test 808 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_usesBroadcastInfo_returnsDerivednull809 fun networkName_usesBroadcastInfo_returnsDerived() = 810 testScope.runTest { 811 var latest: NetworkNameModel? = null 812 val job = underTest.networkName.onEach { latest = it }.launchIn(this) 813 814 val intent = spnIntent() 815 val captor = argumentCaptor<BroadcastReceiver>() 816 verify(context).registerReceiver(captor.capture(), any()) 817 captor.lastValue.onReceive(context, intent) 818 819 // spnIntent() sets all values to true and test strings 820 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 821 822 job.cancel() 823 } 824 825 @Test 826 @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_usesBroadcastInfo_returnsDerived_flagOffnull827 fun networkName_usesBroadcastInfo_returnsDerived_flagOff() = 828 testScope.runTest { 829 var latest: NetworkNameModel? = null 830 val job = underTest.networkName.onEach { latest = it }.launchIn(this) 831 832 val intent = spnIntent() 833 val captor = argumentCaptor<BroadcastReceiver>() 834 verify(context).registerReceiver(captor.capture(), any()) 835 captor.lastValue.onReceive(context, intent) 836 837 // spnIntent() sets all values to true and test strings 838 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 839 840 job.cancel() 841 } 842 843 @Test 844 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_broadcastNotForThisSubId_keepsOldValuenull845 fun networkName_broadcastNotForThisSubId_keepsOldValue() = 846 testScope.runTest { 847 var latest: NetworkNameModel? = null 848 val job = underTest.networkName.onEach { latest = it }.launchIn(this) 849 850 val intent = spnIntent() 851 val captor = argumentCaptor<BroadcastReceiver>() 852 verify(context).registerReceiver(captor.capture(), any()) 853 captor.lastValue.onReceive(context, intent) 854 855 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 856 857 // WHEN an intent with a different subId is sent 858 val wrongSubIntent = spnIntent(subId = 101) 859 860 captor.lastValue.onReceive(context, wrongSubIntent) 861 862 // THEN the previous intent's name is still used 863 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 864 865 job.cancel() 866 } 867 868 @Test 869 @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_broadcastNotForThisSubId_keepsOldValue_flagOffnull870 fun networkName_broadcastNotForThisSubId_keepsOldValue_flagOff() = 871 testScope.runTest { 872 var latest: NetworkNameModel? = null 873 val job = underTest.networkName.onEach { latest = it }.launchIn(this) 874 875 val intent = spnIntent() 876 val captor = argumentCaptor<BroadcastReceiver>() 877 verify(context).registerReceiver(captor.capture(), any()) 878 captor.lastValue.onReceive(context, intent) 879 880 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 881 882 // WHEN an intent with a different subId is sent 883 val wrongSubIntent = spnIntent(subId = 101) 884 885 captor.lastValue.onReceive(context, wrongSubIntent) 886 887 // THEN the previous intent's name is still used 888 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 889 890 job.cancel() 891 } 892 893 @Test 894 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_broadcastHasNoData_updatesToDefaultnull895 fun networkName_broadcastHasNoData_updatesToDefault() = 896 testScope.runTest { 897 var latest: NetworkNameModel? = null 898 val job = underTest.networkName.onEach { latest = it }.launchIn(this) 899 900 val intent = spnIntent() 901 val captor = argumentCaptor<BroadcastReceiver>() 902 verify(context).registerReceiver(captor.capture(), any()) 903 captor.lastValue.onReceive(context, intent) 904 905 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 906 907 val intentWithoutInfo = 908 spnIntent( 909 showSpn = false, 910 showPlmn = false, 911 ) 912 913 captor.lastValue.onReceive(context, intentWithoutInfo) 914 915 assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL) 916 917 job.cancel() 918 } 919 920 @Test 921 @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_broadcastHasNoData_updatesToDefault_flagOffnull922 fun networkName_broadcastHasNoData_updatesToDefault_flagOff() = 923 testScope.runTest { 924 var latest: NetworkNameModel? = null 925 val job = underTest.networkName.onEach { latest = it }.launchIn(this) 926 927 val intent = spnIntent() 928 val captor = argumentCaptor<BroadcastReceiver>() 929 verify(context).registerReceiver(captor.capture(), any()) 930 captor.lastValue.onReceive(context, intent) 931 932 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 933 934 val intentWithoutInfo = 935 spnIntent( 936 showSpn = false, 937 showPlmn = false, 938 ) 939 940 captor.lastValue.onReceive(context, intentWithoutInfo) 941 942 assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL) 943 944 job.cancel() 945 } 946 947 @Test 948 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_usingEagerStrategy_retainsNameBetweenSubscribersnull949 fun networkName_usingEagerStrategy_retainsNameBetweenSubscribers() = 950 testScope.runTest { 951 // Use the [StateFlow.value] getter so we can prove that the collection happens 952 // even when there is no [Job] 953 954 // Starts out default 955 assertThat(underTest.networkName.value).isEqualTo(DEFAULT_NAME_MODEL) 956 957 val intent = spnIntent() 958 val captor = argumentCaptor<BroadcastReceiver>() 959 verify(context).registerReceiver(captor.capture(), any()) 960 captor.lastValue.onReceive(context, intent) 961 962 // The value is still there despite no active subscribers 963 assertThat(underTest.networkName.value) 964 .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 965 } 966 967 @Test 968 @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_usingEagerStrategy_retainsNameBetweenSubscribers_flagOffnull969 fun networkName_usingEagerStrategy_retainsNameBetweenSubscribers_flagOff() = 970 testScope.runTest { 971 // Use the [StateFlow.value] getter so we can prove that the collection happens 972 // even when there is no [Job] 973 974 // Starts out default 975 assertThat(underTest.networkName.value).isEqualTo(DEFAULT_NAME_MODEL) 976 977 val intent = spnIntent() 978 val captor = argumentCaptor<BroadcastReceiver>() 979 verify(context).registerReceiver(captor.capture(), any()) 980 captor.lastValue.onReceive(context, intent) 981 982 // The value is still there despite no active subscribers 983 assertThat(underTest.networkName.value) 984 .isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 985 } 986 987 @Test 988 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_allFieldsSet_prioritizesDataSpnOverSpnnull989 fun networkName_allFieldsSet_prioritizesDataSpnOverSpn() = 990 testScope.runTest { 991 val latest by collectLastValue(underTest.networkName) 992 val captor = argumentCaptor<BroadcastReceiver>() 993 verify(context).registerReceiver(captor.capture(), any()) 994 995 val intent = 996 spnIntent( 997 subId = SUB_1_ID, 998 showSpn = true, 999 spn = SPN, 1000 dataSpn = DATA_SPN, 1001 showPlmn = true, 1002 plmn = PLMN, 1003 ) 1004 captor.lastValue.onReceive(context, intent) 1005 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 1006 } 1007 1008 @Test 1009 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_spnAndPlmn_fallbackToSpnWhenNullDataSpnnull1010 fun networkName_spnAndPlmn_fallbackToSpnWhenNullDataSpn() = 1011 testScope.runTest { 1012 val latest by collectLastValue(underTest.networkName) 1013 val captor = argumentCaptor<BroadcastReceiver>() 1014 verify(context).registerReceiver(captor.capture(), any()) 1015 1016 val intent = 1017 spnIntent( 1018 subId = SUB_1_ID, 1019 showSpn = true, 1020 spn = SPN, 1021 dataSpn = null, 1022 showPlmn = true, 1023 plmn = PLMN, 1024 ) 1025 captor.lastValue.onReceive(context, intent) 1026 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN")) 1027 } 1028 1029 @Test 1030 @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_allFieldsSet_flagOffnull1031 fun networkName_allFieldsSet_flagOff() = 1032 testScope.runTest { 1033 val latest by collectLastValue(underTest.networkName) 1034 val captor = argumentCaptor<BroadcastReceiver>() 1035 verify(context).registerReceiver(captor.capture(), any()) 1036 1037 val intent = 1038 spnIntent( 1039 subId = SUB_1_ID, 1040 showSpn = true, 1041 spn = SPN, 1042 dataSpn = DATA_SPN, 1043 showPlmn = true, 1044 plmn = PLMN, 1045 ) 1046 captor.lastValue.onReceive(context, intent) 1047 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 1048 } 1049 1050 @Test 1051 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNullnull1052 fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull() = 1053 testScope.runTest { 1054 val latest by collectLastValue(underTest.networkName) 1055 val captor = argumentCaptor<BroadcastReceiver>() 1056 verify(context).registerReceiver(captor.capture(), any()) 1057 val intent = 1058 spnIntent( 1059 subId = SUB_1_ID, 1060 showSpn = true, 1061 spn = null, 1062 dataSpn = DATA_SPN, 1063 showPlmn = true, 1064 plmn = PLMN, 1065 ) 1066 captor.lastValue.onReceive(context, intent) 1067 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 1068 } 1069 1070 @Test 1071 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_showPlmn_plmnNotNull_showSpn_spnNotNull_dataSpnNullnull1072 fun networkName_showPlmn_plmnNotNull_showSpn_spnNotNull_dataSpnNull() = 1073 testScope.runTest { 1074 val latest by collectLastValue(underTest.networkName) 1075 val captor = argumentCaptor<BroadcastReceiver>() 1076 verify(context).registerReceiver(captor.capture(), any()) 1077 val intent = 1078 spnIntent( 1079 subId = SUB_1_ID, 1080 showSpn = true, 1081 spn = SPN, 1082 dataSpn = null, 1083 showPlmn = true, 1084 plmn = PLMN, 1085 ) 1086 captor.lastValue.onReceive(context, intent) 1087 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$SPN")) 1088 } 1089 1090 @Test 1091 @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull_flagOffnull1092 fun networkName_showPlmn_plmnNotNull_showSpn_spnNull_dataSpnNotNull_flagOff() = 1093 testScope.runTest { 1094 val latest by collectLastValue(underTest.networkName) 1095 val captor = argumentCaptor<BroadcastReceiver>() 1096 verify(context).registerReceiver(captor.capture(), any()) 1097 val intent = 1098 spnIntent( 1099 subId = SUB_1_ID, 1100 showSpn = true, 1101 spn = null, 1102 dataSpn = DATA_SPN, 1103 showPlmn = true, 1104 plmn = PLMN, 1105 ) 1106 captor.lastValue.onReceive(context, intent) 1107 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN$SEP$DATA_SPN")) 1108 } 1109 1110 @Test networkName_showPlmn_noShowSPNnull1111 fun networkName_showPlmn_noShowSPN() = 1112 testScope.runTest { 1113 val latest by collectLastValue(underTest.networkName) 1114 val captor = argumentCaptor<BroadcastReceiver>() 1115 verify(context).registerReceiver(captor.capture(), any()) 1116 val intent = 1117 spnIntent( 1118 subId = SUB_1_ID, 1119 showSpn = false, 1120 spn = SPN, 1121 dataSpn = DATA_SPN, 1122 showPlmn = true, 1123 plmn = PLMN, 1124 ) 1125 captor.lastValue.onReceive(context, intent) 1126 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$PLMN")) 1127 } 1128 1129 @Test 1130 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_showPlmn_plmnNull_showSpnnull1131 fun networkName_showPlmn_plmnNull_showSpn() = 1132 testScope.runTest { 1133 val latest by collectLastValue(underTest.networkName) 1134 val captor = argumentCaptor<BroadcastReceiver>() 1135 verify(context).registerReceiver(captor.capture(), any()) 1136 val intent = 1137 spnIntent( 1138 subId = SUB_1_ID, 1139 showSpn = true, 1140 spn = SPN, 1141 dataSpn = DATA_SPN, 1142 showPlmn = true, 1143 plmn = null, 1144 ) 1145 captor.lastValue.onReceive(context, intent) 1146 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$DATA_SPN")) 1147 } 1148 1149 @Test 1150 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_showPlmn_plmnNull_showSpn_dataSpnNullnull1151 fun networkName_showPlmn_plmnNull_showSpn_dataSpnNull() = 1152 testScope.runTest { 1153 val latest by collectLastValue(underTest.networkName) 1154 val captor = argumentCaptor<BroadcastReceiver>() 1155 verify(context).registerReceiver(captor.capture(), any()) 1156 val intent = 1157 spnIntent( 1158 subId = SUB_1_ID, 1159 showSpn = true, 1160 spn = SPN, 1161 dataSpn = null, 1162 showPlmn = true, 1163 plmn = null, 1164 ) 1165 captor.lastValue.onReceive(context, intent) 1166 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$SPN")) 1167 } 1168 1169 @Test 1170 @EnableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_showPlmn_plmnNull_showSpn_bothSpnNullnull1171 fun networkName_showPlmn_plmnNull_showSpn_bothSpnNull() = 1172 testScope.runTest { 1173 val latest by collectLastValue(underTest.networkName) 1174 val captor = argumentCaptor<BroadcastReceiver>() 1175 verify(context).registerReceiver(captor.capture(), any()) 1176 val intent = 1177 spnIntent( 1178 subId = SUB_1_ID, 1179 showSpn = true, 1180 spn = null, 1181 dataSpn = null, 1182 showPlmn = true, 1183 plmn = null, 1184 ) 1185 captor.lastValue.onReceive(context, intent) 1186 assertThat(latest).isEqualTo(DEFAULT_NAME_MODEL) 1187 } 1188 1189 @Test 1190 @DisableFlags(Flags.FLAG_STATUS_BAR_SWITCH_TO_SPN_FROM_DATA_SPN) networkName_showPlmn_plmnNull_showSpn_flagOffnull1191 fun networkName_showPlmn_plmnNull_showSpn_flagOff() = 1192 testScope.runTest { 1193 val latest by collectLastValue(underTest.networkName) 1194 val captor = argumentCaptor<BroadcastReceiver>() 1195 verify(context).registerReceiver(captor.capture(), any()) 1196 val intent = 1197 spnIntent( 1198 subId = SUB_1_ID, 1199 showSpn = true, 1200 spn = SPN, 1201 dataSpn = DATA_SPN, 1202 showPlmn = true, 1203 plmn = null, 1204 ) 1205 captor.lastValue.onReceive(context, intent) 1206 assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived("$DATA_SPN")) 1207 } 1208 1209 @Test operatorAlphaShort_trackednull1210 fun operatorAlphaShort_tracked() = 1211 testScope.runTest { 1212 var latest: String? = null 1213 1214 val job = underTest.operatorAlphaShort.onEach { latest = it }.launchIn(this) 1215 1216 val shortName = "short name" 1217 val serviceState = ServiceState() 1218 serviceState.setOperatorName( 1219 /* longName */ "long name", 1220 /* shortName */ shortName, 1221 /* numeric */ "12345", 1222 ) 1223 1224 getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState) 1225 1226 assertThat(latest).isEqualTo(shortName) 1227 1228 job.cancel() 1229 } 1230 1231 @Test isInService_notIwlannull1232 fun isInService_notIwlan() = 1233 testScope.runTest { 1234 var latest: Boolean? = null 1235 val job = underTest.isInService.onEach { latest = it }.launchIn(this) 1236 1237 val nriInService = 1238 NetworkRegistrationInfo.Builder() 1239 .setDomain(DOMAIN_PS) 1240 .setTransportType(TRANSPORT_TYPE_WWAN) 1241 .setRegistrationState(REGISTRATION_STATE_HOME) 1242 .build() 1243 1244 getTelephonyCallbackForType<ServiceStateListener>() 1245 .onServiceStateChanged( 1246 ServiceState().also { 1247 it.voiceRegState = STATE_IN_SERVICE 1248 it.addNetworkRegistrationInfo(nriInService) 1249 } 1250 ) 1251 1252 assertThat(latest).isTrue() 1253 1254 getTelephonyCallbackForType<ServiceStateListener>() 1255 .onServiceStateChanged( 1256 ServiceState().also { 1257 it.voiceRegState = STATE_OUT_OF_SERVICE 1258 it.addNetworkRegistrationInfo(nriInService) 1259 } 1260 ) 1261 assertThat(latest).isTrue() 1262 1263 val nriNotInService = 1264 NetworkRegistrationInfo.Builder() 1265 .setDomain(DOMAIN_PS) 1266 .setTransportType(TRANSPORT_TYPE_WWAN) 1267 .setRegistrationState(REGISTRATION_STATE_DENIED) 1268 .build() 1269 getTelephonyCallbackForType<ServiceStateListener>() 1270 .onServiceStateChanged( 1271 ServiceState().also { 1272 it.voiceRegState = STATE_OUT_OF_SERVICE 1273 it.addNetworkRegistrationInfo(nriNotInService) 1274 } 1275 ) 1276 assertThat(latest).isFalse() 1277 1278 job.cancel() 1279 } 1280 1281 @Test isInService_isIwlan_voiceOutOfService_dataInServicenull1282 fun isInService_isIwlan_voiceOutOfService_dataInService() = 1283 testScope.runTest { 1284 var latest: Boolean? = null 1285 val job = underTest.isInService.onEach { latest = it }.launchIn(this) 1286 1287 val iwlanData = 1288 NetworkRegistrationInfo.Builder() 1289 .setDomain(DOMAIN_PS) 1290 .setTransportType(TRANSPORT_TYPE_WLAN) 1291 .setRegistrationState(REGISTRATION_STATE_HOME) 1292 .build() 1293 val serviceState = 1294 ServiceState().also { 1295 it.voiceRegState = STATE_OUT_OF_SERVICE 1296 it.addNetworkRegistrationInfo(iwlanData) 1297 } 1298 1299 getTelephonyCallbackForType<ServiceStateListener>().onServiceStateChanged(serviceState) 1300 assertThat(latest).isFalse() 1301 1302 job.cancel() 1303 } 1304 1305 @Test 1306 @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) isNonTerrestrial_updatesFromCallback0null1307 fun isNonTerrestrial_updatesFromCallback0() = 1308 testScope.runTest { 1309 val latest by collectLastValue(underTest.isNonTerrestrial) 1310 1311 // Starts out false 1312 assertThat(latest).isFalse() 1313 1314 val callback = getTelephonyCallbackForType<CarrierRoamingNtnModeListener>() 1315 1316 callback.onCarrierRoamingNtnModeChanged(true) 1317 assertThat(latest).isTrue() 1318 1319 callback.onCarrierRoamingNtnModeChanged(false) 1320 assertThat(latest).isFalse() 1321 } 1322 1323 @Test numberOfLevels_usesCarrierConfignull1324 fun numberOfLevels_usesCarrierConfig() = 1325 testScope.runTest { 1326 var latest: Int? = null 1327 val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this) 1328 1329 assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS) 1330 1331 systemUiCarrierConfig.processNewCarrierConfig( 1332 configWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true) 1333 ) 1334 1335 assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS + 1) 1336 1337 systemUiCarrierConfig.processNewCarrierConfig( 1338 configWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false) 1339 ) 1340 1341 assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS) 1342 1343 job.cancel() 1344 } 1345 1346 @Test inflateSignalStrength_usesCarrierConfignull1347 fun inflateSignalStrength_usesCarrierConfig() = 1348 testScope.runTest { 1349 val latest by collectLastValue(underTest.inflateSignalStrength) 1350 1351 assertThat(latest).isEqualTo(false) 1352 1353 systemUiCarrierConfig.processNewCarrierConfig( 1354 configWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true) 1355 ) 1356 1357 assertThat(latest).isEqualTo(true) 1358 1359 systemUiCarrierConfig.processNewCarrierConfig( 1360 configWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false) 1361 ) 1362 1363 assertThat(latest).isEqualTo(false) 1364 } 1365 1366 @Test allowNetworkSliceIndicator_exposesCarrierConfigValuenull1367 fun allowNetworkSliceIndicator_exposesCarrierConfigValue() = 1368 testScope.runTest { 1369 val latest by collectLastValue(underTest.allowNetworkSliceIndicator) 1370 1371 systemUiCarrierConfig.processNewCarrierConfig( 1372 configWithOverride(KEY_SHOW_5G_SLICE_ICON_BOOL, true) 1373 ) 1374 1375 assertThat(latest).isTrue() 1376 1377 systemUiCarrierConfig.processNewCarrierConfig( 1378 configWithOverride(KEY_SHOW_5G_SLICE_ICON_BOOL, false) 1379 ) 1380 1381 assertThat(latest).isFalse() 1382 } 1383 1384 @Test isAllowedDuringAirplaneMode_alwaysFalsenull1385 fun isAllowedDuringAirplaneMode_alwaysFalse() = 1386 testScope.runTest { 1387 val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode) 1388 1389 assertThat(latest).isFalse() 1390 } 1391 1392 @Test hasPrioritizedCaps_defaultFalsenull1393 fun hasPrioritizedCaps_defaultFalse() { 1394 assertThat(underTest.hasPrioritizedNetworkCapabilities.value).isFalse() 1395 } 1396 1397 @Test hasPrioritizedCaps_trueWhenAvailablenull1398 fun hasPrioritizedCaps_trueWhenAvailable() = 1399 testScope.runTest { 1400 val latest by collectLastValue(underTest.hasPrioritizedNetworkCapabilities) 1401 1402 val callback: NetworkCallback = 1403 withArgCaptor<NetworkCallback> { 1404 verify(connectivityManager).registerNetworkCallback(any(), capture()) 1405 } 1406 1407 callback.onAvailable(mock()) 1408 1409 assertThat(latest).isTrue() 1410 } 1411 1412 @Test hasPrioritizedCaps_becomesFalseWhenNetworkLostnull1413 fun hasPrioritizedCaps_becomesFalseWhenNetworkLost() = 1414 testScope.runTest { 1415 val latest by collectLastValue(underTest.hasPrioritizedNetworkCapabilities) 1416 1417 val callback: NetworkCallback = 1418 withArgCaptor<NetworkCallback> { 1419 verify(connectivityManager).registerNetworkCallback(any(), capture()) 1420 } 1421 1422 callback.onAvailable(mock()) 1423 1424 assertThat(latest).isTrue() 1425 1426 callback.onLost(mock()) 1427 1428 assertThat(latest).isFalse() 1429 } 1430 getTelephonyCallbackForTypenull1431 private inline fun <reified T> getTelephonyCallbackForType(): T { 1432 return MobileTelephonyHelpers.getTelephonyCallbackForType(telephonyManager) 1433 } 1434 carrierIdIntentnull1435 private fun carrierIdIntent( 1436 subId: Int = SUB_1_ID, 1437 carrierId: Int, 1438 ): Intent = 1439 Intent(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED).apply { 1440 putExtra(EXTRA_SUBSCRIPTION_ID, subId) 1441 putExtra(EXTRA_CARRIER_ID, carrierId) 1442 } 1443 spnIntentnull1444 private fun spnIntent( 1445 subId: Int = SUB_1_ID, 1446 showSpn: Boolean = true, 1447 spn: String? = SPN, 1448 dataSpn: String? = DATA_SPN, 1449 showPlmn: Boolean = true, 1450 plmn: String? = PLMN, 1451 ): Intent = 1452 Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED).apply { 1453 putExtra(EXTRA_SUBSCRIPTION_INDEX, subId) 1454 putExtra(EXTRA_SHOW_SPN, showSpn) 1455 putExtra(EXTRA_SPN, spn) 1456 putExtra(EXTRA_DATA_SPN, dataSpn) 1457 putExtra(EXTRA_SHOW_PLMN, showPlmn) 1458 putExtra(EXTRA_PLMN, plmn) 1459 } 1460 1461 companion object { 1462 private const val SUB_1_ID = 1 1463 1464 private const val DEFAULT_NAME = "Fake Mobile Network" 1465 private val DEFAULT_NAME_MODEL = NetworkNameModel.Default(DEFAULT_NAME) 1466 private const val SEP = "-" 1467 1468 private const val SPN = "testSpn" 1469 private const val DATA_SPN = "testDataSpn" 1470 private const val PLMN = "testPlmn" 1471 } 1472 } 1473