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 android.content.ComponentName; 20 import android.content.Context; 21 import android.graphics.BitmapFactory; 22 import android.graphics.Rect; 23 import android.graphics.drawable.Icon; 24 import android.net.Uri; 25 import android.os.Bundle; 26 import android.os.Parcel; 27 import android.os.Process; 28 import android.os.UserHandle; 29 import android.os.UserManager; 30 import android.support.test.InstrumentationRegistry; 31 import android.telecom.Log; 32 import android.telecom.PhoneAccount; 33 import android.telecom.PhoneAccountHandle; 34 import android.telecom.TelecomManager; 35 import android.test.suitebuilder.annotation.MediumTest; 36 import android.util.Xml; 37 38 import com.android.internal.telecom.IConnectionService; 39 import com.android.internal.util.FastXmlSerializer; 40 import com.android.server.telecom.DefaultDialerCache; 41 import com.android.server.telecom.PhoneAccountRegistrar; 42 import com.android.server.telecom.PhoneAccountRegistrar.DefaultPhoneAccountHandle; 43 44 import org.junit.After; 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.junit.runners.JUnit4; 49 import org.mockito.Mock; 50 import org.mockito.Mockito; 51 import org.mockito.MockitoAnnotations; 52 import org.xmlpull.v1.XmlPullParser; 53 import org.xmlpull.v1.XmlSerializer; 54 55 import java.io.BufferedInputStream; 56 import java.io.BufferedOutputStream; 57 import java.io.ByteArrayInputStream; 58 import java.io.ByteArrayOutputStream; 59 import java.io.File; 60 import java.util.Arrays; 61 import java.util.List; 62 import java.util.Map; 63 import java.util.Set; 64 65 import static org.junit.Assert.assertEquals; 66 import static org.junit.Assert.assertFalse; 67 import static org.junit.Assert.assertNotNull; 68 import static org.junit.Assert.assertNull; 69 import static org.junit.Assert.assertTrue; 70 import static org.junit.Assert.fail; 71 import static org.mockito.Matchers.anyInt; 72 import static org.mockito.Matchers.anyString; 73 import static org.mockito.Mockito.when; 74 75 @RunWith(JUnit4.class) 76 public class PhoneAccountRegistrarTest extends TelecomTestCase { 77 78 private static final int MAX_VERSION = Integer.MAX_VALUE; 79 private static final String FILE_NAME = "phone-account-registrar-test-1223.xml"; 80 private static final String TEST_LABEL = "right"; 81 private PhoneAccountRegistrar mRegistrar; 82 @Mock private TelecomManager mTelecomManager; 83 @Mock private DefaultDialerCache mDefaultDialerCache; 84 @Mock private PhoneAccountRegistrar.AppLabelProxy mAppLabelProxy; 85 86 @Override 87 @Before 88 public void setUp() throws Exception { 89 super.setUp(); 90 MockitoAnnotations.initMocks(this); 91 mComponentContextFixture.setTelecomManager(mTelecomManager); 92 new File( 93 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(), 94 FILE_NAME) 95 .delete(); 96 when(mDefaultDialerCache.getDefaultDialerApplication(anyInt())) 97 .thenReturn("com.android.dialer"); 98 when(mAppLabelProxy.getAppLabel(anyString())) 99 .thenReturn(TEST_LABEL); 100 mRegistrar = new PhoneAccountRegistrar( 101 mComponentContextFixture.getTestDouble().getApplicationContext(), 102 FILE_NAME, mDefaultDialerCache, mAppLabelProxy); 103 } 104 105 @Override 106 @After 107 public void tearDown() throws Exception { 108 mRegistrar = null; 109 new File( 110 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(), 111 FILE_NAME) 112 .delete(); 113 super.tearDown(); 114 } 115 116 @MediumTest 117 @Test 118 public void testPhoneAccountHandle() throws Exception { 119 PhoneAccountHandle input = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0"); 120 PhoneAccountHandle result = roundTripXml(this, input, 121 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 122 assertPhoneAccountHandleEquals(input, result); 123 124 PhoneAccountHandle inputN = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), null); 125 PhoneAccountHandle resultN = roundTripXml(this, inputN, 126 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 127 Log.i(this, "inputN = %s, resultN = %s", inputN, resultN); 128 assertPhoneAccountHandleEquals(inputN, resultN); 129 } 130 131 @MediumTest 132 @Test 133 public void testPhoneAccount() throws Exception { 134 Bundle testBundle = new Bundle(); 135 testBundle.putInt("EXTRA_INT_1", 1); 136 testBundle.putInt("EXTRA_INT_100", 100); 137 testBundle.putBoolean("EXTRA_BOOL_TRUE", true); 138 testBundle.putBoolean("EXTRA_BOOL_FALSE", false); 139 testBundle.putString("EXTRA_STR1", "Hello"); 140 testBundle.putString("EXTRA_STR2", "There"); 141 142 PhoneAccount input = makeQuickAccountBuilder("id0", 0) 143 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 144 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 145 .setExtras(testBundle) 146 .setIsEnabled(true) 147 .build(); 148 PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml, 149 mContext); 150 151 assertPhoneAccountEquals(input, result); 152 } 153 154 @MediumTest 155 @Test 156 public void testDefaultPhoneAccountHandleEmptyGroup() throws Exception { 157 DefaultPhoneAccountHandle input = new DefaultPhoneAccountHandle(Process.myUserHandle(), 158 makeQuickAccountHandle("i1"), ""); 159 when(UserManager.get(mContext).getSerialNumberForUser(input.userHandle)) 160 .thenReturn(0L); 161 when(UserManager.get(mContext).getUserForSerialNumber(0L)) 162 .thenReturn(input.userHandle); 163 DefaultPhoneAccountHandle result = roundTripXml(this, input, 164 PhoneAccountRegistrar.sDefaultPhoneAcountHandleXml, mContext); 165 166 assertDefaultPhoneAccountHandleEquals(input, result); 167 } 168 169 /** 170 * Test to ensure non-supported values 171 * @throws Exception 172 */ 173 @MediumTest 174 @Test 175 public void testPhoneAccountExtrasEdge() throws Exception { 176 Bundle testBundle = new Bundle(); 177 // Ensure null values for string are not persisted. 178 testBundle.putString("EXTRA_STR2", null); 179 // 180 181 // Ensure unsupported data types are not persisted. 182 testBundle.putShort("EXTRA_SHORT", (short) 2); 183 testBundle.putByte("EXTRA_BYTE", (byte) 1); 184 testBundle.putParcelable("EXTRA_PARC", new Rect(1, 1, 1, 1)); 185 // Put in something valid so the bundle exists. 186 testBundle.putString("EXTRA_OK", "OK"); 187 188 PhoneAccount input = makeQuickAccountBuilder("id0", 0) 189 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 190 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 191 .setExtras(testBundle) 192 .build(); 193 PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml, 194 mContext); 195 196 Bundle extras = result.getExtras(); 197 assertFalse(extras.keySet().contains("EXTRA_STR2")); 198 assertFalse(extras.keySet().contains("EXTRA_SHORT")); 199 assertFalse(extras.keySet().contains("EXTRA_BYTE")); 200 assertFalse(extras.keySet().contains("EXTRA_PARC")); 201 } 202 203 @MediumTest 204 @Test 205 public void testState() throws Exception { 206 PhoneAccountRegistrar.State input = makeQuickState(); 207 PhoneAccountRegistrar.State result = roundTripXml(this, input, 208 PhoneAccountRegistrar.sStateXml, 209 mContext); 210 assertStateEquals(input, result); 211 } 212 213 private void registerAndEnableAccount(PhoneAccount account) { 214 mRegistrar.registerPhoneAccount(account); 215 mRegistrar.enablePhoneAccount(account.getAccountHandle(), true); 216 } 217 218 @MediumTest 219 @Test 220 public void testAccounts() throws Exception { 221 int i = 0; 222 223 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 224 Mockito.mock(IConnectionService.class)); 225 226 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 227 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 228 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 229 .build()); 230 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 231 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 232 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 233 .build()); 234 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 235 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 236 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 237 .build()); 238 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 239 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 240 .build()); 241 242 assertEquals(4, mRegistrar.getAllPhoneAccountsOfCurrentUser().size()); 243 assertEquals(3, mRegistrar.getCallCapablePhoneAccountsOfCurrentUser(null, false).size()); 244 assertEquals(null, mRegistrar.getSimCallManagerOfCurrentUser()); 245 assertEquals(null, mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 246 PhoneAccount.SCHEME_TEL)); 247 } 248 249 @MediumTest 250 @Test 251 public void testSimCallManager() throws Exception { 252 // TODO 253 } 254 255 @MediumTest 256 @Test 257 public void testDefaultOutgoing() throws Exception { 258 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 259 Mockito.mock(IConnectionService.class)); 260 261 // By default, there is no default outgoing account (nothing has been registered) 262 assertNull( 263 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 264 265 // Register one tel: account 266 PhoneAccountHandle telAccount = makeQuickAccountHandle("tel_acct"); 267 registerAndEnableAccount(new PhoneAccount.Builder(telAccount, "tel_acct") 268 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 269 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 270 .build()); 271 PhoneAccountHandle defaultAccount = 272 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 273 assertEquals(telAccount, defaultAccount); 274 275 // Add a SIP account, make sure tel: doesn't change 276 PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct"); 277 registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct") 278 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 279 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP) 280 .build()); 281 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 282 PhoneAccount.SCHEME_SIP); 283 assertEquals(sipAccount, defaultAccount); 284 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 285 PhoneAccount.SCHEME_TEL); 286 assertEquals(telAccount, defaultAccount); 287 288 // Add a connection manager, make sure tel: doesn't change 289 PhoneAccountHandle connectionManager = makeQuickAccountHandle("mgr_acct"); 290 registerAndEnableAccount(new PhoneAccount.Builder(connectionManager, "mgr_acct") 291 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 292 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 293 .build()); 294 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 295 PhoneAccount.SCHEME_TEL); 296 assertEquals(telAccount, defaultAccount); 297 298 // Unregister the tel: account, make sure there is no tel: default now. 299 mRegistrar.unregisterPhoneAccount(telAccount); 300 assertNull( 301 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 302 } 303 304 @MediumTest 305 @Test 306 public void testReplacePhoneAccountByGroup() throws Exception { 307 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 308 Mockito.mock(IConnectionService.class)); 309 310 // By default, there is no default outgoing account (nothing has been registered) 311 assertNull( 312 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 313 314 // Register one tel: account 315 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 316 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 317 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 318 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 319 .setGroupId("testGroup") 320 .build()); 321 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 322 PhoneAccountHandle defaultAccount = 323 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 324 assertEquals(telAccount1, defaultAccount); 325 326 // Add call capable SIP account, make sure tel: doesn't change 327 PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct"); 328 registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct") 329 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 330 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 331 .build()); 332 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 333 PhoneAccount.SCHEME_TEL); 334 assertEquals(telAccount1, defaultAccount); 335 336 // Replace tel: account with another in the same Group 337 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 338 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 339 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 340 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 341 .setGroupId("testGroup") 342 .build()); 343 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 344 PhoneAccount.SCHEME_TEL); 345 assertEquals(telAccount2, defaultAccount); 346 assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 347 } 348 349 @MediumTest 350 @Test 351 public void testAddSameDefault() throws Exception { 352 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 353 Mockito.mock(IConnectionService.class)); 354 355 // By default, there is no default outgoing account (nothing has been registered) 356 assertNull( 357 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 358 359 // Register one tel: account 360 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 361 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 362 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 363 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 364 .setGroupId("testGroup") 365 .build()); 366 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 367 PhoneAccountHandle defaultAccount = 368 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 369 assertEquals(telAccount1, defaultAccount); 370 mRegistrar.unregisterPhoneAccount(telAccount1); 371 372 // Register Emergency Account and unregister 373 PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct"); 374 registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct") 375 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 376 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 377 .build()); 378 defaultAccount = 379 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 380 assertNull(defaultAccount); 381 mRegistrar.unregisterPhoneAccount(emerAccount); 382 383 // Re-register the same account and make sure the default is in place 384 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 385 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 386 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 387 .setGroupId("testGroup") 388 .build()); 389 defaultAccount = 390 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 391 assertEquals(telAccount1, defaultAccount); 392 } 393 394 @MediumTest 395 @Test 396 public void testAddSameGroup() throws Exception { 397 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 398 Mockito.mock(IConnectionService.class)); 399 400 // By default, there is no default outgoing account (nothing has been registered) 401 assertNull( 402 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 403 404 // Register one tel: account 405 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 406 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 407 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 408 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 409 .setGroupId("testGroup") 410 .build()); 411 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 412 PhoneAccountHandle defaultAccount = 413 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 414 assertEquals(telAccount1, defaultAccount); 415 mRegistrar.unregisterPhoneAccount(telAccount1); 416 417 // Register Emergency Account and unregister 418 PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct"); 419 registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct") 420 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 421 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 422 .build()); 423 defaultAccount = 424 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 425 assertNull(defaultAccount); 426 mRegistrar.unregisterPhoneAccount(emerAccount); 427 428 // Re-register a new account with the same group 429 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 430 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 431 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 432 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 433 .setGroupId("testGroup") 434 .build()); 435 defaultAccount = 436 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 437 assertEquals(telAccount2, defaultAccount); 438 } 439 440 @MediumTest 441 @Test 442 public void testAddSameGroupButDifferentComponent() throws Exception { 443 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 444 Mockito.mock(IConnectionService.class)); 445 446 // By default, there is no default outgoing account (nothing has been registered) 447 assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 448 PhoneAccount.SCHEME_TEL)); 449 450 // Register one tel: account 451 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 452 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 453 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 454 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 455 .setGroupId("testGroup") 456 .build()); 457 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 458 PhoneAccountHandle defaultAccount = 459 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 460 assertEquals(telAccount1, defaultAccount); 461 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 462 463 // Register a new account with the same group, but different Component, so don't replace 464 // Default 465 PhoneAccountHandle telAccount2 = makeQuickAccountHandle( 466 new ComponentName("other1", "other2"), "tel_acct2"); 467 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 468 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 469 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 470 .setGroupId("testGroup") 471 .build()); 472 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount2)); 473 474 defaultAccount = 475 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 476 assertEquals(telAccount1, defaultAccount); 477 } 478 479 @MediumTest 480 @Test 481 public void testAddSameGroupButDifferentComponent2() throws Exception { 482 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 483 Mockito.mock(IConnectionService.class)); 484 485 // By default, there is no default outgoing account (nothing has been registered) 486 assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 487 PhoneAccount.SCHEME_TEL)); 488 489 // Register first tel: account 490 PhoneAccountHandle telAccount1 = makeQuickAccountHandle( 491 new ComponentName("other1", "other2"), "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 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 498 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 499 500 // Register second account with the same group, but a second Component, so don't replace 501 // Default 502 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 503 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 504 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 505 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 506 .setGroupId("testGroup") 507 .build()); 508 509 PhoneAccountHandle defaultAccount = 510 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 511 assertEquals(telAccount1, defaultAccount); 512 513 // Register third account with the second component name, but same group id 514 PhoneAccountHandle telAccount3 = makeQuickAccountHandle("tel_acct3"); 515 registerAndEnableAccount(new PhoneAccount.Builder(telAccount3, "tel_acct3") 516 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 517 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 518 .setGroupId("testGroup") 519 .build()); 520 521 // Make sure that the default account is still the original PhoneAccount and that the 522 // second PhoneAccount with the second ComponentName was replaced by the third PhoneAccount 523 defaultAccount = 524 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 525 assertEquals(telAccount1, defaultAccount); 526 527 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 528 assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount2)); 529 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount3)); 530 } 531 532 @MediumTest 533 @Test 534 public void testPhoneAccountParceling() throws Exception { 535 PhoneAccountHandle handle = makeQuickAccountHandle("foo"); 536 roundTripPhoneAccount(new PhoneAccount.Builder(handle, null).build()); 537 roundTripPhoneAccount(new PhoneAccount.Builder(handle, "foo").build()); 538 roundTripPhoneAccount( 539 new PhoneAccount.Builder(handle, "foo") 540 .setAddress(Uri.parse("tel:123456")) 541 .setCapabilities(23) 542 .setHighlightColor(0xf0f0f0) 543 .setIcon(Icon.createWithResource( 544 "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call)) 545 // TODO: set icon tint (0xfefefe) 546 .setShortDescription("short description") 547 .setSubscriptionAddress(Uri.parse("tel:2345678")) 548 .setSupportedUriSchemes(Arrays.asList("tel", "sip")) 549 .setGroupId("testGroup") 550 .build()); 551 roundTripPhoneAccount( 552 new PhoneAccount.Builder(handle, "foo") 553 .setAddress(Uri.parse("tel:123456")) 554 .setCapabilities(23) 555 .setHighlightColor(0xf0f0f0) 556 .setIcon(Icon.createWithBitmap( 557 BitmapFactory.decodeResource( 558 InstrumentationRegistry.getContext().getResources(), 559 R.drawable.stat_sys_phone_call))) 560 .setShortDescription("short description") 561 .setSubscriptionAddress(Uri.parse("tel:2345678")) 562 .setSupportedUriSchemes(Arrays.asList("tel", "sip")) 563 .setGroupId("testGroup") 564 .build()); 565 } 566 567 /** 568 * Tests ability to register a self-managed PhoneAccount; verifies that the user defined label 569 * is overridden. 570 * @throws Exception 571 */ 572 @MediumTest 573 @Test 574 public void testSelfManagedPhoneAccount() throws Exception { 575 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 576 Mockito.mock(IConnectionService.class)); 577 578 PhoneAccountHandle selfManagedHandle = makeQuickAccountHandle( 579 new ComponentName("self", "managed"), "selfie1"); 580 581 PhoneAccount selfManagedAccount = new PhoneAccount.Builder(selfManagedHandle, "Wrong") 582 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED) 583 .build(); 584 585 mRegistrar.registerPhoneAccount(selfManagedAccount); 586 587 PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(selfManagedHandle); 588 assertEquals(TEST_LABEL, registeredAccount.getLabel()); 589 } 590 591 /** 592 * Tests to ensure that when registering a self-managed PhoneAccount, it cannot also be defined 593 * as a call provider, connection manager, or sim subscription. 594 * @throws Exception 595 */ 596 @MediumTest 597 @Test 598 public void testSelfManagedCapabilityOverride() throws Exception { 599 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 600 Mockito.mock(IConnectionService.class)); 601 602 PhoneAccountHandle selfManagedHandle = makeQuickAccountHandle( 603 new ComponentName("self", "managed"), "selfie1"); 604 605 PhoneAccount selfManagedAccount = new PhoneAccount.Builder(selfManagedHandle, TEST_LABEL) 606 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED | 607 PhoneAccount.CAPABILITY_CALL_PROVIDER | 608 PhoneAccount.CAPABILITY_CONNECTION_MANAGER | 609 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 610 .build(); 611 612 mRegistrar.registerPhoneAccount(selfManagedAccount); 613 614 PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(selfManagedHandle); 615 assertEquals(PhoneAccount.CAPABILITY_SELF_MANAGED, registeredAccount.getCapabilities()); 616 } 617 618 @MediumTest 619 @Test 620 public void testSortSimFirst() throws Exception { 621 ComponentName componentA = new ComponentName("a", "a"); 622 ComponentName componentB = new ComponentName("b", "b"); 623 mComponentContextFixture.addConnectionService(componentA, 624 Mockito.mock(IConnectionService.class)); 625 mComponentContextFixture.addConnectionService(componentB, 626 Mockito.mock(IConnectionService.class)); 627 628 PhoneAccount simAccount = new PhoneAccount.Builder( 629 makeQuickAccountHandle(componentB, "2"), "2") 630 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 631 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 632 .setIsEnabled(true) 633 .build(); 634 635 PhoneAccount nonSimAccount = new PhoneAccount.Builder( 636 makeQuickAccountHandle(componentA, "1"), "1") 637 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 638 .setIsEnabled(true) 639 .build(); 640 641 registerAndEnableAccount(nonSimAccount); 642 registerAndEnableAccount(simAccount); 643 644 List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle()); 645 assertTrue(accounts.get(0).getLabel().toString().equals("2")); 646 assertTrue(accounts.get(1).getLabel().toString().equals("1")); 647 } 648 649 @MediumTest 650 @Test 651 public void testSortBySortOrder() throws Exception { 652 ComponentName componentA = new ComponentName("a", "a"); 653 ComponentName componentB = new ComponentName("b", "b"); 654 ComponentName componentC = new ComponentName("c", "c"); 655 mComponentContextFixture.addConnectionService(componentA, 656 Mockito.mock(IConnectionService.class)); 657 mComponentContextFixture.addConnectionService(componentB, 658 Mockito.mock(IConnectionService.class)); 659 mComponentContextFixture.addConnectionService(componentC, 660 Mockito.mock(IConnectionService.class)); 661 662 PhoneAccount account1 = new PhoneAccount.Builder( 663 makeQuickAccountHandle(componentA, "c"), "c") 664 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 665 .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "A")) 666 .build(); 667 668 PhoneAccount account2 = new PhoneAccount.Builder( 669 makeQuickAccountHandle(componentB, "b"), "b") 670 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 671 .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "B")) 672 .build(); 673 674 PhoneAccount account3 = new PhoneAccount.Builder( 675 makeQuickAccountHandle(componentC, "c"), "a") 676 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 677 .build(); 678 679 registerAndEnableAccount(account3); 680 registerAndEnableAccount(account2); 681 registerAndEnableAccount(account1); 682 683 List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle()); 684 assertTrue(accounts.get(0).getLabel().toString().equals("c")); 685 assertTrue(accounts.get(1).getLabel().toString().equals("b")); 686 assertTrue(accounts.get(2).getLabel().toString().equals("a")); 687 } 688 689 @MediumTest 690 @Test 691 public void testSortByLabel() throws Exception { 692 ComponentName componentA = new ComponentName("a", "a"); 693 ComponentName componentB = new ComponentName("b", "b"); 694 ComponentName componentC = new ComponentName("c", "c"); 695 mComponentContextFixture.addConnectionService(componentA, 696 Mockito.mock(IConnectionService.class)); 697 mComponentContextFixture.addConnectionService(componentB, 698 Mockito.mock(IConnectionService.class)); 699 mComponentContextFixture.addConnectionService(componentC, 700 Mockito.mock(IConnectionService.class)); 701 702 PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle(componentA, "c"), 703 "c") 704 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 705 .build(); 706 707 PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle(componentB, "b"), 708 "b") 709 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 710 .build(); 711 712 PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle(componentC, "a"), 713 "a") 714 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 715 .build(); 716 717 registerAndEnableAccount(account1); 718 registerAndEnableAccount(account2); 719 registerAndEnableAccount(account3); 720 721 List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle()); 722 assertTrue(accounts.get(0).getLabel().toString().equals("a")); 723 assertTrue(accounts.get(1).getLabel().toString().equals("b")); 724 assertTrue(accounts.get(2).getLabel().toString().equals("c")); 725 } 726 727 @MediumTest 728 @Test 729 public void testSortAll() throws Exception { 730 ComponentName componentA = new ComponentName("a", "a"); 731 ComponentName componentB = new ComponentName("b", "b"); 732 ComponentName componentC = new ComponentName("c", "c"); 733 ComponentName componentW = new ComponentName("w", "w"); 734 ComponentName componentX = new ComponentName("x", "x"); 735 ComponentName componentY = new ComponentName("y", "y"); 736 ComponentName componentZ = new ComponentName("z", "z"); 737 mComponentContextFixture.addConnectionService(componentA, 738 Mockito.mock(IConnectionService.class)); 739 mComponentContextFixture.addConnectionService(componentB, 740 Mockito.mock(IConnectionService.class)); 741 mComponentContextFixture.addConnectionService(componentC, 742 Mockito.mock(IConnectionService.class)); 743 mComponentContextFixture.addConnectionService(componentW, 744 Mockito.mock(IConnectionService.class)); 745 mComponentContextFixture.addConnectionService(componentX, 746 Mockito.mock(IConnectionService.class)); 747 mComponentContextFixture.addConnectionService(componentY, 748 Mockito.mock(IConnectionService.class)); 749 mComponentContextFixture.addConnectionService(componentZ, 750 Mockito.mock(IConnectionService.class)); 751 PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle( 752 makeQuickConnectionServiceComponentName(), "y"), "y") 753 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 754 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 755 .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "2")) 756 .build(); 757 758 PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle( 759 makeQuickConnectionServiceComponentName(), "z"), "z") 760 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 761 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 762 .setExtras(Bundle.forPair(PhoneAccount.EXTRA_SORT_ORDER, "1")) 763 .build(); 764 765 PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle( 766 makeQuickConnectionServiceComponentName(), "x"), "x") 767 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 768 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 769 .build(); 770 771 PhoneAccount account4 = new PhoneAccount.Builder(makeQuickAccountHandle( 772 makeQuickConnectionServiceComponentName(), "w"), "w") 773 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | 774 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) 775 .build(); 776 777 PhoneAccount account5 = new PhoneAccount.Builder(makeQuickAccountHandle( 778 makeQuickConnectionServiceComponentName(), "b"), "b") 779 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 780 .build(); 781 782 PhoneAccount account6 = new PhoneAccount.Builder(makeQuickAccountHandle( 783 makeQuickConnectionServiceComponentName(), "c"), "a") 784 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 785 .build(); 786 787 registerAndEnableAccount(account1); 788 registerAndEnableAccount(account2); 789 registerAndEnableAccount(account3); 790 registerAndEnableAccount(account4); 791 registerAndEnableAccount(account5); 792 registerAndEnableAccount(account6); 793 794 List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle()); 795 // Sim accts ordered by sort order first 796 assertTrue(accounts.get(0).getLabel().toString().equals("z")); 797 assertTrue(accounts.get(1).getLabel().toString().equals("y")); 798 799 // Sim accts with no sort order next 800 assertTrue(accounts.get(2).getLabel().toString().equals("w")); 801 assertTrue(accounts.get(3).getLabel().toString().equals("x")); 802 803 // Other accts sorted by label next 804 assertTrue(accounts.get(4).getLabel().toString().equals("a")); 805 assertTrue(accounts.get(5).getLabel().toString().equals("b")); 806 } 807 808 /** 809 * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle)} 810 * to ensure disabled accounts are filtered out of results when requested. 811 * @throws Exception 812 */ 813 @MediumTest 814 @Test 815 public void testGetByEnabledState() throws Exception { 816 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 817 Mockito.mock(IConnectionService.class)); 818 mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id1", 1) 819 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 820 .build()); 821 822 assertEquals(0, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL, 823 false /* includeDisabled */, Process.myUserHandle()).size()); 824 assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL, 825 true /* includeDisabled */, Process.myUserHandle()).size()); 826 } 827 828 /** 829 * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle)} 830 * to ensure scheme filtering operates. 831 * @throws Exception 832 */ 833 @MediumTest 834 @Test 835 public void testGetByScheme() throws Exception { 836 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 837 Mockito.mock(IConnectionService.class)); 838 registerAndEnableAccount(makeQuickAccountBuilder("id1", 1) 839 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 840 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP)) 841 .build()); 842 registerAndEnableAccount(makeQuickAccountBuilder("id2", 2) 843 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 844 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL)) 845 .build()); 846 847 assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP, 848 false /* includeDisabled */, Process.myUserHandle()).size()); 849 assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL, 850 false /* includeDisabled */, Process.myUserHandle()).size()); 851 assertEquals(2, mRegistrar.getCallCapablePhoneAccounts(null, false /* includeDisabled */, 852 Process.myUserHandle()).size()); 853 } 854 855 /** 856 * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle, 857 * int)} to ensure capability filtering operates. 858 * @throws Exception 859 */ 860 @MediumTest 861 @Test 862 public void testGetByCapability() throws Exception { 863 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 864 Mockito.mock(IConnectionService.class)); 865 registerAndEnableAccount(makeQuickAccountBuilder("id1", 1) 866 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER 867 | PhoneAccount.CAPABILITY_VIDEO_CALLING) 868 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP)) 869 .build()); 870 registerAndEnableAccount(makeQuickAccountBuilder("id2", 2) 871 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 872 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP)) 873 .build()); 874 875 assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP, 876 false /* includeDisabled */, Process.myUserHandle()).size(), 877 PhoneAccount.CAPABILITY_VIDEO_CALLING); 878 assertEquals(2, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP, 879 false /* includeDisabled */, Process.myUserHandle()).size(), 0 /* none extra */); 880 assertEquals(0, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP, 881 false /* includeDisabled */, Process.myUserHandle()).size(), 882 PhoneAccount.CAPABILITY_RTT); 883 } 884 885 private static ComponentName makeQuickConnectionServiceComponentName() { 886 return new ComponentName( 887 "com.android.server.telecom.tests", 888 "com.android.server.telecom.tests.MockConnectionService"); 889 } 890 891 private static PhoneAccountHandle makeQuickAccountHandle(String id) { 892 return makeQuickAccountHandle(makeQuickConnectionServiceComponentName(), id); 893 } 894 895 private static PhoneAccountHandle makeQuickAccountHandle(ComponentName name, String id) { 896 return new PhoneAccountHandle(name, id, Process.myUserHandle()); 897 } 898 899 private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) { 900 return new PhoneAccount.Builder( 901 makeQuickAccountHandle(id), 902 "label" + idx); 903 } 904 905 private PhoneAccount makeQuickAccount(String id, int idx) { 906 return makeQuickAccountBuilder(id, idx) 907 .setAddress(Uri.parse("http://foo.com/" + idx)) 908 .setSubscriptionAddress(Uri.parse("tel:555-000" + idx)) 909 .setCapabilities(idx) 910 .setIcon(Icon.createWithResource( 911 "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call)) 912 .setShortDescription("desc" + idx) 913 .setIsEnabled(true) 914 .build(); 915 } 916 917 private static void roundTripPhoneAccount(PhoneAccount original) throws Exception { 918 PhoneAccount copy = null; 919 920 { 921 Parcel parcel = Parcel.obtain(); 922 parcel.writeParcelable(original, 0); 923 parcel.setDataPosition(0); 924 copy = parcel.readParcelable(PhoneAccountRegistrarTest.class.getClassLoader()); 925 parcel.recycle(); 926 } 927 928 assertPhoneAccountEquals(original, copy); 929 } 930 931 private static <T> T roundTripXml( 932 Object self, 933 T input, 934 PhoneAccountRegistrar.XmlSerialization<T> xml, 935 Context context) 936 throws Exception { 937 Log.d(self, "Input = %s", input); 938 939 byte[] data; 940 { 941 XmlSerializer serializer = new FastXmlSerializer(); 942 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 943 serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); 944 xml.writeToXml(input, serializer, context); 945 serializer.flush(); 946 data = baos.toByteArray(); 947 } 948 949 Log.i(self, "====== XML data ======\n%s", new String(data)); 950 951 T result = null; 952 { 953 XmlPullParser parser = Xml.newPullParser(); 954 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(data)), null); 955 parser.nextTag(); 956 result = xml.readFromXml(parser, MAX_VERSION, context); 957 } 958 959 Log.i(self, "result = " + result); 960 961 return result; 962 } 963 964 private static void assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b) { 965 if (a != b) { 966 assertEquals( 967 a.getComponentName().getPackageName(), 968 b.getComponentName().getPackageName()); 969 assertEquals( 970 a.getComponentName().getClassName(), 971 b.getComponentName().getClassName()); 972 assertEquals(a.getId(), b.getId()); 973 } 974 } 975 976 private static void assertIconEquals(Icon a, Icon b) { 977 if (a != b) { 978 if (a != null && b != null) { 979 assertEquals(a.toString(), b.toString()); 980 } else { 981 fail("Icons not equal: " + a + ", " + b); 982 } 983 } 984 } 985 986 private static void assertDefaultPhoneAccountHandleEquals(DefaultPhoneAccountHandle a, 987 DefaultPhoneAccountHandle b) { 988 if (a != b) { 989 if (a!= null && b != null) { 990 assertEquals(a.userHandle, b.userHandle); 991 assertPhoneAccountHandleEquals(a.phoneAccountHandle, b.phoneAccountHandle); 992 } else { 993 fail("Default phone account handles are not equal: " + a + ", " + b); 994 } 995 } 996 } 997 998 private static void assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b) { 999 if (a != b) { 1000 if (a != null && b != null) { 1001 assertPhoneAccountHandleEquals(a.getAccountHandle(), b.getAccountHandle()); 1002 assertEquals(a.getAddress(), b.getAddress()); 1003 assertEquals(a.getSubscriptionAddress(), b.getSubscriptionAddress()); 1004 assertEquals(a.getCapabilities(), b.getCapabilities()); 1005 assertIconEquals(a.getIcon(), b.getIcon()); 1006 assertEquals(a.getHighlightColor(), b.getHighlightColor()); 1007 assertEquals(a.getLabel(), b.getLabel()); 1008 assertEquals(a.getShortDescription(), b.getShortDescription()); 1009 assertEquals(a.getSupportedUriSchemes(), b.getSupportedUriSchemes()); 1010 assertBundlesEqual(a.getExtras(), b.getExtras()); 1011 assertEquals(a.isEnabled(), b.isEnabled()); 1012 } else { 1013 fail("Phone accounts not equal: " + a + ", " + b); 1014 } 1015 } 1016 } 1017 1018 private static void assertBundlesEqual(Bundle a, Bundle b) { 1019 if (a == null && b == null) { 1020 return; 1021 } 1022 1023 assertNotNull(a); 1024 assertNotNull(b); 1025 Set<String> keySetA = a.keySet(); 1026 Set<String> keySetB = b.keySet(); 1027 1028 assertTrue("Bundle keys not the same", keySetA.containsAll(keySetB)); 1029 assertTrue("Bundle keys not the same", keySetB.containsAll(keySetA)); 1030 1031 for (String keyA : keySetA) { 1032 assertEquals("Bundle value not the same", a.get(keyA), b.get(keyA)); 1033 } 1034 } 1035 1036 private static void assertStateEquals( 1037 PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b) { 1038 assertEquals(a.defaultOutgoingAccountHandles.size(), 1039 b.defaultOutgoingAccountHandles.size()); 1040 for (Map.Entry<UserHandle, DefaultPhoneAccountHandle> e : 1041 a.defaultOutgoingAccountHandles.entrySet()) { 1042 assertDefaultPhoneAccountHandleEquals(e.getValue(), 1043 b.defaultOutgoingAccountHandles.get(e.getKey())); 1044 } 1045 assertEquals(a.accounts.size(), b.accounts.size()); 1046 for (int i = 0; i < a.accounts.size(); i++) { 1047 assertPhoneAccountEquals(a.accounts.get(i), b.accounts.get(i)); 1048 } 1049 } 1050 1051 private PhoneAccountRegistrar.State makeQuickState() { 1052 PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State(); 1053 s.accounts.add(makeQuickAccount("id0", 0)); 1054 s.accounts.add(makeQuickAccount("id1", 1)); 1055 s.accounts.add(makeQuickAccount("id2", 2)); 1056 PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle( 1057 new ComponentName("pkg0", "cls0"), "id0"); 1058 UserHandle userHandle = phoneAccountHandle.getUserHandle(); 1059 when(UserManager.get(mContext).getSerialNumberForUser(userHandle)) 1060 .thenReturn(0L); 1061 when(UserManager.get(mContext).getUserForSerialNumber(0L)) 1062 .thenReturn(userHandle); 1063 s.defaultOutgoingAccountHandles 1064 .put(userHandle, new DefaultPhoneAccountHandle(userHandle, phoneAccountHandle, 1065 "testGroup")); 1066 return s; 1067 } 1068 } 1069