1 /* 2 * Copyright (C) 2014 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.server.telecom.tests; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNull; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assert.fail; 25 import static org.mockito.Matchers.anyBoolean; 26 import static org.mockito.Matchers.anyInt; 27 import static org.mockito.Matchers.anyString; 28 import static org.mockito.Mockito.clearInvocations; 29 import static org.mockito.Mockito.never; 30 import static org.mockito.Mockito.times; 31 import static org.mockito.Mockito.verify; 32 import static org.mockito.Mockito.when; 33 34 import android.annotation.Nullable; 35 import android.content.ComponentName; 36 import android.content.Context; 37 import android.content.pm.PackageInfo; 38 import android.content.pm.PackageManager; 39 import android.graphics.BitmapFactory; 40 import android.graphics.Rect; 41 import android.graphics.drawable.Icon; 42 import android.net.Uri; 43 import android.os.Bundle; 44 import android.os.Parcel; 45 import android.os.PersistableBundle; 46 import android.os.Process; 47 import android.os.UserHandle; 48 import android.os.UserManager; 49 import android.telecom.Log; 50 import android.telecom.PhoneAccount; 51 import android.telecom.PhoneAccountHandle; 52 import android.telecom.TelecomManager; 53 import android.telephony.CarrierConfigManager; 54 import android.telephony.SubscriptionInfo; 55 import android.telephony.SubscriptionManager; 56 import android.test.suitebuilder.annotation.SmallTest; 57 import android.test.suitebuilder.annotation.MediumTest; 58 import android.util.Xml; 59 60 import androidx.test.InstrumentationRegistry; 61 62 import com.android.internal.telecom.IConnectionService; 63 import com.android.internal.util.FastXmlSerializer; 64 import com.android.server.telecom.AppLabelProxy; 65 import com.android.server.telecom.DefaultDialerCache; 66 import com.android.server.telecom.PhoneAccountRegistrar; 67 import com.android.server.telecom.PhoneAccountRegistrar.DefaultPhoneAccountHandle; 68 import com.android.server.telecom.TelecomSystem; 69 70 import org.junit.After; 71 import org.junit.Before; 72 import org.junit.Test; 73 import org.junit.runner.RunWith; 74 import org.junit.runners.JUnit4; 75 import org.mockito.Mock; 76 import org.mockito.Mockito; 77 import org.mockito.MockitoAnnotations; 78 import org.xmlpull.v1.XmlPullParser; 79 import org.xmlpull.v1.XmlSerializer; 80 81 import java.io.BufferedInputStream; 82 import java.io.BufferedOutputStream; 83 import java.io.ByteArrayInputStream; 84 import java.io.ByteArrayOutputStream; 85 import java.io.File; 86 import java.util.ArrayList; 87 import java.util.Arrays; 88 import java.util.Collection; 89 import java.util.List; 90 import java.util.Map; 91 import java.util.Set; 92 93 @RunWith(JUnit4.class) 94 public class PhoneAccountRegistrarTest extends TelecomTestCase { 95 96 private static final int MAX_VERSION = Integer.MAX_VALUE; 97 private static final String FILE_NAME = "phone-account-registrar-test-1223.xml"; 98 private static final String TEST_LABEL = "right"; 99 private final String PACKAGE_1 = "PACKAGE_1"; 100 private final String PACKAGE_2 = "PACKAGE_2"; 101 private final String COMPONENT_NAME = "com.android.server.telecom.tests.MockConnectionService"; 102 private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { }; 103 private PhoneAccountRegistrar mRegistrar; 104 @Mock private SubscriptionManager mSubscriptionManager; 105 @Mock private TelecomManager mTelecomManager; 106 @Mock private DefaultDialerCache mDefaultDialerCache; 107 @Mock private AppLabelProxy mAppLabelProxy; 108 109 @Override 110 @Before setUp()111 public void setUp() throws Exception { 112 super.setUp(); 113 MockitoAnnotations.initMocks(this); 114 mComponentContextFixture.setTelecomManager(mTelecomManager); 115 mComponentContextFixture.setSubscriptionManager(mSubscriptionManager); 116 new File( 117 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(), 118 FILE_NAME) 119 .delete(); 120 when(mDefaultDialerCache.getDefaultDialerApplication(anyInt())) 121 .thenReturn("com.android.dialer"); 122 when(mAppLabelProxy.getAppLabel(anyString())) 123 .thenReturn(TEST_LABEL); 124 mRegistrar = new PhoneAccountRegistrar( 125 mComponentContextFixture.getTestDouble().getApplicationContext(), 126 mLock, FILE_NAME, mDefaultDialerCache, mAppLabelProxy); 127 } 128 129 @Override 130 @After tearDown()131 public void tearDown() throws Exception { 132 mRegistrar = null; 133 new File( 134 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(), 135 FILE_NAME) 136 .delete(); 137 super.tearDown(); 138 } 139 140 @MediumTest 141 @Test testPhoneAccountHandle()142 public void testPhoneAccountHandle() throws Exception { 143 PhoneAccountHandle input = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0"); 144 PhoneAccountHandle result = roundTripXml(this, input, 145 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 146 assertPhoneAccountHandleEquals(input, result); 147 148 PhoneAccountHandle inputN = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), null); 149 PhoneAccountHandle resultN = roundTripXml(this, inputN, 150 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 151 Log.i(this, "inputN = %s, resultN = %s", inputN, resultN); 152 assertPhoneAccountHandleEquals(inputN, resultN); 153 } 154 155 @MediumTest 156 @Test testPhoneAccount()157 public void testPhoneAccount() throws Exception { 158 Bundle testBundle = new Bundle(); 159 testBundle.putInt("EXTRA_INT_1", 1); 160 testBundle.putInt("EXTRA_INT_100", 100); 161 testBundle.putBoolean("EXTRA_BOOL_TRUE", true); 162 testBundle.putBoolean("EXTRA_BOOL_FALSE", false); 163 testBundle.putString("EXTRA_STR1", "Hello"); 164 testBundle.putString("EXTRA_STR2", "There"); 165 166 PhoneAccount input = makeQuickAccountBuilder("id0", 0) 167 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 168 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 169 .setExtras(testBundle) 170 .setIsEnabled(true) 171 .build(); 172 PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml, 173 mContext); 174 175 assertPhoneAccountEquals(input, result); 176 } 177 178 @SmallTest 179 @Test testFilterPhoneAccountForTest()180 public void testFilterPhoneAccountForTest() throws Exception { 181 ComponentName componentA = new ComponentName("a", "a"); 182 ComponentName componentB1 = new ComponentName("b", "b1"); 183 ComponentName componentB2 = new ComponentName("b", "b2"); 184 ComponentName componentC = new ComponentName("c", "c"); 185 186 PhoneAccount simAccountA = new PhoneAccount.Builder( 187 makeQuickAccountHandle(componentA, "1"), "1") 188 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 189 .setIsEnabled(true) 190 .build(); 191 192 List<PhoneAccount> accountAList = new ArrayList<>(); 193 accountAList.add(simAccountA); 194 195 PhoneAccount simAccountB1 = new PhoneAccount.Builder( 196 makeQuickAccountHandle(componentB1, "2"), "2") 197 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 198 .setIsEnabled(true) 199 .build(); 200 201 PhoneAccount simAccountB2 = new PhoneAccount.Builder( 202 makeQuickAccountHandle(componentB2, "3"), "3") 203 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 204 .setIsEnabled(true) 205 .build(); 206 207 List<PhoneAccount> accountBList = new ArrayList<>(); 208 accountBList.add(simAccountB1); 209 accountBList.add(simAccountB2); 210 211 PhoneAccount simAccountC = new PhoneAccount.Builder( 212 makeQuickAccountHandle(componentC, "4"), "4") 213 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 214 .setIsEnabled(true) 215 .build(); 216 217 List<PhoneAccount> accountCList = new ArrayList<>(); 218 accountCList.add(simAccountC); 219 220 List<PhoneAccount> allAccounts = new ArrayList<>(); 221 allAccounts.addAll(accountAList); 222 allAccounts.addAll(accountBList); 223 allAccounts.addAll(accountCList); 224 225 assertEquals(allAccounts, mRegistrar.filterRestrictedPhoneAccounts(allAccounts)); 226 227 mRegistrar.setTestPhoneAccountPackageNameFilter(componentA.getPackageName()); 228 assertEquals(accountAList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts)); 229 230 mRegistrar.setTestPhoneAccountPackageNameFilter(componentB1.getPackageName()); 231 assertEquals(accountBList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts)); 232 233 mRegistrar.setTestPhoneAccountPackageNameFilter(componentC.getPackageName()); 234 assertEquals(accountCList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts)); 235 236 mRegistrar.setTestPhoneAccountPackageNameFilter(null); 237 assertEquals(allAccounts, mRegistrar.filterRestrictedPhoneAccounts(allAccounts)); 238 } 239 240 @MediumTest 241 @Test testDefaultPhoneAccountHandleEmptyGroup()242 public void testDefaultPhoneAccountHandleEmptyGroup() throws Exception { 243 DefaultPhoneAccountHandle input = new DefaultPhoneAccountHandle(Process.myUserHandle(), 244 makeQuickAccountHandle("i1"), ""); 245 when(UserManager.get(mContext).getSerialNumberForUser(input.userHandle)) 246 .thenReturn(0L); 247 when(UserManager.get(mContext).getUserForSerialNumber(0L)) 248 .thenReturn(input.userHandle); 249 DefaultPhoneAccountHandle result = roundTripXml(this, input, 250 PhoneAccountRegistrar.sDefaultPhoneAcountHandleXml, mContext); 251 252 assertDefaultPhoneAccountHandleEquals(input, result); 253 } 254 255 /** 256 * Test to ensure non-supported values 257 * @throws Exception 258 */ 259 @MediumTest 260 @Test testPhoneAccountExtrasEdge()261 public void testPhoneAccountExtrasEdge() throws Exception { 262 Bundle testBundle = new Bundle(); 263 // Ensure null values for string are not persisted. 264 testBundle.putString("EXTRA_STR2", null); 265 // 266 267 // Ensure unsupported data types are not persisted. 268 testBundle.putShort("EXTRA_SHORT", (short) 2); 269 testBundle.putByte("EXTRA_BYTE", (byte) 1); 270 testBundle.putParcelable("EXTRA_PARC", new Rect(1, 1, 1, 1)); 271 // Put in something valid so the bundle exists. 272 testBundle.putString("EXTRA_OK", "OK"); 273 274 PhoneAccount input = makeQuickAccountBuilder("id0", 0) 275 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 276 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 277 .setExtras(testBundle) 278 .build(); 279 PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml, 280 mContext); 281 282 Bundle extras = result.getExtras(); 283 assertFalse(extras.keySet().contains("EXTRA_STR2")); 284 assertFalse(extras.keySet().contains("EXTRA_SHORT")); 285 assertFalse(extras.keySet().contains("EXTRA_BYTE")); 286 assertFalse(extras.keySet().contains("EXTRA_PARC")); 287 } 288 289 @MediumTest 290 @Test testState()291 public void testState() throws Exception { 292 PhoneAccountRegistrar.State input = makeQuickState(); 293 PhoneAccountRegistrar.State result = roundTripXml(this, input, 294 PhoneAccountRegistrar.sStateXml, 295 mContext); 296 assertStateEquals(input, result); 297 } 298 registerAndEnableAccount(PhoneAccount account)299 private void registerAndEnableAccount(PhoneAccount account) { 300 mRegistrar.registerPhoneAccount(account); 301 mRegistrar.enablePhoneAccount(account.getAccountHandle(), true); 302 } 303 304 @MediumTest 305 @Test testAccounts()306 public void testAccounts() throws Exception { 307 int i = 0; 308 309 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 310 Mockito.mock(IConnectionService.class)); 311 312 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 313 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 314 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 315 .build()); 316 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 317 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 318 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 319 .build()); 320 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 321 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 322 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 323 .build()); 324 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 325 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 326 .build()); 327 328 assertEquals(4, mRegistrar.getAllPhoneAccountsOfCurrentUser().size()); 329 assertEquals(3, mRegistrar.getCallCapablePhoneAccountsOfCurrentUser(null, false).size()); 330 assertEquals(null, mRegistrar.getSimCallManagerOfCurrentUser()); 331 assertEquals(null, mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 332 PhoneAccount.SCHEME_TEL)); 333 } 334 335 @MediumTest 336 @Test testSimCallManager()337 public void testSimCallManager() throws Exception { 338 // TODO 339 } 340 341 @MediumTest 342 @Test testDefaultOutgoing()343 public void testDefaultOutgoing() throws Exception { 344 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 345 Mockito.mock(IConnectionService.class)); 346 347 // By default, there is no default outgoing account (nothing has been registered) 348 assertNull( 349 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 350 351 // Register one tel: account 352 PhoneAccountHandle telAccount = makeQuickAccountHandle("tel_acct"); 353 registerAndEnableAccount(new PhoneAccount.Builder(telAccount, "tel_acct") 354 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 355 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 356 .build()); 357 PhoneAccountHandle defaultAccount = 358 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 359 assertEquals(telAccount, defaultAccount); 360 361 // Add a SIP account, make sure tel: doesn't change 362 PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct"); 363 registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct") 364 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 365 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP) 366 .build()); 367 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 368 PhoneAccount.SCHEME_SIP); 369 assertEquals(sipAccount, defaultAccount); 370 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 371 PhoneAccount.SCHEME_TEL); 372 assertEquals(telAccount, defaultAccount); 373 374 // Add a connection manager, make sure tel: doesn't change 375 PhoneAccountHandle connectionManager = makeQuickAccountHandle("mgr_acct"); 376 registerAndEnableAccount(new PhoneAccount.Builder(connectionManager, "mgr_acct") 377 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 378 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 379 .build()); 380 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 381 PhoneAccount.SCHEME_TEL); 382 assertEquals(telAccount, defaultAccount); 383 384 // Unregister the tel: account, make sure there is no tel: default now. 385 mRegistrar.unregisterPhoneAccount(telAccount); 386 assertNull( 387 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 388 } 389 390 @MediumTest 391 @Test testReplacePhoneAccountByGroup()392 public void testReplacePhoneAccountByGroup() throws Exception { 393 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 394 Mockito.mock(IConnectionService.class)); 395 396 // By default, there is no default outgoing account (nothing has been registered) 397 assertNull( 398 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 399 400 // Register one tel: account 401 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 402 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 403 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 404 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 405 .setGroupId("testGroup") 406 .build()); 407 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 408 PhoneAccountHandle defaultAccount = 409 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 410 assertEquals(telAccount1, defaultAccount); 411 412 // Add call capable SIP account, make sure tel: doesn't change 413 PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct"); 414 registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct") 415 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 416 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 417 .build()); 418 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 419 PhoneAccount.SCHEME_TEL); 420 assertEquals(telAccount1, defaultAccount); 421 422 // Replace tel: account with another in the same Group 423 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 424 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 425 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 426 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 427 .setGroupId("testGroup") 428 .build()); 429 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 430 PhoneAccount.SCHEME_TEL); 431 assertEquals(telAccount2, defaultAccount); 432 assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 433 } 434 435 @MediumTest 436 @Test testAddSameDefault()437 public void testAddSameDefault() throws Exception { 438 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 439 Mockito.mock(IConnectionService.class)); 440 441 // By default, there is no default outgoing account (nothing has been registered) 442 assertNull( 443 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 444 445 // Register one tel: account 446 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 447 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 448 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 449 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 450 .setGroupId("testGroup") 451 .build()); 452 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 453 PhoneAccountHandle defaultAccount = 454 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 455 assertEquals(telAccount1, defaultAccount); 456 mRegistrar.unregisterPhoneAccount(telAccount1); 457 458 // Register Emergency Account and unregister 459 PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct"); 460 registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct") 461 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 462 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 463 .build()); 464 defaultAccount = 465 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 466 assertNull(defaultAccount); 467 mRegistrar.unregisterPhoneAccount(emerAccount); 468 469 // Re-register the same account and make sure the default is in place 470 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 471 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 472 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 473 .setGroupId("testGroup") 474 .build()); 475 defaultAccount = 476 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 477 assertEquals(telAccount1, defaultAccount); 478 } 479 480 @MediumTest 481 @Test testAddSameGroup()482 public void testAddSameGroup() throws Exception { 483 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 484 Mockito.mock(IConnectionService.class)); 485 486 // By default, there is no default outgoing account (nothing has been registered) 487 assertNull( 488 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 489 490 // Register one tel: account 491 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 492 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 493 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 494 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 495 .setGroupId("testGroup") 496 .build()); 497 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 498 PhoneAccountHandle defaultAccount = 499 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 500 assertEquals(telAccount1, defaultAccount); 501 mRegistrar.unregisterPhoneAccount(telAccount1); 502 503 // Register Emergency Account and unregister 504 PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct"); 505 registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct") 506 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 507 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 508 .build()); 509 defaultAccount = 510 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 511 assertNull(defaultAccount); 512 mRegistrar.unregisterPhoneAccount(emerAccount); 513 514 // Re-register a new account with the same group 515 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 516 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 517 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 518 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 519 .setGroupId("testGroup") 520 .build()); 521 defaultAccount = 522 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 523 assertEquals(telAccount2, defaultAccount); 524 } 525 526 @MediumTest 527 @Test testAddSameGroupButDifferentComponent()528 public void testAddSameGroupButDifferentComponent() throws Exception { 529 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 530 Mockito.mock(IConnectionService.class)); 531 532 // By default, there is no default outgoing account (nothing has been registered) 533 assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 534 PhoneAccount.SCHEME_TEL)); 535 536 // Register one tel: account 537 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 538 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 539 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 540 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 541 .setGroupId("testGroup") 542 .build()); 543 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 544 PhoneAccountHandle defaultAccount = 545 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 546 assertEquals(telAccount1, defaultAccount); 547 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 548 549 // Register a new account with the same group, but different Component, so don't replace 550 // Default 551 PhoneAccountHandle telAccount2 = makeQuickAccountHandle( 552 new ComponentName("other1", "other2"), "tel_acct2"); 553 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 554 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 555 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 556 .setGroupId("testGroup") 557 .build()); 558 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount2)); 559 560 defaultAccount = 561 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 562 assertEquals(telAccount1, defaultAccount); 563 } 564 565 @MediumTest 566 @Test testAddSameGroupButDifferentComponent2()567 public void testAddSameGroupButDifferentComponent2() throws Exception { 568 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 569 Mockito.mock(IConnectionService.class)); 570 571 // By default, there is no default outgoing account (nothing has been registered) 572 assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 573 PhoneAccount.SCHEME_TEL)); 574 575 // Register first tel: account 576 PhoneAccountHandle telAccount1 = makeQuickAccountHandle( 577 new ComponentName("other1", "other2"), "tel_acct1"); 578 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 579 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 580 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 581 .setGroupId("testGroup") 582 .build()); 583 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 584 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 585 586 // Register second account with the same group, but a second Component, so don't replace 587 // Default 588 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 589 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 590 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 591 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 592 .setGroupId("testGroup") 593 .build()); 594 595 PhoneAccountHandle defaultAccount = 596 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 597 assertEquals(telAccount1, defaultAccount); 598 599 // Register third account with the second component name, but same group id 600 PhoneAccountHandle telAccount3 = makeQuickAccountHandle("tel_acct3"); 601 registerAndEnableAccount(new PhoneAccount.Builder(telAccount3, "tel_acct3") 602 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 603 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 604 .setGroupId("testGroup") 605 .build()); 606 607 // Make sure that the default account is still the original PhoneAccount and that the 608 // second PhoneAccount with the second ComponentName was replaced by the third PhoneAccount 609 defaultAccount = 610 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 611 assertEquals(telAccount1, defaultAccount); 612 613 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 614 assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount2)); 615 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount3)); 616 } 617 618 @MediumTest 619 @Test testPhoneAccountParceling()620 public void testPhoneAccountParceling() throws Exception { 621 PhoneAccountHandle handle = makeQuickAccountHandle("foo"); 622 roundTripPhoneAccount(new PhoneAccount.Builder(handle, null).build()); 623 roundTripPhoneAccount(new PhoneAccount.Builder(handle, "foo").build()); 624 roundTripPhoneAccount( 625 new PhoneAccount.Builder(handle, "foo") 626 .setAddress(Uri.parse("tel:123456")) 627 .setCapabilities(23) 628 .setHighlightColor(0xf0f0f0) 629 .setIcon(Icon.createWithResource( 630 "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call)) 631 // TODO: set icon tint (0xfefefe) 632 .setShortDescription("short description") 633 .setSubscriptionAddress(Uri.parse("tel:2345678")) 634 .setSupportedUriSchemes(Arrays.asList("tel", "sip")) 635 .setGroupId("testGroup") 636 .build()); 637 roundTripPhoneAccount( 638 new PhoneAccount.Builder(handle, "foo") 639 .setAddress(Uri.parse("tel:123456")) 640 .setCapabilities(23) 641 .setHighlightColor(0xf0f0f0) 642 .setIcon(Icon.createWithBitmap( 643 BitmapFactory.decodeResource( 644 InstrumentationRegistry.getContext().getResources(), 645 R.drawable.stat_sys_phone_call))) 646 .setShortDescription("short description") 647 .setSubscriptionAddress(Uri.parse("tel:2345678")) 648 .setSupportedUriSchemes(Arrays.asList("tel", "sip")) 649 .setGroupId("testGroup") 650 .build()); 651 } 652 653 /** 654 * Tests ability to register a self-managed PhoneAccount; verifies that the user defined label 655 * is overridden. 656 * @throws Exception 657 */ 658 @MediumTest 659 @Test testSelfManagedPhoneAccount()660 public void testSelfManagedPhoneAccount() throws Exception { 661 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 662 Mockito.mock(IConnectionService.class)); 663 664 PhoneAccountHandle selfManagedHandle = makeQuickAccountHandle( 665 new ComponentName("self", "managed"), "selfie1"); 666 667 PhoneAccount selfManagedAccount = new PhoneAccount.Builder(selfManagedHandle, "Wrong") 668 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED) 669 .build(); 670 671 mRegistrar.registerPhoneAccount(selfManagedAccount); 672 673 PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(selfManagedHandle); 674 assertEquals(TEST_LABEL, registeredAccount.getLabel()); 675 } 676 677 /** 678 * Tests to ensure that when registering a self-managed PhoneAccount, it cannot also be defined 679 * as a call provider, connection manager, or sim subscription. 680 * @throws Exception 681 */ 682 @MediumTest 683 @Test testSelfManagedCapabilityOverride()684 public void testSelfManagedCapabilityOverride() throws Exception { 685 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 686 Mockito.mock(IConnectionService.class)); 687 688 PhoneAccountHandle selfManagedHandle = makeQuickAccountHandle( 689 new ComponentName("self", "managed"), "selfie1"); 690 691 PhoneAccount selfManagedAccount = new PhoneAccount.Builder(selfManagedHandle, TEST_LABEL) 692 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED | 693 PhoneAccount.CAPABILITY_CALL_PROVIDER | 694 PhoneAccount.CAPABILITY_CONNECTION_MANAGER | 695 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 696 .build(); 697 698 mRegistrar.registerPhoneAccount(selfManagedAccount); 699 700 PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(selfManagedHandle); 701 assertEquals(PhoneAccount.CAPABILITY_SELF_MANAGED, registeredAccount.getCapabilities()); 702 } 703 704 @MediumTest 705 @Test testSortSimFirst()706 public void testSortSimFirst() throws Exception { 707 ComponentName componentA = new ComponentName("a", "a"); 708 ComponentName componentB = new ComponentName("b", "b"); 709 mComponentContextFixture.addConnectionService(componentA, 710 Mockito.mock(IConnectionService.class)); 711 mComponentContextFixture.addConnectionService(componentB, 712 Mockito.mock(IConnectionService.class)); 713 714 PhoneAccount simAccount = new PhoneAccount.Builder( 715 makeQuickAccountHandle(componentB, "2"), "2") 716 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 717 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 718 .setIsEnabled(true) 719 .build(); 720 721 PhoneAccount nonSimAccount = new PhoneAccount.Builder( 722 makeQuickAccountHandle(componentA, "1"), "1") 723 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 724 .setIsEnabled(true) 725 .build(); 726 727 registerAndEnableAccount(nonSimAccount); 728 registerAndEnableAccount(simAccount); 729 730 List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle()); 731 assertTrue(accounts.get(0).getLabel().toString().equals("2")); 732 assertTrue(accounts.get(1).getLabel().toString().equals("1")); 733 } 734 735 @MediumTest 736 @Test testSortBySortOrder()737 public void testSortBySortOrder() throws Exception { 738 ComponentName componentA = new ComponentName("a", "a"); 739 ComponentName componentB = new ComponentName("b", "b"); 740 ComponentName componentC = new ComponentName("c", "c"); 741 mComponentContextFixture.addConnectionService(componentA, 742 Mockito.mock(IConnectionService.class)); 743 mComponentContextFixture.addConnectionService(componentB, 744 Mockito.mock(IConnectionService.class)); 745 mComponentContextFixture.addConnectionService(componentC, 746 Mockito.mock(IConnectionService.class)); 747 748 Bundle account1Extras = new Bundle(); 749 account1Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 1); 750 PhoneAccount account1 = new PhoneAccount.Builder( 751 makeQuickAccountHandle(componentA, "c"), "c") 752 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 753 .setExtras(account1Extras) 754 .build(); 755 756 Bundle account2Extras = new Bundle(); 757 account2Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 2); 758 PhoneAccount account2 = new PhoneAccount.Builder( 759 makeQuickAccountHandle(componentB, "b"), "b") 760 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 761 .setExtras(account2Extras) 762 .build(); 763 764 PhoneAccount account3 = new PhoneAccount.Builder( 765 makeQuickAccountHandle(componentC, "c"), "a") 766 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 767 .build(); 768 769 registerAndEnableAccount(account3); 770 registerAndEnableAccount(account2); 771 registerAndEnableAccount(account1); 772 773 List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle()); 774 assertTrue(accounts.get(0).getLabel().toString().equals("c")); 775 assertTrue(accounts.get(1).getLabel().toString().equals("b")); 776 assertTrue(accounts.get(2).getLabel().toString().equals("a")); 777 } 778 779 @MediumTest 780 @Test testSortByLabel()781 public void testSortByLabel() throws Exception { 782 ComponentName componentA = new ComponentName("a", "a"); 783 ComponentName componentB = new ComponentName("b", "b"); 784 ComponentName componentC = new ComponentName("c", "c"); 785 mComponentContextFixture.addConnectionService(componentA, 786 Mockito.mock(IConnectionService.class)); 787 mComponentContextFixture.addConnectionService(componentB, 788 Mockito.mock(IConnectionService.class)); 789 mComponentContextFixture.addConnectionService(componentC, 790 Mockito.mock(IConnectionService.class)); 791 792 PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle(componentA, "c"), 793 "c") 794 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 795 .build(); 796 797 PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle(componentB, "b"), 798 "b") 799 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 800 .build(); 801 802 PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle(componentC, "a"), 803 "a") 804 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 805 .build(); 806 807 registerAndEnableAccount(account1); 808 registerAndEnableAccount(account2); 809 registerAndEnableAccount(account3); 810 811 List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle()); 812 assertTrue(accounts.get(0).getLabel().toString().equals("a")); 813 assertTrue(accounts.get(1).getLabel().toString().equals("b")); 814 assertTrue(accounts.get(2).getLabel().toString().equals("c")); 815 } 816 817 @MediumTest 818 @Test testSortAll()819 public void testSortAll() throws Exception { 820 ComponentName componentA = new ComponentName("a", "a"); 821 ComponentName componentB = new ComponentName("b", "b"); 822 ComponentName componentC = new ComponentName("c", "c"); 823 ComponentName componentW = new ComponentName("w", "w"); 824 ComponentName componentX = new ComponentName("x", "x"); 825 ComponentName componentY = new ComponentName("y", "y"); 826 ComponentName componentZ = new ComponentName("z", "z"); 827 mComponentContextFixture.addConnectionService(componentA, 828 Mockito.mock(IConnectionService.class)); 829 mComponentContextFixture.addConnectionService(componentB, 830 Mockito.mock(IConnectionService.class)); 831 mComponentContextFixture.addConnectionService(componentC, 832 Mockito.mock(IConnectionService.class)); 833 mComponentContextFixture.addConnectionService(componentW, 834 Mockito.mock(IConnectionService.class)); 835 mComponentContextFixture.addConnectionService(componentX, 836 Mockito.mock(IConnectionService.class)); 837 mComponentContextFixture.addConnectionService(componentY, 838 Mockito.mock(IConnectionService.class)); 839 mComponentContextFixture.addConnectionService(componentZ, 840 Mockito.mock(IConnectionService.class)); 841 842 Bundle account1Extras = new Bundle(); 843 account1Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 2); 844 PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle( 845 makeQuickConnectionServiceComponentName(), "y"), "y") 846 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 847 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 848 .setExtras(account1Extras) 849 .build(); 850 851 Bundle account2Extras = new Bundle(); 852 account2Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 1); 853 PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle( 854 makeQuickConnectionServiceComponentName(), "z"), "z") 855 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 856 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 857 .setExtras(account2Extras) 858 .build(); 859 860 PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle( 861 makeQuickConnectionServiceComponentName(), "x"), "x") 862 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 863 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 864 .build(); 865 866 PhoneAccount account4 = new PhoneAccount.Builder(makeQuickAccountHandle( 867 makeQuickConnectionServiceComponentName(), "w"), "w") 868 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 869 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 870 .build(); 871 872 PhoneAccount account5 = new PhoneAccount.Builder(makeQuickAccountHandle( 873 makeQuickConnectionServiceComponentName(), "b"), "b") 874 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 875 .build(); 876 877 PhoneAccount account6 = new PhoneAccount.Builder(makeQuickAccountHandle( 878 makeQuickConnectionServiceComponentName(), "c"), "a") 879 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 880 .build(); 881 882 registerAndEnableAccount(account1); 883 registerAndEnableAccount(account2); 884 registerAndEnableAccount(account3); 885 registerAndEnableAccount(account4); 886 registerAndEnableAccount(account5); 887 registerAndEnableAccount(account6); 888 889 List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle()); 890 // Sim accts ordered by sort order first 891 assertTrue(accounts.get(0).getLabel().toString().equals("z")); 892 assertTrue(accounts.get(1).getLabel().toString().equals("y")); 893 894 // Sim accts with no sort order next 895 assertTrue(accounts.get(2).getLabel().toString().equals("w")); 896 assertTrue(accounts.get(3).getLabel().toString().equals("x")); 897 898 // Other accts sorted by label next 899 assertTrue(accounts.get(4).getLabel().toString().equals("a")); 900 assertTrue(accounts.get(5).getLabel().toString().equals("b")); 901 } 902 903 /** 904 * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle)} 905 * to ensure disabled accounts are filtered out of results when requested. 906 * @throws Exception 907 */ 908 @MediumTest 909 @Test testGetByEnabledState()910 public void testGetByEnabledState() throws Exception { 911 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 912 Mockito.mock(IConnectionService.class)); 913 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id1", 1) 914 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 915 .build()); 916 917 assertEquals(0, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL, 918 false /* includeDisabled */, Process.myUserHandle()).size()); 919 assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL, 920 true /* includeDisabled */, Process.myUserHandle()).size()); 921 } 922 923 /** 924 * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle)} 925 * to ensure scheme filtering operates. 926 * @throws Exception 927 */ 928 @MediumTest 929 @Test testGetByScheme()930 public void testGetByScheme() throws Exception { 931 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 932 Mockito.mock(IConnectionService.class)); 933 registerAndEnableAccount(makeQuickAccountBuilder("id1", 1) 934 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 935 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP)) 936 .build()); 937 registerAndEnableAccount(makeQuickAccountBuilder("id2", 2) 938 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 939 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL)) 940 .build()); 941 942 assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP, 943 false /* includeDisabled */, Process.myUserHandle()).size()); 944 assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL, 945 false /* includeDisabled */, Process.myUserHandle()).size()); 946 assertEquals(2, mRegistrar.getCallCapablePhoneAccounts(null, false /* includeDisabled */, 947 Process.myUserHandle()).size()); 948 } 949 950 /** 951 * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle, 952 * int)} to ensure capability filtering operates. 953 * @throws Exception 954 */ 955 @MediumTest 956 @Test testGetByCapability()957 public void testGetByCapability() throws Exception { 958 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 959 Mockito.mock(IConnectionService.class)); 960 registerAndEnableAccount(makeQuickAccountBuilder("id1", 1) 961 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER 962 | PhoneAccount.CAPABILITY_VIDEO_CALLING) 963 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP)) 964 .build()); 965 registerAndEnableAccount(makeQuickAccountBuilder("id2", 2) 966 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 967 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP)) 968 .build()); 969 970 assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP, 971 false /* includeDisabled */, Process.myUserHandle()).size(), 972 PhoneAccount.CAPABILITY_VIDEO_CALLING); 973 assertEquals(2, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP, 974 false /* includeDisabled */, Process.myUserHandle()).size(), 0 /* none extra */); 975 assertEquals(0, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP, 976 false /* includeDisabled */, Process.myUserHandle()).size(), 977 PhoneAccount.CAPABILITY_RTT); 978 } 979 980 /** 981 * Tests {@link PhoneAccount#equals(Object)} operator. 982 * @throws Exception 983 */ 984 @MediumTest 985 @Test testPhoneAccountEquality()986 public void testPhoneAccountEquality() throws Exception { 987 PhoneAccountHandle handle = new PhoneAccountHandle(new ComponentName("foo", "bar"), "id"); 988 PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, "label"); 989 builder.addSupportedUriScheme("tel"); 990 builder.setAddress(Uri.fromParts("tel", "6505551212", null)); 991 builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER); 992 Bundle extras = new Bundle(); 993 extras.putInt("INT", 1); 994 extras.putString("STR", "str"); 995 builder.setExtras(extras); 996 builder.setGroupId("group"); 997 builder.setHighlightColor(1); 998 builder.setShortDescription("short"); 999 builder.setSubscriptionAddress(Uri.fromParts("tel", "6505551213", null)); 1000 builder.setSupportedAudioRoutes(2); 1001 1002 PhoneAccount account1 = builder.build(); 1003 PhoneAccount account2 = builder.build(); 1004 assertEquals(account1, account2); 1005 } 1006 1007 /** 1008 * Tests {@link PhoneAccountHandle#areFromSamePackage(PhoneAccountHandle, 1009 * PhoneAccountHandle)} comparison. 1010 */ 1011 @SmallTest 1012 @Test testSamePhoneAccountHandlePackage()1013 public void testSamePhoneAccountHandlePackage() { 1014 PhoneAccountHandle a = new PhoneAccountHandle(new ComponentName("packageA", "class1"), 1015 "id1"); 1016 PhoneAccountHandle b = new PhoneAccountHandle(new ComponentName("packageA", "class2"), 1017 "id2"); 1018 PhoneAccountHandle c = new PhoneAccountHandle(new ComponentName("packageA", "class1"), 1019 "id3"); 1020 PhoneAccountHandle d = new PhoneAccountHandle(new ComponentName("packageB", "class1"), 1021 "id1"); 1022 1023 assertTrue(PhoneAccountHandle.areFromSamePackage(null, null)); 1024 assertTrue(PhoneAccountHandle.areFromSamePackage(a, b)); 1025 assertTrue(PhoneAccountHandle.areFromSamePackage(a, c)); 1026 assertTrue(PhoneAccountHandle.areFromSamePackage(b, c)); 1027 assertFalse(PhoneAccountHandle.areFromSamePackage(a, d)); 1028 assertFalse(PhoneAccountHandle.areFromSamePackage(b, d)); 1029 assertFalse(PhoneAccountHandle.areFromSamePackage(c, d)); 1030 assertFalse(PhoneAccountHandle.areFromSamePackage(a, null)); 1031 assertFalse(PhoneAccountHandle.areFromSamePackage(b, null)); 1032 assertFalse(PhoneAccountHandle.areFromSamePackage(c, null)); 1033 assertFalse(PhoneAccountHandle.areFromSamePackage(null, d)); 1034 assertFalse(PhoneAccountHandle.areFromSamePackage(null, d)); 1035 assertFalse(PhoneAccountHandle.areFromSamePackage(null, d)); 1036 } 1037 1038 /** 1039 * Tests {@link PhoneAccountRegistrar#cleanupOrphanedPhoneAccounts } cleans up / deletes an 1040 * orphan account. 1041 */ 1042 @Test testCleanUpOrphanAccounts()1043 public void testCleanUpOrphanAccounts() throws Exception { 1044 // GIVEN 1045 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 1046 Mockito.mock(IConnectionService.class)); 1047 1048 List<UserHandle> users = Arrays.asList(new UserHandle(0), 1049 new UserHandle(1000)); 1050 1051 PhoneAccount pa1 = new PhoneAccount.Builder( 1052 new PhoneAccountHandle(new ComponentName(PACKAGE_1, COMPONENT_NAME), "1234", 1053 users.get(0)), "l1").build(); 1054 PhoneAccount pa2 = new PhoneAccount.Builder( 1055 new PhoneAccountHandle(new ComponentName(PACKAGE_2, COMPONENT_NAME), "5678", 1056 users.get(1)), "l2").build(); 1057 1058 1059 registerAndEnableAccount(pa1); 1060 registerAndEnableAccount(pa2); 1061 1062 assertEquals(1, mRegistrar.getAllPhoneAccounts(users.get(0)).size()); 1063 assertEquals(1, mRegistrar.getAllPhoneAccounts(users.get(1)).size()); 1064 1065 1066 // WHEN 1067 when(mContext.getPackageManager().getPackageInfo(PACKAGE_1, 0)) 1068 .thenReturn(new PackageInfo()); 1069 1070 when(mContext.getPackageManager().getPackageInfo(PACKAGE_2, 0)) 1071 .thenThrow(new PackageManager.NameNotFoundException()); 1072 1073 when(UserManager.get(mContext).getSerialNumberForUser(users.get(0))) 1074 .thenReturn(0L); 1075 1076 when(UserManager.get(mContext).getSerialNumberForUser(users.get(1))) 1077 .thenReturn(-1L); 1078 1079 // THEN 1080 int deletedAccounts = mRegistrar.cleanupOrphanedPhoneAccounts(); 1081 assertEquals(1, deletedAccounts); 1082 } 1083 1084 @Test testGetSimPhoneAccountsFromSimCallManager()1085 public void testGetSimPhoneAccountsFromSimCallManager() throws Exception { 1086 // Register the SIM PhoneAccounts 1087 mComponentContextFixture.addConnectionService( 1088 makeQuickConnectionServiceComponentName(), Mockito.mock(IConnectionService.class)); 1089 PhoneAccount sim1Account = makeQuickSimAccount(1); 1090 PhoneAccountHandle sim1Handle = sim1Account.getAccountHandle(); 1091 registerAndEnableAccount(sim1Account); 1092 PhoneAccount sim2Account = makeQuickSimAccount(2); 1093 PhoneAccountHandle sim2Handle = sim2Account.getAccountHandle(); 1094 registerAndEnableAccount(sim2Account); 1095 1096 assertEquals( 1097 List.of(sim1Handle, sim2Handle), mRegistrar.getSimPhoneAccountsOfCurrentUser()); 1098 1099 // Set up the SIM call manager app + carrier configs 1100 ComponentName simCallManagerComponent = 1101 new ComponentName("com.carrier.app", "CarrierConnectionService"); 1102 PhoneAccountHandle simCallManagerHandle = 1103 makeQuickAccountHandle(simCallManagerComponent, "sim-call-manager"); 1104 setSimCallManagerCarrierConfig( 1105 1, new ComponentName("com.other.carrier", "OtherConnectionService")); 1106 setSimCallManagerCarrierConfig(2, simCallManagerComponent); 1107 1108 // Since SIM 1 names another app, so we only get the handle for SIM 2 1109 assertEquals( 1110 List.of(sim2Handle), 1111 mRegistrar.getSimPhoneAccountsFromSimCallManager(simCallManagerHandle)); 1112 // We do exact component matching, not just package name matching 1113 assertEquals( 1114 List.of(), 1115 mRegistrar.getSimPhoneAccountsFromSimCallManager( 1116 makeQuickAccountHandle( 1117 new ComponentName("com.carrier.app", "SomeOtherUnrelatedService"), 1118 "same-pkg-but-diff-svc"))); 1119 1120 // Results are identical after we register the PhoneAccount 1121 mComponentContextFixture.addConnectionService( 1122 simCallManagerComponent, Mockito.mock(IConnectionService.class)); 1123 PhoneAccount simCallManagerAccount = 1124 new PhoneAccount.Builder(simCallManagerHandle, "SIM call manager") 1125 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 1126 .build(); 1127 mRegistrar.registerPhoneAccount(simCallManagerAccount); 1128 assertEquals( 1129 List.of(sim2Handle), 1130 mRegistrar.getSimPhoneAccountsFromSimCallManager(simCallManagerHandle)); 1131 } 1132 1133 @Test testMaybeNotifyTelephonyForVoiceServiceState()1134 public void testMaybeNotifyTelephonyForVoiceServiceState() throws Exception { 1135 // Register the SIM PhoneAccounts 1136 mComponentContextFixture.addConnectionService( 1137 makeQuickConnectionServiceComponentName(), Mockito.mock(IConnectionService.class)); 1138 PhoneAccount sim1Account = makeQuickSimAccount(1); 1139 registerAndEnableAccount(sim1Account); 1140 PhoneAccount sim2Account = makeQuickSimAccount(2); 1141 registerAndEnableAccount(sim2Account); 1142 // Telephony is notified by default when new SIM accounts are registered 1143 verify(mComponentContextFixture.getTelephonyManager(), times(2)) 1144 .setVoiceServiceStateOverride(false); 1145 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1146 1147 // Set up the SIM call manager app + carrier configs 1148 ComponentName simCallManagerComponent = 1149 new ComponentName("com.carrier.app", "CarrierConnectionService"); 1150 PhoneAccountHandle simCallManagerHandle = 1151 makeQuickAccountHandle(simCallManagerComponent, "sim-call-manager"); 1152 mComponentContextFixture.addConnectionService( 1153 simCallManagerComponent, Mockito.mock(IConnectionService.class)); 1154 setSimCallManagerCarrierConfig(1, simCallManagerComponent); 1155 setSimCallManagerCarrierConfig(2, simCallManagerComponent); 1156 1157 // When the SIM call manager is registered without the SUPPORTS capability, telephony is 1158 // still notified for consistency (e.g. runtime capability removal + re-registration). 1159 PhoneAccount simCallManagerAccount = 1160 new PhoneAccount.Builder(simCallManagerHandle, "SIM call manager") 1161 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 1162 .build(); 1163 mRegistrar.registerPhoneAccount(simCallManagerAccount); 1164 verify(mComponentContextFixture.getTelephonyManager(), times(2)) 1165 .setVoiceServiceStateOverride(false); 1166 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1167 1168 // Adding the SUPPORTS capability causes the SIMs to get notified with false again for 1169 // consistency purposes 1170 simCallManagerAccount = 1171 copyPhoneAccountAndAddCapabilities( 1172 simCallManagerAccount, 1173 PhoneAccount.CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS); 1174 mRegistrar.registerPhoneAccount(simCallManagerAccount); 1175 verify(mComponentContextFixture.getTelephonyManager(), times(2)) 1176 .setVoiceServiceStateOverride(false); 1177 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1178 1179 // Adding the AVAILABLE capability updates the SIMs again, this time with hasService = true 1180 simCallManagerAccount = 1181 copyPhoneAccountAndAddCapabilities( 1182 simCallManagerAccount, PhoneAccount.CAPABILITY_VOICE_CALLING_AVAILABLE); 1183 mRegistrar.registerPhoneAccount(simCallManagerAccount); 1184 verify(mComponentContextFixture.getTelephonyManager(), times(2)) 1185 .setVoiceServiceStateOverride(true); 1186 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1187 1188 // Removing a SIM account does nothing, regardless of SIM call manager capabilities 1189 mRegistrar.unregisterPhoneAccount(sim1Account.getAccountHandle()); 1190 verify(mComponentContextFixture.getTelephonyManager(), never()) 1191 .setVoiceServiceStateOverride(anyBoolean()); 1192 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1193 1194 // Adding a SIM account while a SIM call manager with both capabilities is registered causes 1195 // a call to telephony with hasService = true 1196 mRegistrar.registerPhoneAccount(sim1Account); 1197 verify(mComponentContextFixture.getTelephonyManager(), times(1)) 1198 .setVoiceServiceStateOverride(true); 1199 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1200 1201 // Removing the SIM call manager while it has both capabilities causes a call to telephony 1202 // with hasService = false 1203 mRegistrar.unregisterPhoneAccount(simCallManagerHandle); 1204 verify(mComponentContextFixture.getTelephonyManager(), times(2)) 1205 .setVoiceServiceStateOverride(false); 1206 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1207 1208 // Removing the SIM call manager while it has the SUPPORTS capability but not AVAILABLE 1209 // still causes a call to telephony with hasService = false for consistency 1210 simCallManagerAccount = 1211 copyPhoneAccountAndRemoveCapabilities( 1212 simCallManagerAccount, PhoneAccount.CAPABILITY_VOICE_CALLING_AVAILABLE); 1213 mRegistrar.registerPhoneAccount(simCallManagerAccount); 1214 clearInvocations(mComponentContextFixture.getTelephonyManager()); // from re-registration 1215 mRegistrar.unregisterPhoneAccount(simCallManagerHandle); 1216 verify(mComponentContextFixture.getTelephonyManager(), times(2)) 1217 .setVoiceServiceStateOverride(false); 1218 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1219 1220 // Finally, removing the SIM call manager while it has neither capability still causes a 1221 // call to telephony with hasService = false for consistency 1222 simCallManagerAccount = 1223 copyPhoneAccountAndRemoveCapabilities( 1224 simCallManagerAccount, 1225 PhoneAccount.CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS); 1226 mRegistrar.registerPhoneAccount(simCallManagerAccount); 1227 clearInvocations(mComponentContextFixture.getTelephonyManager()); // from re-registration 1228 mRegistrar.unregisterPhoneAccount(simCallManagerHandle); 1229 verify(mComponentContextFixture.getTelephonyManager(), times(2)) 1230 .setVoiceServiceStateOverride(false); 1231 clearInvocations(mComponentContextFixture.getTelephonyManager()); 1232 } 1233 1234 /** 1235 * Test PhoneAccountHandle Migration Logic. 1236 */ 1237 @Test testPhoneAccountMigration()1238 public void testPhoneAccountMigration() throws Exception { 1239 PhoneAccountRegistrar.State testState = makeQuickStateWithTelephonyPhoneAccountHandle(); 1240 final int mTestPhoneAccountHandleSubIdInt = 123; 1241 // Mock SubscriptionManager 1242 SubscriptionInfo subscriptionInfo = new SubscriptionInfo( 1243 mTestPhoneAccountHandleSubIdInt, "id0", 1, "a", "b", 1, 1, "test", 1244 1, null, null, null, null, false, null, null); 1245 List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>(); 1246 subscriptionInfoList.add(subscriptionInfo); 1247 when(mSubscriptionManager.getAllSubscriptionInfoList()).thenReturn(subscriptionInfoList); 1248 mRegistrar.migratePhoneAccountHandle(testState); 1249 Collection<DefaultPhoneAccountHandle> defaultPhoneAccountHandles 1250 = testState.defaultOutgoingAccountHandles.values(); 1251 DefaultPhoneAccountHandle defaultPhoneAccountHandle 1252 = defaultPhoneAccountHandles.iterator().next(); 1253 assertEquals(Integer.toString(mTestPhoneAccountHandleSubIdInt), 1254 defaultPhoneAccountHandle.phoneAccountHandle.getId()); 1255 } 1256 makeQuickConnectionServiceComponentName()1257 private static ComponentName makeQuickConnectionServiceComponentName() { 1258 return new ComponentName( 1259 "com.android.server.telecom.tests", 1260 "com.android.server.telecom.tests.MockConnectionService"); 1261 } 1262 makeQuickAccountHandle(String id)1263 private static PhoneAccountHandle makeQuickAccountHandle(String id) { 1264 return makeQuickAccountHandle(makeQuickConnectionServiceComponentName(), id); 1265 } 1266 makeQuickAccountHandle(ComponentName name, String id)1267 private static PhoneAccountHandle makeQuickAccountHandle(ComponentName name, String id) { 1268 return new PhoneAccountHandle(name, id, Process.myUserHandle()); 1269 } 1270 makeQuickAccountBuilder(String id, int idx)1271 private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) { 1272 return new PhoneAccount.Builder( 1273 makeQuickAccountHandle(id), 1274 "label" + idx); 1275 } 1276 copyPhoneAccountAndOverrideCapabilities( PhoneAccount base, int newCapabilities)1277 private static PhoneAccount copyPhoneAccountAndOverrideCapabilities( 1278 PhoneAccount base, int newCapabilities) { 1279 return base.toBuilder().setCapabilities(newCapabilities).build(); 1280 } 1281 copyPhoneAccountAndAddCapabilities( PhoneAccount base, int capabilitiesToAdd)1282 private static PhoneAccount copyPhoneAccountAndAddCapabilities( 1283 PhoneAccount base, int capabilitiesToAdd) { 1284 return copyPhoneAccountAndOverrideCapabilities( 1285 base, base.getCapabilities() | capabilitiesToAdd); 1286 } 1287 copyPhoneAccountAndRemoveCapabilities( PhoneAccount base, int capabilitiesToRemove)1288 private static PhoneAccount copyPhoneAccountAndRemoveCapabilities( 1289 PhoneAccount base, int capabilitiesToRemove) { 1290 return copyPhoneAccountAndOverrideCapabilities( 1291 base, base.getCapabilities() & ~capabilitiesToRemove); 1292 } 1293 makeQuickAccount(String id, int idx)1294 private PhoneAccount makeQuickAccount(String id, int idx) { 1295 return makeQuickAccountBuilder(id, idx) 1296 .setAddress(Uri.parse("http://foo.com/" + idx)) 1297 .setSubscriptionAddress(Uri.parse("tel:555-000" + idx)) 1298 .setCapabilities(idx) 1299 .setIcon(Icon.createWithResource( 1300 "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call)) 1301 .setShortDescription("desc" + idx) 1302 .setIsEnabled(true) 1303 .build(); 1304 } 1305 1306 /** 1307 * Similar to {@link #makeQuickAccount}, but also hooks up {@code TelephonyManager} so that it 1308 * returns {@code simId} as the account's subscriptionId. 1309 */ makeQuickSimAccount(int simId)1310 private PhoneAccount makeQuickSimAccount(int simId) { 1311 PhoneAccount simAccount = 1312 makeQuickAccountBuilder("sim" + simId, simId) 1313 .setCapabilities( 1314 PhoneAccount.CAPABILITY_CALL_PROVIDER 1315 | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 1316 .setIsEnabled(true) 1317 .build(); 1318 when(mComponentContextFixture 1319 .getTelephonyManager() 1320 .getSubscriptionId(simAccount.getAccountHandle())) 1321 .thenReturn(simId); 1322 // mComponentContextFixture already sets up the createForSubscriptionId self-reference 1323 when(mComponentContextFixture 1324 .getTelephonyManager() 1325 .createForPhoneAccountHandle(simAccount.getAccountHandle())) 1326 .thenReturn(mComponentContextFixture.getTelephonyManager()); 1327 return simAccount; 1328 } 1329 1330 /** 1331 * Hooks up carrier config to point to {@code simCallManagerComponent} for the given {@code 1332 * subscriptionId}. 1333 */ setSimCallManagerCarrierConfig( int subscriptionId, @Nullable ComponentName simCallManagerComponent)1334 private void setSimCallManagerCarrierConfig( 1335 int subscriptionId, @Nullable ComponentName simCallManagerComponent) { 1336 PersistableBundle config = new PersistableBundle(); 1337 config.putString( 1338 CarrierConfigManager.KEY_DEFAULT_SIM_CALL_MANAGER_STRING, 1339 simCallManagerComponent != null ? simCallManagerComponent.flattenToString() : null); 1340 when(mComponentContextFixture.getCarrierConfigManager().getConfigForSubId(subscriptionId)) 1341 .thenReturn(config); 1342 } 1343 roundTripPhoneAccount(PhoneAccount original)1344 private static void roundTripPhoneAccount(PhoneAccount original) throws Exception { 1345 PhoneAccount copy = null; 1346 1347 { 1348 Parcel parcel = Parcel.obtain(); 1349 parcel.writeParcelable(original, 0); 1350 parcel.setDataPosition(0); 1351 copy = parcel.readParcelable(PhoneAccountRegistrarTest.class.getClassLoader()); 1352 parcel.recycle(); 1353 } 1354 1355 assertPhoneAccountEquals(original, copy); 1356 } 1357 roundTripXml( Object self, T input, PhoneAccountRegistrar.XmlSerialization<T> xml, Context context)1358 private static <T> T roundTripXml( 1359 Object self, 1360 T input, 1361 PhoneAccountRegistrar.XmlSerialization<T> xml, 1362 Context context) 1363 throws Exception { 1364 Log.d(self, "Input = %s", input); 1365 1366 byte[] data; 1367 { 1368 XmlSerializer serializer = new FastXmlSerializer(); 1369 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1370 serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); 1371 xml.writeToXml(input, serializer, context); 1372 serializer.flush(); 1373 data = baos.toByteArray(); 1374 } 1375 1376 Log.i(self, "====== XML data ======\n%s", new String(data)); 1377 1378 T result = null; 1379 { 1380 XmlPullParser parser = Xml.newPullParser(); 1381 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(data)), null); 1382 parser.nextTag(); 1383 result = xml.readFromXml(parser, MAX_VERSION, context); 1384 } 1385 1386 Log.i(self, "result = " + result); 1387 1388 return result; 1389 } 1390 assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b)1391 private static void assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b) { 1392 if (a != b) { 1393 assertEquals( 1394 a.getComponentName().getPackageName(), 1395 b.getComponentName().getPackageName()); 1396 assertEquals( 1397 a.getComponentName().getClassName(), 1398 b.getComponentName().getClassName()); 1399 assertEquals(a.getId(), b.getId()); 1400 } 1401 } 1402 assertIconEquals(Icon a, Icon b)1403 private static void assertIconEquals(Icon a, Icon b) { 1404 if (a != b) { 1405 if (a != null && b != null) { 1406 assertEquals(a.toString(), b.toString()); 1407 } else { 1408 fail("Icons not equal: " + a + ", " + b); 1409 } 1410 } 1411 } 1412 assertDefaultPhoneAccountHandleEquals(DefaultPhoneAccountHandle a, DefaultPhoneAccountHandle b)1413 private static void assertDefaultPhoneAccountHandleEquals(DefaultPhoneAccountHandle a, 1414 DefaultPhoneAccountHandle b) { 1415 if (a != b) { 1416 if (a!= null && b != null) { 1417 assertEquals(a.userHandle, b.userHandle); 1418 assertPhoneAccountHandleEquals(a.phoneAccountHandle, b.phoneAccountHandle); 1419 } else { 1420 fail("Default phone account handles are not equal: " + a + ", " + b); 1421 } 1422 } 1423 } 1424 assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b)1425 private static void assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b) { 1426 if (a != b) { 1427 if (a != null && b != null) { 1428 assertPhoneAccountHandleEquals(a.getAccountHandle(), b.getAccountHandle()); 1429 assertEquals(a.getAddress(), b.getAddress()); 1430 assertEquals(a.getSubscriptionAddress(), b.getSubscriptionAddress()); 1431 assertEquals(a.getCapabilities(), b.getCapabilities()); 1432 assertIconEquals(a.getIcon(), b.getIcon()); 1433 assertEquals(a.getHighlightColor(), b.getHighlightColor()); 1434 assertEquals(a.getLabel(), b.getLabel()); 1435 assertEquals(a.getShortDescription(), b.getShortDescription()); 1436 assertEquals(a.getSupportedUriSchemes(), b.getSupportedUriSchemes()); 1437 assertBundlesEqual(a.getExtras(), b.getExtras()); 1438 assertEquals(a.isEnabled(), b.isEnabled()); 1439 } else { 1440 fail("Phone accounts not equal: " + a + ", " + b); 1441 } 1442 } 1443 } 1444 assertBundlesEqual(Bundle a, Bundle b)1445 private static void assertBundlesEqual(Bundle a, Bundle b) { 1446 if (a == null && b == null) { 1447 return; 1448 } 1449 1450 assertNotNull(a); 1451 assertNotNull(b); 1452 Set<String> keySetA = a.keySet(); 1453 Set<String> keySetB = b.keySet(); 1454 1455 assertTrue("Bundle keys not the same", keySetA.containsAll(keySetB)); 1456 assertTrue("Bundle keys not the same", keySetB.containsAll(keySetA)); 1457 1458 for (String keyA : keySetA) { 1459 assertEquals("Bundle value not the same", a.get(keyA), b.get(keyA)); 1460 } 1461 } 1462 assertStateEquals( PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b)1463 private static void assertStateEquals( 1464 PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b) { 1465 assertEquals(a.defaultOutgoingAccountHandles.size(), 1466 b.defaultOutgoingAccountHandles.size()); 1467 for (Map.Entry<UserHandle, DefaultPhoneAccountHandle> e : 1468 a.defaultOutgoingAccountHandles.entrySet()) { 1469 assertDefaultPhoneAccountHandleEquals(e.getValue(), 1470 b.defaultOutgoingAccountHandles.get(e.getKey())); 1471 } 1472 assertEquals(a.accounts.size(), b.accounts.size()); 1473 for (int i = 0; i < a.accounts.size(); i++) { 1474 assertPhoneAccountEquals(a.accounts.get(i), b.accounts.get(i)); 1475 } 1476 } 1477 makeQuickStateWithTelephonyPhoneAccountHandle()1478 private PhoneAccountRegistrar.State makeQuickStateWithTelephonyPhoneAccountHandle() { 1479 PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State(); 1480 s.accounts.add(makeQuickAccount("id0", 0)); 1481 s.accounts.add(makeQuickAccount("id1", 1)); 1482 s.accounts.add(makeQuickAccount("id2", 2)); 1483 PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(new ComponentName( 1484 "com.android.phone", 1485 "com.android.services.telephony.TelephonyConnectionService"), "id0"); 1486 UserHandle userHandle = phoneAccountHandle.getUserHandle(); 1487 when(UserManager.get(mContext).getSerialNumberForUser(userHandle)) 1488 .thenReturn(0L); 1489 when(UserManager.get(mContext).getUserForSerialNumber(0L)) 1490 .thenReturn(userHandle); 1491 s.defaultOutgoingAccountHandles 1492 .put(userHandle, new DefaultPhoneAccountHandle(userHandle, phoneAccountHandle, 1493 "testGroup")); 1494 return s; 1495 } 1496 makeQuickState()1497 private PhoneAccountRegistrar.State makeQuickState() { 1498 PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State(); 1499 s.accounts.add(makeQuickAccount("id0", 0)); 1500 s.accounts.add(makeQuickAccount("id1", 1)); 1501 s.accounts.add(makeQuickAccount("id2", 2)); 1502 PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle( 1503 new ComponentName("pkg0", "cls0"), "id0"); 1504 UserHandle userHandle = phoneAccountHandle.getUserHandle(); 1505 when(UserManager.get(mContext).getSerialNumberForUser(userHandle)) 1506 .thenReturn(0L); 1507 when(UserManager.get(mContext).getUserForSerialNumber(0L)) 1508 .thenReturn(userHandle); 1509 s.defaultOutgoingAccountHandles 1510 .put(userHandle, new DefaultPhoneAccountHandle(userHandle, phoneAccountHandle, 1511 "testGroup")); 1512 return s; 1513 } 1514 } 1515