1 /* 2 * Copyright (C) 2023 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.net.ConnectivityManager 20 import android.os.PersistableBundle 21 import android.telephony.ServiceState 22 import android.telephony.SignalStrength 23 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET 24 import android.telephony.TelephonyCallback 25 import android.telephony.TelephonyManager 26 import androidx.test.ext.junit.runners.AndroidJUnit4 27 import androidx.test.filters.SmallTest 28 import com.android.systemui.SysuiTestCase 29 import com.android.systemui.coroutines.collectLastValue 30 import com.android.systemui.flags.FakeFeatureFlagsClassic 31 import com.android.systemui.flags.Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO 32 import com.android.systemui.log.table.logcatTableLogBuffer 33 import com.android.systemui.log.table.tableLogBufferFactory 34 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel 35 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel 36 import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig 37 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository 38 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository 39 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_EMERGENCY 40 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_OPERATOR 41 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_PRIMARY_LEVEL 42 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.getTelephonyCallbackForType 43 import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository 44 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel 45 import com.android.systemui.testKosmos 46 import com.android.systemui.util.mockito.any 47 import com.android.systemui.util.mockito.eq 48 import com.android.systemui.util.mockito.mock 49 import com.android.systemui.util.mockito.whenever 50 import com.google.common.truth.Truth.assertThat 51 import java.io.PrintWriter 52 import java.io.StringWriter 53 import kotlinx.coroutines.ExperimentalCoroutinesApi 54 import kotlinx.coroutines.flow.MutableStateFlow 55 import kotlinx.coroutines.flow.launchIn 56 import kotlinx.coroutines.flow.onEach 57 import kotlinx.coroutines.test.TestScope 58 import kotlinx.coroutines.test.UnconfinedTestDispatcher 59 import kotlinx.coroutines.test.runTest 60 import org.junit.Before 61 import org.junit.Test 62 import org.junit.runner.RunWith 63 import org.mockito.Mockito.never 64 import org.mockito.Mockito.verify 65 66 /** 67 * This repo acts as a dispatcher to either the `typical` or `carrier merged` versions of the 68 * repository interface it's switching on. These tests just need to verify that the entire interface 69 * properly switches over when the value of `isCarrierMerged` changes. 70 */ 71 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") 72 @OptIn(ExperimentalCoroutinesApi::class) 73 @SmallTest 74 @RunWith(AndroidJUnit4::class) 75 class FullMobileConnectionRepositoryTest : SysuiTestCase() { 76 private val kosmos = testKosmos() 77 78 private lateinit var underTest: FullMobileConnectionRepository 79 80 private val flags = <lambda>null81 FakeFeatureFlagsClassic().also { it.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) } 82 83 private val testDispatcher = UnconfinedTestDispatcher() 84 private val testScope = TestScope(testDispatcher) 85 private val tableLogBuffer = logcatTableLogBuffer(kosmos, "TestName") 86 private val mobileFactory = mock<MobileConnectionRepositoryImpl.Factory>() 87 private val carrierMergedFactory = mock<CarrierMergedConnectionRepository.Factory>() 88 private val connectivityManager = mock<ConnectivityManager>() 89 90 private val subscriptionModel = 91 MutableStateFlow( 92 SubscriptionModel( 93 subscriptionId = SUB_ID, 94 carrierName = DEFAULT_NAME, 95 profileClass = PROFILE_CLASS_UNSET, 96 ) 97 ) 98 99 // Use a real config, with no overrides 100 private val systemUiCarrierConfig = SystemUiCarrierConfig(SUB_ID, PersistableBundle()) 101 102 private lateinit var mobileRepo: FakeMobileConnectionRepository 103 private lateinit var carrierMergedRepo: FakeMobileConnectionRepository 104 105 @Before setUpnull106 fun setUp() { 107 mobileRepo = 108 FakeMobileConnectionRepository( 109 SUB_ID, 110 tableLogBuffer, 111 ) 112 carrierMergedRepo = 113 FakeMobileConnectionRepository( 114 SUB_ID, 115 tableLogBuffer, 116 ) 117 .apply { 118 // Mimicks the real carrier merged repository 119 this.isAllowedDuringAirplaneMode.value = true 120 } 121 122 whenever( 123 mobileFactory.build( 124 eq(SUB_ID), 125 any(), 126 any(), 127 eq(DEFAULT_NAME_MODEL), 128 eq(SEP), 129 ) 130 ) 131 .thenReturn(mobileRepo) 132 whenever( 133 carrierMergedFactory.build( 134 eq(SUB_ID), 135 any(), 136 ) 137 ) 138 .thenReturn(carrierMergedRepo) 139 } 140 141 @Test startingIsCarrierMerged_usesCarrierMergedInitiallynull142 fun startingIsCarrierMerged_usesCarrierMergedInitially() = 143 testScope.runTest { 144 val carrierMergedOperatorName = "Carrier Merged Operator" 145 val nonCarrierMergedName = "Non-carrier-merged" 146 147 carrierMergedRepo.operatorAlphaShort.value = carrierMergedOperatorName 148 mobileRepo.operatorAlphaShort.value = nonCarrierMergedName 149 150 initializeRepo(startingIsCarrierMerged = true) 151 152 assertThat(underTest.activeRepo.value).isEqualTo(carrierMergedRepo) 153 assertThat(underTest.operatorAlphaShort.value).isEqualTo(carrierMergedOperatorName) 154 verify(mobileFactory, never()) 155 .build( 156 SUB_ID, 157 tableLogBuffer, 158 subscriptionModel, 159 DEFAULT_NAME_MODEL, 160 SEP, 161 ) 162 } 163 164 @Test startingNotCarrierMerged_usesTypicalInitiallynull165 fun startingNotCarrierMerged_usesTypicalInitially() = 166 testScope.runTest { 167 val carrierMergedOperatorName = "Carrier Merged Operator" 168 val nonCarrierMergedName = "Typical Operator" 169 170 carrierMergedRepo.operatorAlphaShort.value = carrierMergedOperatorName 171 mobileRepo.operatorAlphaShort.value = nonCarrierMergedName 172 173 initializeRepo(startingIsCarrierMerged = false) 174 175 assertThat(underTest.activeRepo.value).isEqualTo(mobileRepo) 176 assertThat(underTest.operatorAlphaShort.value).isEqualTo(nonCarrierMergedName) 177 verify(carrierMergedFactory, never()) 178 .build( 179 SUB_ID, 180 tableLogBuffer, 181 ) 182 } 183 184 @Test activeRepo_matchesIsCarrierMergednull185 fun activeRepo_matchesIsCarrierMerged() = 186 testScope.runTest { 187 initializeRepo(startingIsCarrierMerged = false) 188 var latest: MobileConnectionRepository? = null 189 val job = underTest.activeRepo.onEach { latest = it }.launchIn(this) 190 191 underTest.setIsCarrierMerged(true) 192 193 assertThat(latest).isEqualTo(carrierMergedRepo) 194 195 underTest.setIsCarrierMerged(false) 196 197 assertThat(latest).isEqualTo(mobileRepo) 198 199 underTest.setIsCarrierMerged(true) 200 201 assertThat(latest).isEqualTo(carrierMergedRepo) 202 203 job.cancel() 204 } 205 206 @Test connectionInfo_getsUpdatesFromRepo_carrierMergednull207 fun connectionInfo_getsUpdatesFromRepo_carrierMerged() = 208 testScope.runTest { 209 initializeRepo(startingIsCarrierMerged = false) 210 211 var latestName: String? = null 212 var latestLevel: Int? = null 213 214 val nameJob = underTest.operatorAlphaShort.onEach { latestName = it }.launchIn(this) 215 val levelJob = underTest.primaryLevel.onEach { latestLevel = it }.launchIn(this) 216 217 underTest.setIsCarrierMerged(true) 218 219 val operator1 = "Carrier Merged Operator" 220 val level1 = 1 221 carrierMergedRepo.operatorAlphaShort.value = operator1 222 carrierMergedRepo.primaryLevel.value = level1 223 224 assertThat(latestName).isEqualTo(operator1) 225 assertThat(latestLevel).isEqualTo(level1) 226 227 val operator2 = "Carrier Merged Operator #2" 228 val level2 = 2 229 carrierMergedRepo.operatorAlphaShort.value = operator2 230 carrierMergedRepo.primaryLevel.value = level2 231 232 assertThat(latestName).isEqualTo(operator2) 233 assertThat(latestLevel).isEqualTo(level2) 234 235 val operator3 = "Carrier Merged Operator #3" 236 val level3 = 3 237 carrierMergedRepo.operatorAlphaShort.value = operator3 238 carrierMergedRepo.primaryLevel.value = level3 239 240 assertThat(latestName).isEqualTo(operator3) 241 assertThat(latestLevel).isEqualTo(level3) 242 243 nameJob.cancel() 244 levelJob.cancel() 245 } 246 247 @Test connectionInfo_getsUpdatesFromRepo_mobilenull248 fun connectionInfo_getsUpdatesFromRepo_mobile() = 249 testScope.runTest { 250 initializeRepo(startingIsCarrierMerged = false) 251 252 var latestName: String? = null 253 var latestLevel: Int? = null 254 255 val nameJob = underTest.operatorAlphaShort.onEach { latestName = it }.launchIn(this) 256 val levelJob = underTest.primaryLevel.onEach { latestLevel = it }.launchIn(this) 257 258 underTest.setIsCarrierMerged(false) 259 260 val operator1 = "Typical Merged Operator" 261 val level1 = 1 262 mobileRepo.operatorAlphaShort.value = operator1 263 mobileRepo.primaryLevel.value = level1 264 265 assertThat(latestName).isEqualTo(operator1) 266 assertThat(latestLevel).isEqualTo(level1) 267 268 val operator2 = "Typical Merged Operator #2" 269 val level2 = 2 270 mobileRepo.operatorAlphaShort.value = operator2 271 mobileRepo.primaryLevel.value = level2 272 273 assertThat(latestName).isEqualTo(operator2) 274 assertThat(latestLevel).isEqualTo(level2) 275 276 val operator3 = "Typical Merged Operator #3" 277 val level3 = 3 278 mobileRepo.operatorAlphaShort.value = operator3 279 mobileRepo.primaryLevel.value = level3 280 281 assertThat(latestName).isEqualTo(operator3) 282 assertThat(latestLevel).isEqualTo(level3) 283 284 nameJob.cancel() 285 levelJob.cancel() 286 } 287 288 @Test connectionInfo_updatesWhenCarrierMergedUpdatesnull289 fun connectionInfo_updatesWhenCarrierMergedUpdates() = 290 testScope.runTest { 291 initializeRepo(startingIsCarrierMerged = false) 292 293 var latestName: String? = null 294 var latestLevel: Int? = null 295 296 val nameJob = underTest.operatorAlphaShort.onEach { latestName = it }.launchIn(this) 297 val levelJob = underTest.primaryLevel.onEach { latestLevel = it }.launchIn(this) 298 299 val carrierMergedOperator = "Carrier Merged Operator" 300 val carrierMergedLevel = 4 301 carrierMergedRepo.operatorAlphaShort.value = carrierMergedOperator 302 carrierMergedRepo.primaryLevel.value = carrierMergedLevel 303 304 val mobileName = "Typical Operator" 305 val mobileLevel = 2 306 mobileRepo.operatorAlphaShort.value = mobileName 307 mobileRepo.primaryLevel.value = mobileLevel 308 309 // Start with the mobile info 310 assertThat(latestName).isEqualTo(mobileName) 311 assertThat(latestLevel).isEqualTo(mobileLevel) 312 313 // WHEN isCarrierMerged is set to true 314 underTest.setIsCarrierMerged(true) 315 316 // THEN the carrier merged info is used 317 assertThat(latestName).isEqualTo(carrierMergedOperator) 318 assertThat(latestLevel).isEqualTo(carrierMergedLevel) 319 320 val newCarrierMergedName = "New CM Operator" 321 val newCarrierMergedLevel = 0 322 carrierMergedRepo.operatorAlphaShort.value = newCarrierMergedName 323 carrierMergedRepo.primaryLevel.value = newCarrierMergedLevel 324 325 assertThat(latestName).isEqualTo(newCarrierMergedName) 326 assertThat(latestLevel).isEqualTo(newCarrierMergedLevel) 327 328 // WHEN isCarrierMerged is set to false 329 underTest.setIsCarrierMerged(false) 330 331 // THEN the typical info is used 332 assertThat(latestName).isEqualTo(mobileName) 333 assertThat(latestLevel).isEqualTo(mobileLevel) 334 335 val newMobileName = "New MobileOperator" 336 val newMobileLevel = 3 337 mobileRepo.operatorAlphaShort.value = newMobileName 338 mobileRepo.primaryLevel.value = newMobileLevel 339 340 assertThat(latestName).isEqualTo(newMobileName) 341 assertThat(latestLevel).isEqualTo(newMobileLevel) 342 343 nameJob.cancel() 344 levelJob.cancel() 345 } 346 347 @Test isAllowedDuringAirplaneMode_updatesWhenCarrierMergedUpdatesnull348 fun isAllowedDuringAirplaneMode_updatesWhenCarrierMergedUpdates() = 349 testScope.runTest { 350 initializeRepo(startingIsCarrierMerged = false) 351 352 val latest by collectLastValue(underTest.isAllowedDuringAirplaneMode) 353 354 assertThat(latest).isFalse() 355 356 underTest.setIsCarrierMerged(true) 357 358 assertThat(latest).isTrue() 359 360 underTest.setIsCarrierMerged(false) 361 362 assertThat(latest).isFalse() 363 } 364 365 @Test factory_reusesLogBuffersForSameConnectionnull366 fun factory_reusesLogBuffersForSameConnection() = 367 testScope.runTest { 368 val factory = 369 FullMobileConnectionRepository.Factory( 370 scope = testScope.backgroundScope, 371 kosmos.tableLogBufferFactory, 372 mobileFactory, 373 carrierMergedFactory, 374 ) 375 376 // Create two connections for the same subId. Similar to if the connection appeared 377 // and disappeared from the connectionFactory's perspective 378 val connection1 = 379 factory.build( 380 SUB_ID, 381 startingIsCarrierMerged = false, 382 subscriptionModel, 383 DEFAULT_NAME_MODEL, 384 SEP, 385 ) 386 387 val connection1Repeat = 388 factory.build( 389 SUB_ID, 390 startingIsCarrierMerged = false, 391 subscriptionModel, 392 DEFAULT_NAME_MODEL, 393 SEP, 394 ) 395 396 assertThat(connection1.tableLogBuffer) 397 .isSameInstanceAs(connection1Repeat.tableLogBuffer) 398 } 399 400 @Test factory_reusesLogBuffersForSameSubIDevenIfCarrierMergednull401 fun factory_reusesLogBuffersForSameSubIDevenIfCarrierMerged() = 402 testScope.runTest { 403 val factory = 404 FullMobileConnectionRepository.Factory( 405 scope = testScope.backgroundScope, 406 kosmos.tableLogBufferFactory, 407 mobileFactory, 408 carrierMergedFactory, 409 ) 410 411 val connection1 = 412 factory.build( 413 SUB_ID, 414 startingIsCarrierMerged = false, 415 subscriptionModel, 416 DEFAULT_NAME_MODEL, 417 SEP, 418 ) 419 420 // WHEN a connection with the same sub ID but carrierMerged = true is created 421 val connection1Repeat = 422 factory.build( 423 SUB_ID, 424 startingIsCarrierMerged = true, 425 subscriptionModel, 426 DEFAULT_NAME_MODEL, 427 SEP, 428 ) 429 430 // THEN the same table is re-used 431 assertThat(connection1.tableLogBuffer) 432 .isSameInstanceAs(connection1Repeat.tableLogBuffer) 433 } 434 435 @Test connectionInfo_logging_notCarrierMerged_getsUpdatesnull436 fun connectionInfo_logging_notCarrierMerged_getsUpdates() = 437 testScope.runTest { 438 // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) 439 val telephonyManager = 440 mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") } 441 createRealMobileRepo(telephonyManager) 442 createRealCarrierMergedRepo(telephonyManager, FakeWifiRepository()) 443 444 initializeRepo(startingIsCarrierMerged = false) 445 446 val emergencyJob = underTest.isEmergencyOnly.launchIn(this) 447 val operatorJob = underTest.operatorAlphaShort.launchIn(this) 448 449 // WHEN we set up some mobile connection info 450 val serviceState = ServiceState() 451 serviceState.setOperatorName("longName", "OpTypical", "1") 452 serviceState.isEmergencyOnly = true 453 getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager) 454 .onServiceStateChanged(serviceState) 455 456 // THEN it's logged to the buffer 457 assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpTypical") 458 assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}true") 459 460 // WHEN we update mobile connection info 461 val serviceState2 = ServiceState() 462 serviceState2.setOperatorName("longName", "OpDiff", "1") 463 serviceState2.isEmergencyOnly = false 464 getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager) 465 .onServiceStateChanged(serviceState2) 466 467 // THEN the updates are logged 468 assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpDiff") 469 assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}false") 470 471 emergencyJob.cancel() 472 operatorJob.cancel() 473 } 474 475 @Test connectionInfo_logging_carrierMerged_getsUpdatesnull476 fun connectionInfo_logging_carrierMerged_getsUpdates() = 477 testScope.runTest { 478 // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) 479 val telephonyManager = 480 mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") } 481 createRealMobileRepo(telephonyManager) 482 val wifiRepository = FakeWifiRepository() 483 createRealCarrierMergedRepo(telephonyManager, wifiRepository) 484 485 initializeRepo(startingIsCarrierMerged = true) 486 487 val job = underTest.primaryLevel.launchIn(this) 488 489 // WHEN we set up carrier merged info 490 wifiRepository.setWifiNetwork( 491 WifiNetworkModel.CarrierMerged.of( 492 SUB_ID, 493 level = 3, 494 ) 495 ) 496 497 // THEN the carrier merged info is logged 498 assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3") 499 500 // WHEN we update the info 501 wifiRepository.setWifiNetwork( 502 WifiNetworkModel.CarrierMerged.of( 503 SUB_ID, 504 level = 1, 505 ) 506 ) 507 508 // THEN the updates are logged 509 assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1") 510 511 job.cancel() 512 } 513 514 @Test connectionInfo_logging_updatesWhenCarrierMergedUpdatesnull515 fun connectionInfo_logging_updatesWhenCarrierMergedUpdates() = 516 testScope.runTest { 517 // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) 518 val telephonyManager = 519 mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") } 520 createRealMobileRepo(telephonyManager) 521 522 val wifiRepository = FakeWifiRepository() 523 createRealCarrierMergedRepo(telephonyManager, wifiRepository) 524 525 initializeRepo(startingIsCarrierMerged = false) 526 527 val job = underTest.primaryLevel.launchIn(this) 528 529 // WHEN we set up some mobile connection info 530 val signalStrength = mock<SignalStrength>() 531 whenever(signalStrength.level).thenReturn(1) 532 533 getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager) 534 .onSignalStrengthsChanged(signalStrength) 535 536 // THEN it's logged to the buffer 537 assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1") 538 539 // WHEN isCarrierMerged is set to true 540 wifiRepository.setWifiNetwork( 541 WifiNetworkModel.CarrierMerged.of( 542 SUB_ID, 543 level = 3, 544 ) 545 ) 546 underTest.setIsCarrierMerged(true) 547 548 // THEN the carrier merged info is logged 549 assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3") 550 551 // WHEN the carrier merge network is updated 552 wifiRepository.setWifiNetwork( 553 WifiNetworkModel.CarrierMerged.of( 554 SUB_ID, 555 level = 4, 556 ) 557 ) 558 559 // THEN the new level is logged 560 assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4") 561 562 // WHEN isCarrierMerged is set to false 563 underTest.setIsCarrierMerged(false) 564 565 // THEN the typical info is logged 566 // Note: Since our first logs also had the typical info, we need to search the log 567 // contents for after our carrier merged level log. 568 val fullBuffer = dumpBuffer() 569 val carrierMergedContentIndex = fullBuffer.indexOf("${BUFFER_SEPARATOR}4") 570 val bufferAfterCarrierMerged = fullBuffer.substring(carrierMergedContentIndex) 571 assertThat(bufferAfterCarrierMerged).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1") 572 573 // WHEN the normal network is updated 574 mobileRepo.primaryLevel.value = 0 575 576 // THEN the new level is logged 577 assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}0") 578 579 job.cancel() 580 } 581 582 @Test connectionInfo_logging_doesNotLogUpdatesForNotActiveReponull583 fun connectionInfo_logging_doesNotLogUpdatesForNotActiveRepo() = 584 testScope.runTest { 585 // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.) 586 val telephonyManager = 587 mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") } 588 createRealMobileRepo(telephonyManager) 589 590 val wifiRepository = FakeWifiRepository() 591 createRealCarrierMergedRepo(telephonyManager, wifiRepository) 592 593 // WHEN isCarrierMerged = false 594 initializeRepo(startingIsCarrierMerged = false) 595 596 val job = underTest.primaryLevel.launchIn(this) 597 598 val signalStrength = mock<SignalStrength>() 599 whenever(signalStrength.level).thenReturn(1) 600 getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager) 601 .onSignalStrengthsChanged(signalStrength) 602 603 // THEN updates to the carrier merged level aren't logged 604 wifiRepository.setWifiNetwork( 605 WifiNetworkModel.CarrierMerged.of( 606 SUB_ID, 607 level = 4, 608 ) 609 ) 610 assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4") 611 612 wifiRepository.setWifiNetwork( 613 WifiNetworkModel.CarrierMerged.of( 614 SUB_ID, 615 level = 3, 616 ) 617 ) 618 assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3") 619 620 // WHEN isCarrierMerged is set to true 621 underTest.setIsCarrierMerged(true) 622 623 // THEN updates to the normal level aren't logged 624 whenever(signalStrength.level).thenReturn(5) 625 getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager) 626 .onSignalStrengthsChanged(signalStrength) 627 assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}5") 628 629 whenever(signalStrength.level).thenReturn(6) 630 getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager) 631 .onSignalStrengthsChanged(signalStrength) 632 assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}6") 633 634 job.cancel() 635 } 636 initializeReponull637 private fun initializeRepo(startingIsCarrierMerged: Boolean) { 638 underTest = 639 FullMobileConnectionRepository( 640 SUB_ID, 641 startingIsCarrierMerged, 642 tableLogBuffer, 643 subscriptionModel, 644 DEFAULT_NAME_MODEL, 645 SEP, 646 testScope.backgroundScope, 647 mobileFactory, 648 carrierMergedFactory, 649 ) 650 } 651 createRealMobileReponull652 private fun createRealMobileRepo( 653 telephonyManager: TelephonyManager, 654 ): MobileConnectionRepositoryImpl { 655 whenever(telephonyManager.subscriptionId).thenReturn(SUB_ID) 656 val realRepo = 657 MobileConnectionRepositoryImpl( 658 SUB_ID, 659 context, 660 subscriptionModel, 661 DEFAULT_NAME_MODEL, 662 SEP, 663 connectivityManager, 664 telephonyManager, 665 systemUiCarrierConfig = systemUiCarrierConfig, 666 fakeBroadcastDispatcher, 667 mobileMappingsProxy = mock(), 668 testDispatcher, 669 logger = mock(), 670 tableLogBuffer, 671 flags, 672 testScope.backgroundScope, 673 ) 674 whenever( 675 mobileFactory.build( 676 eq(SUB_ID), 677 any(), 678 any(), 679 eq(DEFAULT_NAME_MODEL), 680 eq(SEP), 681 ) 682 ) 683 .thenReturn(realRepo) 684 685 return realRepo 686 } 687 createRealCarrierMergedReponull688 private fun createRealCarrierMergedRepo( 689 telephonyManager: TelephonyManager, 690 wifiRepository: FakeWifiRepository, 691 ): CarrierMergedConnectionRepository { 692 wifiRepository.setIsWifiEnabled(true) 693 wifiRepository.setIsWifiDefault(true) 694 val realRepo = 695 CarrierMergedConnectionRepository( 696 SUB_ID, 697 tableLogBuffer, 698 telephonyManager, 699 testScope.backgroundScope.coroutineContext, 700 testScope.backgroundScope, 701 wifiRepository, 702 ) 703 whenever( 704 carrierMergedFactory.build( 705 eq(SUB_ID), 706 any(), 707 ) 708 ) 709 .thenReturn(realRepo) 710 711 return realRepo 712 } 713 dumpBuffernull714 private fun dumpBuffer(): String { 715 val outputWriter = StringWriter() 716 tableLogBuffer.dump(PrintWriter(outputWriter), arrayOf()) 717 return outputWriter.toString() 718 } 719 720 private companion object { 721 const val SUB_ID = 42 722 private const val DEFAULT_NAME = "default name" 723 private val DEFAULT_NAME_MODEL = NetworkNameModel.Default(DEFAULT_NAME) 724 private const val SEP = "-" 725 private const val BUFFER_SEPARATOR = "|" 726 } 727 } 728