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