Home | History | Annotate | Download | only in tests
      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