PhoneAccountRegistrarTest.java revision ded880cfb3f6bc2e49465b3d2d5f9fa639b045f5
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 17package com.android.server.telecom.tests; 18 19import android.content.ComponentName; 20import android.content.Context; 21import android.graphics.BitmapFactory; 22import android.graphics.Rect; 23import android.graphics.drawable.Icon; 24import android.net.Uri; 25import android.os.Bundle; 26import android.os.Parcel; 27import android.os.Process; 28import android.os.UserHandle; 29import android.telecom.Log; 30import android.telecom.PhoneAccount; 31import android.telecom.PhoneAccountHandle; 32import android.telecom.TelecomManager; 33import android.test.suitebuilder.annotation.MediumTest; 34import android.util.Xml; 35 36import com.android.internal.telecom.IConnectionService; 37import com.android.internal.util.FastXmlSerializer; 38import com.android.server.telecom.DefaultDialerCache; 39import com.android.server.telecom.PhoneAccountRegistrar; 40import com.android.server.telecom.PhoneAccountRegistrar.DefaultPhoneAccountHandle; 41 42import org.mockito.Mock; 43import org.mockito.Mockito; 44import org.mockito.MockitoAnnotations; 45import org.xmlpull.v1.XmlPullParser; 46import org.xmlpull.v1.XmlSerializer; 47 48import java.io.BufferedInputStream; 49import java.io.BufferedOutputStream; 50import java.io.ByteArrayInputStream; 51import java.io.ByteArrayOutputStream; 52import java.io.File; 53import java.util.Arrays; 54import java.util.Set; 55 56import static org.mockito.Matchers.anyInt; 57import static org.mockito.Mockito.when; 58 59public class PhoneAccountRegistrarTest extends TelecomTestCase { 60 61 private static final int MAX_VERSION = Integer.MAX_VALUE; 62 private static final String FILE_NAME = "phone-account-registrar-test-1223.xml"; 63 private PhoneAccountRegistrar mRegistrar; 64 @Mock private TelecomManager mTelecomManager; 65 @Mock private DefaultDialerCache mDefaultDialerCache; 66 67 @Override 68 public void setUp() throws Exception { 69 super.setUp(); 70 MockitoAnnotations.initMocks(this); 71 mComponentContextFixture.setTelecomManager(mTelecomManager); 72 new File( 73 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(), 74 FILE_NAME) 75 .delete(); 76 when(mDefaultDialerCache.getDefaultDialerApplication(anyInt())) 77 .thenReturn("com.android.dialer"); 78 mRegistrar = new PhoneAccountRegistrar( 79 mComponentContextFixture.getTestDouble().getApplicationContext(), 80 FILE_NAME, mDefaultDialerCache); 81 } 82 83 @Override 84 public void tearDown() throws Exception { 85 mRegistrar = null; 86 new File( 87 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(), 88 FILE_NAME) 89 .delete(); 90 super.tearDown(); 91 } 92 93 @MediumTest 94 public void testPhoneAccountHandle() throws Exception { 95 PhoneAccountHandle input = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0"); 96 PhoneAccountHandle result = roundTripXml(this, input, 97 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 98 assertPhoneAccountHandleEquals(input, result); 99 100 PhoneAccountHandle inputN = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), null); 101 PhoneAccountHandle resultN = roundTripXml(this, inputN, 102 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext); 103 Log.i(this, "inputN = %s, resultN = %s", inputN, resultN); 104 assertPhoneAccountHandleEquals(inputN, resultN); 105 } 106 107 @MediumTest 108 public void testPhoneAccount() throws Exception { 109 Bundle testBundle = new Bundle(); 110 testBundle.putInt("EXTRA_INT_1", 1); 111 testBundle.putInt("EXTRA_INT_100", 100); 112 testBundle.putBoolean("EXTRA_BOOL_TRUE", true); 113 testBundle.putBoolean("EXTRA_BOOL_FALSE", false); 114 testBundle.putString("EXTRA_STR1", "Hello"); 115 testBundle.putString("EXTRA_STR2", "There"); 116 117 PhoneAccount input = makeQuickAccountBuilder("id0", 0) 118 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 119 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 120 .setExtras(testBundle) 121 .setIsEnabled(true) 122 .build(); 123 PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml, 124 mContext); 125 126 assertPhoneAccountEquals(input, result); 127 } 128 129 @MediumTest 130 public void testDefaultPhoneAccountHandleEmptyGroup() throws Exception { 131 DefaultPhoneAccountHandle input = new DefaultPhoneAccountHandle(Process.myUserHandle(), 132 makeQuickAccountHandle("i1"), ""); 133 DefaultPhoneAccountHandle result = roundTripXml(this, input, 134 PhoneAccountRegistrar.sDefaultPhoneAcountHandleXml, mContext); 135 136 assertDefaultPhoneAccountHandleEquals(input, result); 137 } 138 139 /** 140 * Test to ensure non-supported values 141 * @throws Exception 142 */ 143 @MediumTest 144 public void testPhoneAccountExtrasEdge() throws Exception { 145 Bundle testBundle = new Bundle(); 146 // Ensure null values for string are not persisted. 147 testBundle.putString("EXTRA_STR2", null); 148 // 149 150 // Ensure unsupported data types are not persisted. 151 testBundle.putShort("EXTRA_SHORT", (short) 2); 152 testBundle.putByte("EXTRA_BYTE", (byte) 1); 153 testBundle.putParcelable("EXTRA_PARC", new Rect(1, 1, 1, 1)); 154 // Put in something valid so the bundle exists. 155 testBundle.putString("EXTRA_OK", "OK"); 156 157 PhoneAccount input = makeQuickAccountBuilder("id0", 0) 158 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 159 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) 160 .setExtras(testBundle) 161 .build(); 162 PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml, 163 mContext); 164 165 Bundle extras = result.getExtras(); 166 assertFalse(extras.keySet().contains("EXTRA_STR2")); 167 assertFalse(extras.keySet().contains("EXTRA_SHORT")); 168 assertFalse(extras.keySet().contains("EXTRA_BYTE")); 169 assertFalse(extras.keySet().contains("EXTRA_PARC")); 170 } 171 172 @MediumTest 173 public void testState() throws Exception { 174 PhoneAccountRegistrar.State input = makeQuickState(); 175 PhoneAccountRegistrar.State result = roundTripXml(this, input, 176 PhoneAccountRegistrar.sStateXml, 177 mContext); 178 assertStateEquals(input, result); 179 } 180 181 private void registerAndEnableAccount(PhoneAccount account) { 182 mRegistrar.registerPhoneAccount(account); 183 mRegistrar.enablePhoneAccount(account.getAccountHandle(), true); 184 } 185 186 @MediumTest 187 public void testAccounts() throws Exception { 188 int i = 0; 189 190 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 191 Mockito.mock(IConnectionService.class)); 192 193 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 194 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 195 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 196 .build()); 197 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 198 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 199 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 200 .build()); 201 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 202 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER 203 | PhoneAccount.CAPABILITY_CALL_PROVIDER) 204 .build()); 205 registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++) 206 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 207 .build()); 208 209 assertEquals(4, mRegistrar.getAllPhoneAccountsOfCurrentUser().size()); 210 assertEquals(3, mRegistrar.getCallCapablePhoneAccountsOfCurrentUser(null, false).size()); 211 assertEquals(null, mRegistrar.getSimCallManagerOfCurrentUser()); 212 assertEquals(null, mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 213 PhoneAccount.SCHEME_TEL)); 214 } 215 216 @MediumTest 217 public void testSimCallManager() throws Exception { 218 // TODO 219 } 220 221 @MediumTest 222 public void testDefaultOutgoing() throws Exception { 223 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 224 Mockito.mock(IConnectionService.class)); 225 226 // By default, there is no default outgoing account (nothing has been registered) 227 assertNull( 228 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 229 230 // Register one tel: account 231 PhoneAccountHandle telAccount = makeQuickAccountHandle("tel_acct"); 232 registerAndEnableAccount(new PhoneAccount.Builder(telAccount, "tel_acct") 233 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 234 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 235 .build()); 236 PhoneAccountHandle defaultAccount = 237 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 238 assertEquals(telAccount, defaultAccount); 239 240 // Add a SIP account, make sure tel: doesn't change 241 PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct"); 242 registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct") 243 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 244 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP) 245 .build()); 246 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 247 PhoneAccount.SCHEME_SIP); 248 assertEquals(sipAccount, defaultAccount); 249 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 250 PhoneAccount.SCHEME_TEL); 251 assertEquals(telAccount, defaultAccount); 252 253 // Add a connection manager, make sure tel: doesn't change 254 PhoneAccountHandle connectionManager = makeQuickAccountHandle("mgr_acct"); 255 registerAndEnableAccount(new PhoneAccount.Builder(connectionManager, "mgr_acct") 256 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER) 257 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 258 .build()); 259 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 260 PhoneAccount.SCHEME_TEL); 261 assertEquals(telAccount, defaultAccount); 262 263 // Unregister the tel: account, make sure there is no tel: default now. 264 mRegistrar.unregisterPhoneAccount(telAccount); 265 assertNull( 266 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 267 } 268 269 @MediumTest 270 public void testReplacePhoneAccountByGroup() throws Exception { 271 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 272 Mockito.mock(IConnectionService.class)); 273 274 // By default, there is no default outgoing account (nothing has been registered) 275 assertNull( 276 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 277 278 // Register one tel: account 279 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 280 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 281 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 282 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 283 .setGroupId("testGroup") 284 .build()); 285 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 286 PhoneAccountHandle defaultAccount = 287 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 288 assertEquals(telAccount1, defaultAccount); 289 290 // Add call capable SIP account, make sure tel: doesn't change 291 PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct"); 292 registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct") 293 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 294 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 295 .build()); 296 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 297 PhoneAccount.SCHEME_TEL); 298 assertEquals(telAccount1, defaultAccount); 299 300 // Replace tel: account with another in the same Group 301 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 302 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 303 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 304 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 305 .setGroupId("testGroup") 306 .build()); 307 defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 308 PhoneAccount.SCHEME_TEL); 309 assertEquals(telAccount2, defaultAccount); 310 assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 311 } 312 313 @MediumTest 314 public void testAddSameDefault() throws Exception { 315 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 316 Mockito.mock(IConnectionService.class)); 317 318 // By default, there is no default outgoing account (nothing has been registered) 319 assertNull( 320 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 321 322 // Register one tel: account 323 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 324 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 325 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 326 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 327 .setGroupId("testGroup") 328 .build()); 329 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 330 PhoneAccountHandle defaultAccount = 331 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 332 assertEquals(telAccount1, defaultAccount); 333 mRegistrar.unregisterPhoneAccount(telAccount1); 334 335 // Register Emergency Account and unregister 336 PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct"); 337 registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct") 338 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 339 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 340 .build()); 341 defaultAccount = 342 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 343 assertNull(defaultAccount); 344 mRegistrar.unregisterPhoneAccount(emerAccount); 345 346 // Re-register the same account and make sure the default is in place 347 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 348 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 349 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 350 .setGroupId("testGroup") 351 .build()); 352 defaultAccount = 353 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 354 assertEquals(telAccount1, defaultAccount); 355 } 356 357 @MediumTest 358 public void testAddSameGroup() throws Exception { 359 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 360 Mockito.mock(IConnectionService.class)); 361 362 // By default, there is no default outgoing account (nothing has been registered) 363 assertNull( 364 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL)); 365 366 // Register one tel: account 367 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 368 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 369 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 370 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 371 .setGroupId("testGroup") 372 .build()); 373 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 374 PhoneAccountHandle defaultAccount = 375 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 376 assertEquals(telAccount1, defaultAccount); 377 mRegistrar.unregisterPhoneAccount(telAccount1); 378 379 // Register Emergency Account and unregister 380 PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct"); 381 registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct") 382 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 383 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 384 .build()); 385 defaultAccount = 386 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 387 assertNull(defaultAccount); 388 mRegistrar.unregisterPhoneAccount(emerAccount); 389 390 // Re-register a new account with the same group 391 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 392 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 393 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 394 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 395 .setGroupId("testGroup") 396 .build()); 397 defaultAccount = 398 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 399 assertEquals(telAccount2, defaultAccount); 400 } 401 402 @MediumTest 403 public void testAddSameGroupButDifferentComponent() throws Exception { 404 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 405 Mockito.mock(IConnectionService.class)); 406 407 // By default, there is no default outgoing account (nothing has been registered) 408 assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 409 PhoneAccount.SCHEME_TEL)); 410 411 // Register one tel: account 412 PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1"); 413 registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1") 414 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 415 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 416 .setGroupId("testGroup") 417 .build()); 418 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 419 PhoneAccountHandle defaultAccount = 420 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 421 assertEquals(telAccount1, defaultAccount); 422 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 423 424 // Register a new account with the same group, but different Component, so don't replace 425 // Default 426 PhoneAccountHandle telAccount2 = makeQuickAccountHandle( 427 new ComponentName("other1", "other2"), "tel_acct2"); 428 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 429 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 430 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 431 .setGroupId("testGroup") 432 .build()); 433 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount2)); 434 435 defaultAccount = 436 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle()); 437 assertEquals(telAccount1, defaultAccount); 438 } 439 440 @MediumTest 441 public void testAddSameGroupButDifferentComponent2() throws Exception { 442 mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(), 443 Mockito.mock(IConnectionService.class)); 444 445 // By default, there is no default outgoing account (nothing has been registered) 446 assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 447 PhoneAccount.SCHEME_TEL)); 448 449 // Register first tel: account 450 PhoneAccountHandle telAccount1 = makeQuickAccountHandle( 451 new ComponentName("other1", "other2"), "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 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 458 mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle()); 459 460 // Register second account with the same group, but a second Component, so don't replace 461 // Default 462 PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2"); 463 registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2") 464 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 465 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 466 .setGroupId("testGroup") 467 .build()); 468 469 PhoneAccountHandle defaultAccount = 470 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 471 assertEquals(telAccount1, defaultAccount); 472 473 // Register third account with the second component name, but same group id 474 PhoneAccountHandle telAccount3 = makeQuickAccountHandle("tel_acct3"); 475 registerAndEnableAccount(new PhoneAccount.Builder(telAccount3, "tel_acct3") 476 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) 477 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) 478 .setGroupId("testGroup") 479 .build()); 480 481 // Make sure that the default account is still the original PhoneAccount and that the 482 // second PhoneAccount with the second ComponentName was replaced by the third PhoneAccount 483 defaultAccount = 484 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL); 485 assertEquals(telAccount1, defaultAccount); 486 487 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1)); 488 assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount2)); 489 assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount3)); 490 } 491 492 @MediumTest 493 public void testPhoneAccountParceling() throws Exception { 494 PhoneAccountHandle handle = makeQuickAccountHandle("foo"); 495 roundTripPhoneAccount(new PhoneAccount.Builder(handle, null).build()); 496 roundTripPhoneAccount(new PhoneAccount.Builder(handle, "foo").build()); 497 roundTripPhoneAccount( 498 new PhoneAccount.Builder(handle, "foo") 499 .setAddress(Uri.parse("tel:123456")) 500 .setCapabilities(23) 501 .setHighlightColor(0xf0f0f0) 502 .setIcon(Icon.createWithResource( 503 "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call)) 504 // TODO: set icon tint (0xfefefe) 505 .setShortDescription("short description") 506 .setSubscriptionAddress(Uri.parse("tel:2345678")) 507 .setSupportedUriSchemes(Arrays.asList("tel", "sip")) 508 .setGroupId("testGroup") 509 .build()); 510 roundTripPhoneAccount( 511 new PhoneAccount.Builder(handle, "foo") 512 .setAddress(Uri.parse("tel:123456")) 513 .setCapabilities(23) 514 .setHighlightColor(0xf0f0f0) 515 .setIcon(Icon.createWithBitmap( 516 BitmapFactory.decodeResource( 517 getContext().getResources(), 518 R.drawable.stat_sys_phone_call))) 519 .setShortDescription("short description") 520 .setSubscriptionAddress(Uri.parse("tel:2345678")) 521 .setSupportedUriSchemes(Arrays.asList("tel", "sip")) 522 .setGroupId("testGroup") 523 .build()); 524 } 525 526 private static ComponentName makeQuickConnectionServiceComponentName() { 527 return new ComponentName( 528 "com.android.server.telecom.tests", 529 "com.android.server.telecom.tests.MockConnectionService"); 530 } 531 532 private static PhoneAccountHandle makeQuickAccountHandle(String id) { 533 return makeQuickAccountHandle(makeQuickConnectionServiceComponentName(), id); 534 } 535 536 private static PhoneAccountHandle makeQuickAccountHandle(ComponentName name, String id) { 537 return new PhoneAccountHandle(name, id, Process.myUserHandle()); 538 } 539 540 private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) { 541 return new PhoneAccount.Builder( 542 makeQuickAccountHandle(id), 543 "label" + idx); 544 } 545 546 private PhoneAccount makeQuickAccount(String id, int idx) { 547 return makeQuickAccountBuilder(id, idx) 548 .setAddress(Uri.parse("http://foo.com/" + idx)) 549 .setSubscriptionAddress(Uri.parse("tel:555-000" + idx)) 550 .setCapabilities(idx) 551 .setIcon(Icon.createWithResource( 552 "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call)) 553 .setShortDescription("desc" + idx) 554 .setIsEnabled(true) 555 .build(); 556 } 557 558 private static void roundTripPhoneAccount(PhoneAccount original) throws Exception { 559 PhoneAccount copy = null; 560 561 { 562 Parcel parcel = Parcel.obtain(); 563 parcel.writeParcelable(original, 0); 564 parcel.setDataPosition(0); 565 copy = parcel.readParcelable(PhoneAccountRegistrarTest.class.getClassLoader()); 566 parcel.recycle(); 567 } 568 569 assertPhoneAccountEquals(original, copy); 570 } 571 572 private static <T> T roundTripXml( 573 Object self, 574 T input, 575 PhoneAccountRegistrar.XmlSerialization<T> xml, 576 Context context) 577 throws Exception { 578 Log.d(self, "Input = %s", input); 579 580 byte[] data; 581 { 582 XmlSerializer serializer = new FastXmlSerializer(); 583 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 584 serializer.setOutput(new BufferedOutputStream(baos), "utf-8"); 585 xml.writeToXml(input, serializer, context); 586 serializer.flush(); 587 data = baos.toByteArray(); 588 } 589 590 Log.i(self, "====== XML data ======\n%s", new String(data)); 591 592 T result = null; 593 { 594 XmlPullParser parser = Xml.newPullParser(); 595 parser.setInput(new BufferedInputStream(new ByteArrayInputStream(data)), null); 596 parser.nextTag(); 597 result = xml.readFromXml(parser, MAX_VERSION, context); 598 } 599 600 Log.i(self, "result = " + result); 601 602 return result; 603 } 604 605 private static void assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b) { 606 if (a != b) { 607 assertEquals( 608 a.getComponentName().getPackageName(), 609 b.getComponentName().getPackageName()); 610 assertEquals( 611 a.getComponentName().getClassName(), 612 b.getComponentName().getClassName()); 613 assertEquals(a.getId(), b.getId()); 614 } 615 } 616 617 private static void assertIconEquals(Icon a, Icon b) { 618 if (a != b) { 619 if (a != null && b != null) { 620 assertEquals(a.toString(), b.toString()); 621 } else { 622 fail("Icons not equal: " + a + ", " + b); 623 } 624 } 625 } 626 627 private static void assertDefaultPhoneAccountHandleEquals(DefaultPhoneAccountHandle a, 628 DefaultPhoneAccountHandle b) { 629 if (a != b) { 630 if (a!= null && b != null) { 631 assertEquals(a.userHandle, b.userHandle); 632 assertPhoneAccountHandleEquals(a.phoneAccountHandle, b.phoneAccountHandle); 633 } else { 634 fail("Default phone account handles are not equal: " + a + ", " + b); 635 } 636 } 637 } 638 639 private static void assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b) { 640 if (a != b) { 641 if (a != null && b != null) { 642 assertPhoneAccountHandleEquals(a.getAccountHandle(), b.getAccountHandle()); 643 assertEquals(a.getAddress(), b.getAddress()); 644 assertEquals(a.getSubscriptionAddress(), b.getSubscriptionAddress()); 645 assertEquals(a.getCapabilities(), b.getCapabilities()); 646 assertIconEquals(a.getIcon(), b.getIcon()); 647 assertEquals(a.getHighlightColor(), b.getHighlightColor()); 648 assertEquals(a.getLabel(), b.getLabel()); 649 assertEquals(a.getShortDescription(), b.getShortDescription()); 650 assertEquals(a.getSupportedUriSchemes(), b.getSupportedUriSchemes()); 651 assertBundlesEqual(a.getExtras(), b.getExtras()); 652 assertEquals(a.isEnabled(), b.isEnabled()); 653 } else { 654 fail("Phone accounts not equal: " + a + ", " + b); 655 } 656 } 657 } 658 659 private static void assertBundlesEqual(Bundle a, Bundle b) { 660 if (a == null && b == null) { 661 return; 662 } 663 664 assertNotNull(a); 665 assertNotNull(b); 666 Set<String> keySetA = a.keySet(); 667 Set<String> keySetB = b.keySet(); 668 669 assertTrue("Bundle keys not the same", keySetA.containsAll(keySetB)); 670 assertTrue("Bundle keys not the same", keySetB.containsAll(keySetA)); 671 672 for (String keyA : keySetA) { 673 assertEquals("Bundle value not the same", a.get(keyA), b.get(keyA)); 674 } 675 } 676 677 private static void assertStateEquals( 678 PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b) { 679 assertEquals(a.defaultOutgoingAccountHandles.size(), 680 b.defaultOutgoingAccountHandles.size()); 681 for (int i = 0; i < a.defaultOutgoingAccountHandles.size(); i++) { 682 assertDefaultPhoneAccountHandleEquals(a.defaultOutgoingAccountHandles.get(i), 683 b.defaultOutgoingAccountHandles.get(i)); 684 } 685 assertEquals(a.accounts.size(), b.accounts.size()); 686 for (int i = 0; i < a.accounts.size(); i++) { 687 assertPhoneAccountEquals(a.accounts.get(i), b.accounts.get(i)); 688 } 689 } 690 691 private PhoneAccountRegistrar.State makeQuickState() { 692 PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State(); 693 s.accounts.add(makeQuickAccount("id0", 0)); 694 s.accounts.add(makeQuickAccount("id1", 1)); 695 s.accounts.add(makeQuickAccount("id2", 2)); 696 PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle( 697 new ComponentName("pkg0", "cls0"), "id0"); 698 UserHandle userHandle = phoneAccountHandle.getUserHandle(); 699 s.defaultOutgoingAccountHandles 700 .put(userHandle, new DefaultPhoneAccountHandle(userHandle, phoneAccountHandle, 701 "testGroup")); 702 return s; 703 } 704} 705