1 /* 2 * Copyright (C) 2021 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.phone; 18 19 import static android.telephony.ims.ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED; 20 import static android.telephony.ims.ImsStateCallback.REASON_IMS_SERVICE_NOT_READY; 21 import static android.telephony.ims.ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED; 22 import static android.telephony.ims.ImsStateCallback.REASON_SUBSCRIPTION_INACTIVE; 23 import static android.telephony.ims.feature.ImsFeature.FEATURE_MMTEL; 24 import static android.telephony.ims.feature.ImsFeature.FEATURE_RCS; 25 26 import static com.android.ims.FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED; 27 import static com.android.ims.FeatureConnector.UNAVAILABLE_REASON_IMS_UNSUPPORTED; 28 import static com.android.ims.FeatureConnector.UNAVAILABLE_REASON_NOT_READY; 29 30 import static junit.framework.Assert.assertFalse; 31 import static junit.framework.Assert.assertNotNull; 32 import static junit.framework.Assert.assertNull; 33 import static junit.framework.Assert.assertTrue; 34 35 import static org.mockito.Matchers.any; 36 import static org.mockito.Matchers.anyInt; 37 import static org.mockito.Matchers.eq; 38 import static org.mockito.Mockito.atLeastOnce; 39 import static org.mockito.Mockito.doAnswer; 40 import static org.mockito.Mockito.times; 41 import static org.mockito.Mockito.verify; 42 import static org.mockito.Mockito.when; 43 44 import android.content.Context; 45 import android.os.Handler; 46 import android.os.HandlerThread; 47 import android.os.IBinder; 48 import android.os.Looper; 49 import android.telephony.SubscriptionManager; 50 import android.telephony.TelephonyRegistryManager; 51 import android.testing.TestableLooper; 52 import android.util.Log; 53 54 import androidx.test.filters.SmallTest; 55 56 import com.android.TelephonyTestBase; 57 import com.android.ims.FeatureConnector; 58 import com.android.ims.ImsManager; 59 import com.android.ims.RcsFeatureManager; 60 import com.android.internal.telephony.IImsStateCallback; 61 import com.android.internal.telephony.ITelephony; 62 import com.android.internal.telephony.Phone; 63 import com.android.internal.telephony.ims.ImsResolver; 64 65 import org.junit.After; 66 import org.junit.Before; 67 import org.junit.Test; 68 import org.mockito.ArgumentCaptor; 69 import org.mockito.Captor; 70 import org.mockito.Mock; 71 import org.mockito.MockitoAnnotations; 72 import org.mockito.invocation.InvocationOnMock; 73 import org.mockito.stubbing.Answer; 74 75 import java.util.concurrent.Executor; 76 77 /** 78 * Unit tests for RcsProvisioningMonitor 79 */ 80 public class ImsStateCallbackControllerTest extends TelephonyTestBase { 81 private static final String TAG = "ImsStateCallbackControllerTest"; 82 private static final int FAKE_SUB_ID_BASE = 0x0FFFFFF0; 83 84 private static final int SLOT_0 = 0; 85 private static final int SLOT_1 = 1; 86 87 private static final int SLOT_0_SUB_ID = 1; 88 private static final int SLOT_1_SUB_ID = 2; 89 private static final int SLOT_2_SUB_ID = 3; 90 91 private ImsStateCallbackController mImsStateCallbackController; 92 private Handler mHandler; 93 private HandlerThread mHandlerThread; 94 private TestableLooper mLooper; 95 @Mock private SubscriptionManager mSubscriptionManager; 96 private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener; 97 @Mock private TelephonyRegistryManager mTelephonyRegistryManager; 98 @Mock private ITelephony.Stub mITelephony; 99 @Mock private RcsFeatureManager mRcsFeatureManager; 100 @Mock private ImsManager mMmTelFeatureManager; 101 @Mock private ImsStateCallbackController.MmTelFeatureConnectorFactory mMmTelFeatureFactory; 102 @Mock private ImsStateCallbackController.RcsFeatureConnectorFactory mRcsFeatureFactory; 103 @Mock private FeatureConnector<ImsManager> mMmTelFeatureConnectorSlot0; 104 @Mock private FeatureConnector<ImsManager> mMmTelFeatureConnectorSlot1; 105 @Mock private FeatureConnector<RcsFeatureManager> mRcsFeatureConnectorSlot0; 106 @Mock private FeatureConnector<RcsFeatureManager> mRcsFeatureConnectorSlot1; 107 @Captor ArgumentCaptor<FeatureConnector.Listener<ImsManager>> mMmTelConnectorListenerSlot0; 108 @Captor ArgumentCaptor<FeatureConnector.Listener<ImsManager>> mMmTelConnectorListenerSlot1; 109 @Captor ArgumentCaptor<FeatureConnector.Listener<RcsFeatureManager>> mRcsConnectorListenerSlot0; 110 @Captor ArgumentCaptor<FeatureConnector.Listener<RcsFeatureManager>> mRcsConnectorListenerSlot1; 111 @Mock private PhoneGlobals mPhone; 112 @Mock ImsStateCallbackController.PhoneFactoryProxy mPhoneFactoryProxy; 113 @Mock Phone mPhoneSlot0; 114 @Mock Phone mPhoneSlot1; 115 @Mock private IBinder mBinder0; 116 @Mock private IBinder mBinder1; 117 @Mock private IBinder mBinder2; 118 @Mock private IBinder mBinder3; 119 @Mock private IImsStateCallback mCallback0; 120 @Mock private IImsStateCallback mCallback1; 121 @Mock private IImsStateCallback mCallback2; 122 @Mock private IImsStateCallback mCallback3; 123 @Mock private ImsResolver mImsResolver; 124 125 private Executor mExecutor = new Executor() { 126 @Override 127 public void execute(Runnable r) { 128 r.run(); 129 } 130 }; 131 132 @Before setUp()133 public void setUp() throws Exception { 134 MockitoAnnotations.initMocks(this); 135 136 when(mPhone.getMainExecutor()).thenReturn(mExecutor); 137 when(mPhone.getSystemServiceName(eq(SubscriptionManager.class))) 138 .thenReturn(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 139 when(mPhone.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE))) 140 .thenReturn(mSubscriptionManager); 141 when(mPhone.getSystemServiceName(eq(TelephonyRegistryManager.class))) 142 .thenReturn(Context.TELEPHONY_REGISTRY_SERVICE); 143 when(mPhone.getSystemService(eq(Context.TELEPHONY_REGISTRY_SERVICE))) 144 .thenReturn(mTelephonyRegistryManager); 145 when(mPhoneFactoryProxy.getPhone(eq(0))).thenReturn(mPhoneSlot0); 146 when(mPhoneFactoryProxy.getPhone(eq(1))).thenReturn(mPhoneSlot1); 147 when(mPhoneSlot0.getSubId()).thenReturn(SLOT_0_SUB_ID); 148 when(mPhoneSlot1.getSubId()).thenReturn(SLOT_1_SUB_ID); 149 150 when(mCallback0.asBinder()).thenReturn(mBinder0); 151 when(mCallback1.asBinder()).thenReturn(mBinder1); 152 when(mCallback2.asBinder()).thenReturn(mBinder2); 153 when(mCallback3.asBinder()).thenReturn(mBinder3); 154 155 // slot 0 156 when(mImsResolver.isImsServiceConfiguredForFeature(eq(0), eq(FEATURE_MMTEL))) 157 .thenReturn(true); 158 when(mImsResolver.isImsServiceConfiguredForFeature(eq(0), eq(FEATURE_RCS))) 159 .thenReturn(true); 160 161 // slot 1 162 when(mImsResolver.isImsServiceConfiguredForFeature(eq(1), eq(FEATURE_MMTEL))) 163 .thenReturn(true); 164 when(mImsResolver.isImsServiceConfiguredForFeature(eq(1), eq(FEATURE_RCS))) 165 .thenReturn(true); 166 167 doAnswer(new Answer<Void>() { 168 @Override 169 public Void answer(InvocationOnMock invocation) throws Throwable { 170 mSubChangedListener = (SubscriptionManager.OnSubscriptionsChangedListener) 171 invocation.getArguments()[0]; 172 return null; 173 } 174 }).when(mTelephonyRegistryManager).addOnSubscriptionsChangedListener( 175 any(SubscriptionManager.OnSubscriptionsChangedListener.class), 176 any()); 177 178 mHandlerThread = new HandlerThread("ImsStateCallbackControllerTest"); 179 mHandlerThread.start(); 180 } 181 182 @After tearDown()183 public void tearDown() throws Exception { 184 if (mImsStateCallbackController != null) { 185 mImsStateCallbackController.destroy(); 186 mImsStateCallbackController = null; 187 } 188 189 if (mLooper != null) { 190 mLooper.destroy(); 191 mLooper = null; 192 } 193 super.tearDown(); 194 } 195 196 @Test 197 @SmallTest testMmTelRegisterThenUnregisterCallback()198 public void testMmTelRegisterThenUnregisterCallback() throws Exception { 199 createController(1); 200 201 mImsStateCallbackController 202 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_MMTEL, mCallback0, "callback0"); 203 processAllMessages(); 204 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 205 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 206 207 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 208 processAllMessages(); 209 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 210 } 211 212 @Test 213 @SmallTest testMmTelConnectionUnavailable()214 public void testMmTelConnectionUnavailable() throws Exception { 215 createController(1); 216 217 mImsStateCallbackController 218 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_MMTEL, mCallback0, "callback0"); 219 processAllMessages(); 220 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 221 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 222 223 mMmTelConnectorListenerSlot0.getValue() 224 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 225 processAllMessages(); 226 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 227 228 mMmTelConnectorListenerSlot0.getValue() 229 .connectionUnavailable(UNAVAILABLE_REASON_IMS_UNSUPPORTED); 230 processAllMessages(); 231 verify(mCallback0, times(1)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 232 233 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 234 processAllMessages(); 235 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 236 } 237 238 @Test 239 @SmallTest testMmTelConnectionReady()240 public void testMmTelConnectionReady() throws Exception { 241 createController(1); 242 243 mImsStateCallbackController 244 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_MMTEL, mCallback0, "callback0"); 245 processAllMessages(); 246 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 247 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 248 verify(mCallback0, times(0)).onAvailable(); 249 250 mMmTelConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID); 251 processAllMessages(); 252 verify(mCallback0, atLeastOnce()).onAvailable(); 253 254 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 255 processAllMessages(); 256 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 257 } 258 259 @Test 260 @SmallTest testMmTelIgnoreDuplicatedConsecutiveReason()261 public void testMmTelIgnoreDuplicatedConsecutiveReason() throws Exception { 262 createController(1); 263 264 mImsStateCallbackController 265 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_MMTEL, mCallback0, "callback0"); 266 processAllMessages(); 267 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 268 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 269 270 mMmTelConnectorListenerSlot0.getValue() 271 .connectionUnavailable(UNAVAILABLE_REASON_IMS_UNSUPPORTED); 272 processAllMessages(); 273 verify(mCallback0, times(1)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 274 275 mMmTelConnectorListenerSlot0.getValue() 276 .connectionUnavailable(UNAVAILABLE_REASON_IMS_UNSUPPORTED); 277 processAllMessages(); 278 verify(mCallback0, times(1)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 279 280 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 281 processAllMessages(); 282 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 283 } 284 285 @Test 286 @SmallTest testRcsRegisterThenUnregisterCallback()287 public void testRcsRegisterThenUnregisterCallback() throws Exception { 288 createController(1); 289 290 mImsStateCallbackController 291 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_RCS, mCallback0, "callback0"); 292 processAllMessages(); 293 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 294 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 295 296 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 297 processAllMessages(); 298 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 299 } 300 301 @Test 302 @SmallTest testRcsConnectionUnavailable()303 public void testRcsConnectionUnavailable() throws Exception { 304 createController(1); 305 306 mImsStateCallbackController 307 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_RCS, mCallback0, "callback0"); 308 processAllMessages(); 309 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 310 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 311 312 // TelephonyRcsService notifying active features 313 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, false, true); 314 processAllMessages(); 315 316 mRcsConnectorListenerSlot0.getValue() 317 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 318 processAllMessages(); 319 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 320 321 mRcsConnectorListenerSlot0.getValue() 322 .connectionUnavailable(UNAVAILABLE_REASON_IMS_UNSUPPORTED); 323 processAllMessages(); 324 verify(mCallback0, times(1)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 325 326 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 327 processAllMessages(); 328 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 329 } 330 331 @Test 332 @SmallTest testRcsConnectionReady()333 public void testRcsConnectionReady() throws Exception { 334 createController(1); 335 336 mImsStateCallbackController 337 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_RCS, mCallback0, "callback0"); 338 processAllMessages(); 339 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 340 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 341 342 // TelephonyRcsService notifying active features 343 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, false, true); 344 processAllMessages(); 345 346 mRcsConnectorListenerSlot0.getValue() 347 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 348 processAllMessages(); 349 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 350 351 mRcsConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID); 352 processAllMessages(); 353 verify(mCallback0, times(0)).onAvailable(); 354 355 // RcsFeatureController notifying STATE_READY 356 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, true, true); 357 processAllMessages(); 358 verify(mCallback0, times(1)).onAvailable(); 359 360 mRcsConnectorListenerSlot0.getValue() 361 .connectionUnavailable(UNAVAILABLE_REASON_DISCONNECTED); 362 processAllMessages(); 363 verify(mCallback0, times(2)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 364 365 mRcsConnectorListenerSlot0.getValue() 366 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 367 processAllMessages(); 368 verify(mCallback0, times(2)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 369 370 // RcsFeatureController notifying STATE_READY 371 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, true, true); 372 processAllMessages(); 373 verify(mCallback0, times(1)).onAvailable(); 374 375 mRcsConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID); 376 processAllMessages(); 377 verify(mCallback0, times(2)).onAvailable(); 378 379 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 380 processAllMessages(); 381 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 382 } 383 384 @Test 385 @SmallTest testRcsHasNoActiveFeature()386 public void testRcsHasNoActiveFeature() throws Exception { 387 createController(1); 388 389 mImsStateCallbackController 390 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_RCS, mCallback0, "callback0"); 391 processAllMessages(); 392 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 393 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 394 395 // TelephonyRcsService notifying NO active feature 396 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, false, false); 397 processAllMessages(); 398 verify(mCallback0, times(1)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 399 400 mRcsConnectorListenerSlot0.getValue() 401 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 402 processAllMessages(); 403 verify(mCallback0, times(0)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 404 405 mRcsConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID); 406 processAllMessages(); 407 verify(mCallback0, times(0)).onAvailable(); 408 409 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 410 processAllMessages(); 411 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 412 } 413 414 @Test 415 @SmallTest testRcsIgnoreDuplicatedConsecutiveReason()416 public void testRcsIgnoreDuplicatedConsecutiveReason() throws Exception { 417 createController(1); 418 419 mImsStateCallbackController 420 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_RCS, mCallback0, "callback0"); 421 processAllMessages(); 422 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 423 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 424 425 // TelephonyRcsService notifying active features 426 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, false, true); 427 processAllMessages(); 428 429 mRcsConnectorListenerSlot0.getValue() 430 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 431 processAllMessages(); 432 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 433 434 mRcsConnectorListenerSlot0.getValue() 435 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 436 processAllMessages(); 437 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 438 439 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 440 processAllMessages(); 441 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 442 } 443 444 @Test 445 @SmallTest testCallbackRemovedWhenSubInfoChanged()446 public void testCallbackRemovedWhenSubInfoChanged() throws Exception { 447 createController(2); 448 449 mImsStateCallbackController 450 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_MMTEL, mCallback0, "callback0"); 451 mImsStateCallbackController 452 .registerImsStateCallback(SLOT_1_SUB_ID, FEATURE_RCS, mCallback1, "callback1"); 453 processAllMessages(); 454 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 455 assertTrue(mImsStateCallbackController.isRegistered(mCallback1)); 456 457 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 458 verify(mCallback1, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 459 460 makeFakeActiveSubIds(0); 461 mExecutor.execute(() -> mSubChangedListener.onSubscriptionsChanged()); 462 processAllMessages(); 463 464 verify(mCallback0, times(1)).onUnavailable(REASON_SUBSCRIPTION_INACTIVE); 465 verify(mCallback1, times(1)).onUnavailable(REASON_SUBSCRIPTION_INACTIVE); 466 467 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 468 assertFalse(mImsStateCallbackController.isRegistered(mCallback1)); 469 } 470 471 @Test 472 @SmallTest testCarrierConfigurationChanged()473 public void testCarrierConfigurationChanged() throws Exception { 474 createController(2); 475 476 when(mImsResolver.isImsServiceConfiguredForFeature(eq(1), eq(FEATURE_MMTEL))) 477 .thenReturn(false); 478 479 mImsStateCallbackController 480 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_MMTEL, mCallback0, "callback0"); 481 mImsStateCallbackController 482 .registerImsStateCallback(SLOT_1_SUB_ID, FEATURE_MMTEL, mCallback1, "callback1"); 483 mImsStateCallbackController 484 .registerImsStateCallback(SLOT_1_SUB_ID, FEATURE_RCS, mCallback2, "callback2"); 485 processAllMessages(); 486 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 487 assertTrue(mImsStateCallbackController.isRegistered(mCallback1)); 488 assertTrue(mImsStateCallbackController.isRegistered(mCallback2)); 489 490 // check initial reason 491 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 492 verify(mCallback1, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 493 verify(mCallback2, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 494 495 verify(mCallback0, times(0)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 496 verify(mCallback1, times(0)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 497 verify(mCallback2, times(0)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 498 499 // ensure only one reason reported until now 500 verify(mCallback0, times(1)).onUnavailable(anyInt()); 501 verify(mCallback1, times(1)).onUnavailable(anyInt()); 502 verify(mCallback2, times(1)).onUnavailable(anyInt()); 503 504 // state change in RCS for slot 0 505 mRcsConnectorListenerSlot0.getValue() 506 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 507 508 // ensure there is no change, since callbacks are not interested RCS on slot 0 509 verify(mCallback0, times(1)).onUnavailable(anyInt()); 510 verify(mCallback1, times(1)).onUnavailable(anyInt()); 511 verify(mCallback2, times(1)).onUnavailable(anyInt()); 512 513 // carrier config changed, no MMTEL package for slot 1 514 mImsStateCallbackController.notifyCarrierConfigChanged(SLOT_1); 515 processAllMessages(); 516 517 // only the callback for MMTEL of slot 1 received the reason 518 verify(mCallback0, times(0)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 519 verify(mCallback1, times(1)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 520 verify(mCallback2, times(0)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 521 522 // ensure no other callbacks 523 verify(mCallback0, times(1)).onUnavailable(anyInt()); 524 verify(mCallback1, times(2)).onUnavailable(anyInt()); 525 verify(mCallback2, times(1)).onUnavailable(anyInt()); 526 527 mMmTelConnectorListenerSlot1.getValue() 528 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 529 mMmTelConnectorListenerSlot1.getValue() 530 .connectionUnavailable(UNAVAILABLE_REASON_DISCONNECTED); 531 532 // resons except REASON_NO_IMS_SERVICE_CONFIGURED are discared 533 verify(mCallback0, times(1)).onUnavailable(anyInt()); 534 verify(mCallback1, times(2)).onUnavailable(anyInt()); 535 verify(mCallback2, times(1)).onUnavailable(anyInt()); 536 537 // IMS package for MMTEL of slot 1 is added 538 when(mImsResolver.isImsServiceConfiguredForFeature(eq(1), eq(FEATURE_MMTEL))) 539 .thenReturn(true); 540 mImsStateCallbackController.notifyCarrierConfigChanged(SLOT_1); 541 processAllMessages(); 542 543 // ensure the callback to MMTEL of slot 1 only received REASON_IMS_SERVICE_DISCONNECTED 544 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 545 verify(mCallback1, times(2)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 546 verify(mCallback2, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 547 548 // ensure no other reason repored 549 verify(mCallback0, times(1)).onUnavailable(anyInt()); 550 verify(mCallback1, times(3)).onUnavailable(anyInt()); 551 verify(mCallback2, times(1)).onUnavailable(anyInt()); 552 553 // carrier config changed, no MMTEL package for slot 1 554 when(mImsResolver.isImsServiceConfiguredForFeature(eq(1), eq(FEATURE_MMTEL))) 555 .thenReturn(false); 556 mImsStateCallbackController.notifyCarrierConfigChanged(SLOT_1); 557 mImsStateCallbackController.notifyCarrierConfigChanged(SLOT_1); 558 processAllMessages(); 559 // only the callback for MMTEL of slot 1 received the reason 560 verify(mCallback0, times(0)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 561 verify(mCallback1, times(2)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 562 verify(mCallback2, times(0)).onUnavailable(REASON_NO_IMS_SERVICE_CONFIGURED); 563 564 // ensure no other reason repored 565 verify(mCallback0, times(1)).onUnavailable(anyInt()); 566 verify(mCallback1, times(4)).onUnavailable(anyInt()); 567 verify(mCallback2, times(1)).onUnavailable(anyInt()); 568 569 mMmTelConnectorListenerSlot1.getValue() 570 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 571 572 // resons except REASON_NO_IMS_SERVICE_CONFIGURED are discared 573 verify(mCallback0, times(1)).onUnavailable(anyInt()); 574 verify(mCallback1, times(4)).onUnavailable(anyInt()); 575 verify(mCallback2, times(1)).onUnavailable(anyInt()); 576 577 // IMS package for MMTEL of slot 1 is added 578 when(mImsResolver.isImsServiceConfiguredForFeature(eq(1), eq(FEATURE_MMTEL))) 579 .thenReturn(true); 580 mImsStateCallbackController.notifyCarrierConfigChanged(SLOT_1); 581 processAllMessages(); 582 583 // ensure the callback to MMTEL of slot 1 584 // there is a pending reason UNAVAILABLE_REASON_NOT_READY 585 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 586 verify(mCallback1, times(2)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 587 verify(mCallback1, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 588 verify(mCallback2, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 589 590 // ensure no other reason repored 591 verify(mCallback0, times(1)).onUnavailable(anyInt()); 592 verify(mCallback1, times(5)).onUnavailable(anyInt()); 593 verify(mCallback2, times(1)).onUnavailable(anyInt()); 594 595 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 596 assertTrue(mImsStateCallbackController.isRegistered(mCallback1)); 597 assertTrue(mImsStateCallbackController.isRegistered(mCallback2)); 598 599 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 600 mImsStateCallbackController.unregisterImsStateCallback(mCallback1); 601 mImsStateCallbackController.unregisterImsStateCallback(mCallback2); 602 processAllMessages(); 603 604 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 605 assertFalse(mImsStateCallbackController.isRegistered(mCallback1)); 606 assertFalse(mImsStateCallbackController.isRegistered(mCallback2)); 607 } 608 609 @Test 610 @SmallTest testMultiSubscriptions()611 public void testMultiSubscriptions() throws Exception { 612 createController(2); 613 614 // registration 615 mImsStateCallbackController 616 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_MMTEL, mCallback0, "callback0"); 617 mImsStateCallbackController 618 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_RCS, mCallback1, "callback1"); 619 mImsStateCallbackController 620 .registerImsStateCallback(SLOT_1_SUB_ID, FEATURE_MMTEL, mCallback2, "callback2"); 621 mImsStateCallbackController 622 .registerImsStateCallback(SLOT_1_SUB_ID, FEATURE_RCS, mCallback3, "callback3"); 623 processAllMessages(); 624 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 625 assertTrue(mImsStateCallbackController.isRegistered(mCallback1)); 626 assertTrue(mImsStateCallbackController.isRegistered(mCallback2)); 627 assertTrue(mImsStateCallbackController.isRegistered(mCallback3)); 628 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 629 verify(mCallback1, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 630 verify(mCallback2, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 631 verify(mCallback3, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 632 633 // TelephonyRcsService notifying active features 634 // slot 0 635 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, false, true); 636 // slot 1 637 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_1, false, true); 638 processAllMessages(); 639 640 verify(mCallback0, times(1)).onUnavailable(anyInt()); 641 verify(mCallback1, times(1)).onUnavailable(anyInt()); 642 verify(mCallback2, times(1)).onUnavailable(anyInt()); 643 verify(mCallback3, times(1)).onUnavailable(anyInt()); 644 645 verify(mCallback0, times(0)).onAvailable(); 646 verify(mCallback1, times(0)).onAvailable(); 647 verify(mCallback2, times(0)).onAvailable(); 648 verify(mCallback3, times(0)).onAvailable(); 649 650 // connectionUnavailable 651 mMmTelConnectorListenerSlot0.getValue() 652 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 653 processAllMessages(); 654 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 655 verify(mCallback0, times(2)).onUnavailable(anyInt()); 656 verify(mCallback1, times(1)).onUnavailable(anyInt()); 657 verify(mCallback1, times(1)).onUnavailable(anyInt()); 658 verify(mCallback2, times(1)).onUnavailable(anyInt()); 659 verify(mCallback2, times(1)).onUnavailable(anyInt()); 660 verify(mCallback3, times(1)).onUnavailable(anyInt()); 661 verify(mCallback3, times(1)).onUnavailable(anyInt()); 662 663 mRcsConnectorListenerSlot0.getValue() 664 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 665 processAllMessages(); 666 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 667 verify(mCallback0, times(2)).onUnavailable(anyInt()); 668 verify(mCallback1, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 669 verify(mCallback1, times(2)).onUnavailable(anyInt()); 670 verify(mCallback2, times(1)).onUnavailable(anyInt()); 671 verify(mCallback2, times(1)).onUnavailable(anyInt()); 672 verify(mCallback3, times(1)).onUnavailable(anyInt()); 673 verify(mCallback3, times(1)).onUnavailable(anyInt()); 674 675 mMmTelConnectorListenerSlot1.getValue() 676 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 677 processAllMessages(); 678 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 679 verify(mCallback0, times(2)).onUnavailable(anyInt()); 680 verify(mCallback1, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 681 verify(mCallback1, times(2)).onUnavailable(anyInt()); 682 verify(mCallback2, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 683 verify(mCallback2, times(2)).onUnavailable(anyInt()); 684 verify(mCallback3, times(1)).onUnavailable(anyInt()); 685 verify(mCallback3, times(1)).onUnavailable(anyInt()); 686 687 mRcsConnectorListenerSlot1.getValue() 688 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 689 processAllMessages(); 690 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 691 verify(mCallback0, times(2)).onUnavailable(anyInt()); 692 verify(mCallback1, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 693 verify(mCallback1, times(2)).onUnavailable(anyInt()); 694 verify(mCallback2, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 695 verify(mCallback2, times(2)).onUnavailable(anyInt()); 696 verify(mCallback3, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY); 697 verify(mCallback3, times(2)).onUnavailable(anyInt()); 698 699 // connectionReady 700 mMmTelConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID); 701 processAllMessages(); 702 verify(mCallback0, times(1)).onAvailable(); 703 verify(mCallback1, times(0)).onAvailable(); 704 verify(mCallback2, times(0)).onAvailable(); 705 verify(mCallback3, times(0)).onAvailable(); 706 verify(mCallback0, times(2)).onUnavailable(anyInt()); 707 verify(mCallback1, times(2)).onUnavailable(anyInt()); 708 verify(mCallback2, times(2)).onUnavailable(anyInt()); 709 verify(mCallback3, times(2)).onUnavailable(anyInt()); 710 711 mRcsConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID); 712 processAllMessages(); 713 verify(mCallback0, times(1)).onAvailable(); 714 verify(mCallback1, times(0)).onAvailable(); 715 verify(mCallback2, times(0)).onAvailable(); 716 verify(mCallback3, times(0)).onAvailable(); 717 verify(mCallback0, times(2)).onUnavailable(anyInt()); 718 verify(mCallback1, times(2)).onUnavailable(anyInt()); 719 verify(mCallback2, times(2)).onUnavailable(anyInt()); 720 verify(mCallback3, times(2)).onUnavailable(anyInt()); 721 722 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, true, true); 723 processAllMessages(); 724 verify(mCallback0, times(1)).onAvailable(); 725 verify(mCallback1, times(1)).onAvailable(); 726 verify(mCallback2, times(0)).onAvailable(); 727 verify(mCallback3, times(0)).onAvailable(); 728 verify(mCallback0, times(2)).onUnavailable(anyInt()); 729 verify(mCallback1, times(2)).onUnavailable(anyInt()); 730 verify(mCallback2, times(2)).onUnavailable(anyInt()); 731 verify(mCallback3, times(2)).onUnavailable(anyInt()); 732 733 mMmTelConnectorListenerSlot1.getValue().connectionReady(null, SLOT_1_SUB_ID); 734 processAllMessages(); 735 verify(mCallback0, times(1)).onAvailable(); 736 verify(mCallback1, times(1)).onAvailable(); 737 verify(mCallback2, times(1)).onAvailable(); 738 verify(mCallback3, times(0)).onAvailable(); 739 verify(mCallback0, times(2)).onUnavailable(anyInt()); 740 verify(mCallback1, times(2)).onUnavailable(anyInt()); 741 verify(mCallback2, times(2)).onUnavailable(anyInt()); 742 verify(mCallback3, times(2)).onUnavailable(anyInt()); 743 744 mRcsConnectorListenerSlot1.getValue().connectionReady(null, SLOT_1_SUB_ID); 745 processAllMessages(); 746 verify(mCallback0, times(1)).onAvailable(); 747 verify(mCallback1, times(1)).onAvailable(); 748 verify(mCallback2, times(1)).onAvailable(); 749 verify(mCallback3, times(0)).onAvailable(); 750 verify(mCallback0, times(2)).onUnavailable(anyInt()); 751 verify(mCallback1, times(2)).onUnavailable(anyInt()); 752 verify(mCallback2, times(2)).onUnavailable(anyInt()); 753 verify(mCallback3, times(2)).onUnavailable(anyInt()); 754 755 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_1, true, true); 756 processAllMessages(); 757 verify(mCallback0, times(1)).onAvailable(); 758 verify(mCallback1, times(1)).onAvailable(); 759 verify(mCallback2, times(1)).onAvailable(); 760 verify(mCallback3, times(1)).onAvailable(); 761 verify(mCallback0, times(2)).onUnavailable(anyInt()); 762 verify(mCallback1, times(2)).onUnavailable(anyInt()); 763 verify(mCallback2, times(2)).onUnavailable(anyInt()); 764 verify(mCallback3, times(2)).onUnavailable(anyInt()); 765 766 // unregistration 767 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 768 processAllMessages(); 769 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 770 assertTrue(mImsStateCallbackController.isRegistered(mCallback1)); 771 assertTrue(mImsStateCallbackController.isRegistered(mCallback2)); 772 assertTrue(mImsStateCallbackController.isRegistered(mCallback3)); 773 774 mImsStateCallbackController.unregisterImsStateCallback(mCallback1); 775 processAllMessages(); 776 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 777 assertFalse(mImsStateCallbackController.isRegistered(mCallback1)); 778 assertTrue(mImsStateCallbackController.isRegistered(mCallback2)); 779 assertTrue(mImsStateCallbackController.isRegistered(mCallback3)); 780 781 mImsStateCallbackController.unregisterImsStateCallback(mCallback2); 782 processAllMessages(); 783 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 784 assertFalse(mImsStateCallbackController.isRegistered(mCallback1)); 785 assertFalse(mImsStateCallbackController.isRegistered(mCallback2)); 786 assertTrue(mImsStateCallbackController.isRegistered(mCallback3)); 787 788 mImsStateCallbackController.unregisterImsStateCallback(mCallback3); 789 processAllMessages(); 790 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 791 assertFalse(mImsStateCallbackController.isRegistered(mCallback1)); 792 assertFalse(mImsStateCallbackController.isRegistered(mCallback2)); 793 assertFalse(mImsStateCallbackController.isRegistered(mCallback3)); 794 } 795 796 @Test 797 @SmallTest testSlotUpdates()798 public void testSlotUpdates() throws Exception { 799 createController(1); 800 801 verify(mMmTelFeatureConnectorSlot0, times(1)).connect(); 802 verify(mRcsFeatureConnectorSlot0, times(1)).connect(); 803 verify(mMmTelFeatureConnectorSlot0, times(0)).disconnect(); 804 verify(mRcsFeatureConnectorSlot0, times(0)).disconnect(); 805 806 // Add a new slot. 807 mImsStateCallbackController.updateFeatureControllerSize(2); 808 809 // connect in slot 1 810 verify(mMmTelFeatureConnectorSlot1, times(1)).connect(); 811 verify(mRcsFeatureConnectorSlot1, times(1)).connect(); 812 813 // no change in slot 0 814 verify(mMmTelFeatureConnectorSlot0, times(1)).connect(); 815 verify(mRcsFeatureConnectorSlot0, times(1)).connect(); 816 817 // Remove a slot. 818 mImsStateCallbackController.updateFeatureControllerSize(1); 819 820 // destroy in slot 1 821 verify(mMmTelFeatureConnectorSlot1, times(1)).disconnect(); 822 verify(mRcsFeatureConnectorSlot1, times(1)).disconnect(); 823 824 // no change in slot 0 825 verify(mMmTelFeatureConnectorSlot0, times(0)).disconnect(); 826 verify(mRcsFeatureConnectorSlot0, times(0)).disconnect(); 827 } 828 829 @Test 830 @SmallTest testMmTelConnectionReadyWhenReEnableSim()831 public void testMmTelConnectionReadyWhenReEnableSim() throws Exception { 832 createController(1); 833 834 // MMTEL feature 835 mMmTelConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID); 836 processAllMessages(); 837 mMmTelConnectorListenerSlot0.getValue() 838 .connectionUnavailable(UNAVAILABLE_REASON_DISCONNECTED); 839 processAllMessages(); 840 mMmTelConnectorListenerSlot0.getValue().connectionReady(null, 841 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 842 processAllMessages(); 843 mImsStateCallbackController 844 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_MMTEL, mCallback0, "callback0"); 845 processAllMessages(); 846 847 assertTrue(mImsStateCallbackController.isRegistered(mCallback0)); 848 verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 849 verify(mCallback0, times(0)).onAvailable(); 850 851 mImsStateCallbackController.unregisterImsStateCallback(mCallback0); 852 processAllMessages(); 853 assertFalse(mImsStateCallbackController.isRegistered(mCallback0)); 854 855 // RCS feature 856 // TelephonyRcsService notifying active features 857 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, false, true); 858 processAllMessages(); 859 // RcsFeatureController notifying STATE_READY 860 mImsStateCallbackController.notifyExternalRcsStateChanged(SLOT_0, true, true); 861 processAllMessages(); 862 mRcsConnectorListenerSlot0.getValue() 863 .connectionUnavailable(UNAVAILABLE_REASON_DISCONNECTED); 864 processAllMessages(); 865 mRcsConnectorListenerSlot0.getValue().connectionReady(null, 866 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 867 processAllMessages(); 868 mImsStateCallbackController 869 .registerImsStateCallback(SLOT_0_SUB_ID, FEATURE_RCS, mCallback1, "callback1"); 870 processAllMessages(); 871 872 assertTrue(mImsStateCallbackController.isRegistered(mCallback1)); 873 verify(mCallback1, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED); 874 verify(mCallback1, times(0)).onAvailable(); 875 876 mImsStateCallbackController.unregisterImsStateCallback(mCallback1); 877 processAllMessages(); 878 assertFalse(mImsStateCallbackController.isRegistered(mCallback1)); 879 } 880 881 @Test 882 @SmallTest testImsManagerInstance()883 public void testImsManagerInstance() throws Exception { 884 createController(1); 885 886 // MmTelConnection not ready 887 // check ImsManager instance 888 ImsManager imsManager = mImsStateCallbackController.getImsManager(SLOT_0_SUB_ID); 889 assertNull(imsManager); 890 891 // MmTelConnection ready 892 mMmTelConnectorListenerSlot0.getValue() 893 .connectionReady(mMmTelFeatureManager, SLOT_0_SUB_ID); 894 processAllMessages(); 895 896 // check ImsManager instance 897 imsManager = mImsStateCallbackController.getImsManager(SLOT_0_SUB_ID); 898 assertNotNull(imsManager); 899 900 // MmTelConnection unavailable 901 mMmTelConnectorListenerSlot0.getValue() 902 .connectionUnavailable(UNAVAILABLE_REASON_NOT_READY); 903 processAllMessages(); 904 905 // MmTelConnection unavailable 906 // check ImsManager instance 907 imsManager = mImsStateCallbackController.getImsManager(SLOT_0_SUB_ID); 908 assertNull(imsManager); 909 } 910 createController(int slotCount)911 private void createController(int slotCount) throws Exception { 912 if (Looper.myLooper() == null) { 913 Looper.prepare(); 914 } 915 makeFakeActiveSubIds(slotCount); 916 917 when(mMmTelFeatureFactory 918 .create(any(), eq(0), any(), mMmTelConnectorListenerSlot0.capture(), any())) 919 .thenReturn(mMmTelFeatureConnectorSlot0); 920 when(mMmTelFeatureFactory 921 .create(any(), eq(1), any(), mMmTelConnectorListenerSlot1.capture(), any())) 922 .thenReturn(mMmTelFeatureConnectorSlot1); 923 when(mRcsFeatureFactory 924 .create(any(), eq(0), mRcsConnectorListenerSlot0.capture(), any(), any())) 925 .thenReturn(mRcsFeatureConnectorSlot0); 926 when(mRcsFeatureFactory 927 .create(any(), eq(1), mRcsConnectorListenerSlot1.capture(), any(), any())) 928 .thenReturn(mRcsFeatureConnectorSlot1); 929 930 mImsStateCallbackController = 931 new ImsStateCallbackController(mPhone, mHandlerThread.getLooper(), 932 slotCount, mMmTelFeatureFactory, mRcsFeatureFactory, mImsResolver); 933 934 replaceInstance(ImsStateCallbackController.class, 935 "mPhoneFactoryProxy", mImsStateCallbackController, mPhoneFactoryProxy); 936 mImsStateCallbackController.onSubChanged(); 937 938 mHandler = mImsStateCallbackController.getHandler(); 939 try { 940 mLooper = new TestableLooper(mHandler.getLooper()); 941 } catch (Exception e) { 942 logd("Unable to create looper from handler."); 943 } 944 945 verify(mRcsFeatureConnectorSlot0, atLeastOnce()).connect(); 946 verify(mMmTelFeatureConnectorSlot0, atLeastOnce()).connect(); 947 948 if (slotCount == 1) { 949 verify(mRcsFeatureConnectorSlot1, times(0)).connect(); 950 verify(mMmTelFeatureConnectorSlot1, times(0)).connect(); 951 } else { 952 verify(mRcsFeatureConnectorSlot1, atLeastOnce()).connect(); 953 verify(mMmTelFeatureConnectorSlot1, atLeastOnce()).connect(); 954 } 955 } 956 makeFakeActiveSubIds(int count)957 private void makeFakeActiveSubIds(int count) { 958 final int[] subIds = new int[count]; 959 for (int i = 0; i < count; i++) { 960 subIds[i] = FAKE_SUB_ID_BASE + i; 961 } 962 when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(subIds); 963 } 964 processAllMessages()965 private void processAllMessages() { 966 while (!mLooper.getLooper().getQueue().isIdle()) { 967 mLooper.processAllMessages(); 968 } 969 } 970 logd(String str)971 private static void logd(String str) { 972 Log.d(TAG, str); 973 } 974 } 975