1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.telecom.tests;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyBoolean;
27 import static org.mockito.ArgumentMatchers.anyInt;
28 import static org.mockito.ArgumentMatchers.anyString;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.Mockito.clearInvocations;
31 import static org.mockito.Mockito.doReturn;
32 import static org.mockito.Mockito.doThrow;
33 import static org.mockito.Mockito.mock;
34 import static org.mockito.Mockito.never;
35 import static org.mockito.Mockito.times;
36 import static org.mockito.Mockito.verify;
37 import static org.mockito.Mockito.when;
38 
39 import android.annotation.Nullable;
40 import android.content.ComponentName;
41 import android.content.Context;
42 import android.content.pm.PackageInfo;
43 import android.content.pm.PackageManager;
44 import android.graphics.BitmapFactory;
45 import android.graphics.Rect;
46 import android.graphics.drawable.Icon;
47 import android.net.Uri;
48 import android.os.Bundle;
49 import android.os.Parcel;
50 import android.os.PersistableBundle;
51 import android.os.Process;
52 import android.os.UserHandle;
53 import android.os.UserManager;
54 import android.telecom.Log;
55 import android.telecom.PhoneAccount;
56 import android.telecom.PhoneAccountHandle;
57 import android.telecom.TelecomManager;
58 import android.telephony.CarrierConfigManager;
59 import android.telephony.SubscriptionInfo;
60 import android.telephony.SubscriptionManager;
61 import android.util.Xml;
62 
63 import androidx.test.InstrumentationRegistry;
64 import androidx.test.filters.MediumTest;
65 import androidx.test.filters.SmallTest;
66 
67 import com.android.internal.telecom.IConnectionService;
68 import com.android.internal.telephony.flags.FeatureFlags;
69 import com.android.internal.util.FastXmlSerializer;
70 import com.android.server.telecom.AppLabelProxy;
71 import com.android.server.telecom.DefaultDialerCache;
72 import com.android.server.telecom.PhoneAccountRegistrar;
73 import com.android.server.telecom.PhoneAccountRegistrar.DefaultPhoneAccountHandle;
74 import com.android.server.telecom.TelecomSystem;
75 
76 import org.junit.After;
77 import org.junit.Before;
78 import org.junit.Test;
79 import org.junit.runner.RunWith;
80 import org.junit.runners.JUnit4;
81 import org.mockito.Mock;
82 import org.mockito.Mockito;
83 import org.mockito.MockitoAnnotations;
84 import org.xmlpull.v1.XmlPullParser;
85 import org.xmlpull.v1.XmlSerializer;
86 
87 import java.io.BufferedInputStream;
88 import java.io.BufferedOutputStream;
89 import java.io.ByteArrayInputStream;
90 import java.io.ByteArrayOutputStream;
91 import java.io.File;
92 import java.io.IOException;
93 import java.io.OutputStream;
94 import java.util.ArrayList;
95 import java.util.Arrays;
96 import java.util.Collection;
97 import java.util.HashSet;
98 import java.util.List;
99 import java.util.Map;
100 import java.util.Set;
101 import java.util.UUID;
102 
103 @RunWith(JUnit4.class)
104 public class PhoneAccountRegistrarTest extends TelecomTestCase {
105 
106     private static final int MAX_VERSION = Integer.MAX_VALUE;
107     private static final int INVALID_CHAR_LIMIT_COUNT =
108             PhoneAccountRegistrar.MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT + 1;
109     private static final String INVALID_STR = "a".repeat(INVALID_CHAR_LIMIT_COUNT);
110     private static final String FILE_NAME = "phone-account-registrar-test-1223.xml";
111     private static final String TEST_LABEL = "right";
112     private static final String TEST_ID = "123";
113     private final String PACKAGE_1 = "PACKAGE_1";
114     private final String PACKAGE_2 = "PACKAGE_2";
115     private final String COMPONENT_NAME = "com.android.server.telecom.tests.MockConnectionService";
116     private final UserHandle USER_HANDLE_10 = new UserHandle(10);
117     private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
118     private PhoneAccountRegistrar mRegistrar;
119     @Mock private SubscriptionManager mSubscriptionManager;
120     @Mock private TelecomManager mTelecomManager;
121     @Mock private DefaultDialerCache mDefaultDialerCache;
122     @Mock private AppLabelProxy mAppLabelProxy;
123     @Mock private FeatureFlags mTelephonyFeatureFlags;
124 
125     @Override
126     @Before
setUp()127     public void setUp() throws Exception {
128         super.setUp();
129         MockitoAnnotations.initMocks(this);
130         mComponentContextFixture.setTelecomManager(mTelecomManager);
131         mComponentContextFixture.setSubscriptionManager(mSubscriptionManager);
132         new File(
133                 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(),
134                 FILE_NAME)
135                 .delete();
136         when(mDefaultDialerCache.getDefaultDialerApplication(anyInt()))
137                 .thenReturn("com.android.dialer");
138         when(mAppLabelProxy.getAppLabel(anyString()))
139                 .thenReturn(TEST_LABEL);
140         mRegistrar = new PhoneAccountRegistrar(
141                 mComponentContextFixture.getTestDouble().getApplicationContext(), mLock, FILE_NAME,
142                 mDefaultDialerCache, mAppLabelProxy, mTelephonyFeatureFlags, mFeatureFlags);
143         when(mFeatureFlags.onlyUpdateTelephonyOnValidSubIds()).thenReturn(false);
144         when(mFeatureFlags.unregisterUnresolvableAccounts()).thenReturn(true);
145         when(mTelephonyFeatureFlags.workProfileApiSplit()).thenReturn(false);
146     }
147 
148     @Override
149     @After
tearDown()150     public void tearDown() throws Exception {
151         mRegistrar = null;
152         new File(
153                 mComponentContextFixture.getTestDouble().getApplicationContext().getFilesDir(),
154                 FILE_NAME)
155                 .delete();
156         super.tearDown();
157     }
158 
159     @MediumTest
160     @Test
testPhoneAccountHandle()161     public void testPhoneAccountHandle() throws Exception {
162         PhoneAccountHandle input = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), "id0");
163         PhoneAccountHandle result = roundTripXml(this, input,
164                 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext,
165                 mTelephonyFeatureFlags, mFeatureFlags);
166         assertPhoneAccountHandleEquals(input, result);
167 
168         PhoneAccountHandle inputN = new PhoneAccountHandle(new ComponentName("pkg0", "cls0"), null);
169         PhoneAccountHandle resultN = roundTripXml(this, inputN,
170                 PhoneAccountRegistrar.sPhoneAccountHandleXml, mContext,
171                 mTelephonyFeatureFlags, mFeatureFlags);
172         Log.i(this, "inputN = %s, resultN = %s", inputN, resultN);
173         assertPhoneAccountHandleEquals(inputN, resultN);
174     }
175 
176     @MediumTest
177     @Test
testPhoneAccount()178     public void testPhoneAccount() throws Exception {
179         Bundle testBundle = new Bundle();
180         testBundle.putInt("EXTRA_INT_1", 1);
181         testBundle.putInt("EXTRA_INT_100", 100);
182         testBundle.putBoolean("EXTRA_BOOL_TRUE", true);
183         testBundle.putBoolean("EXTRA_BOOL_FALSE", false);
184         testBundle.putString("EXTRA_STR1", "Hello");
185         testBundle.putString("EXTRA_STR2", "There");
186 
187         PhoneAccount input = makeQuickAccountBuilder("id0", 0, null)
188                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
189                 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
190                 .setExtras(testBundle)
191                 .setIsEnabled(true)
192                 .build();
193         PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml,
194                 mContext, mTelephonyFeatureFlags, mFeatureFlags);
195 
196         assertPhoneAccountEquals(input, result);
197     }
198 
199     @MediumTest
200     @Test
testPhoneAccountParsing_simultaneousCallingRestriction()201     public void testPhoneAccountParsing_simultaneousCallingRestriction() throws Exception {
202         doReturn(true).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
203         // workaround: UserManager converts the user to a serial and back, we need to mock this
204         // behavior, unfortunately: USER_HANDLE_10 <-> 10L
205         UserManager userManager = mContext.getSystemService(UserManager.class);
206         doReturn(10L).when(userManager).getSerialNumberForUser(eq(USER_HANDLE_10));
207         doReturn(USER_HANDLE_10).when(userManager).getUserForSerialNumber(eq(10L));
208         Bundle testBundle = new Bundle();
209         testBundle.putInt("EXTRA_INT_1", 1);
210         testBundle.putInt("EXTRA_INT_100", 100);
211         testBundle.putBoolean("EXTRA_BOOL_TRUE", true);
212         testBundle.putBoolean("EXTRA_BOOL_FALSE", false);
213         testBundle.putString("EXTRA_STR1", "Hello");
214         testBundle.putString("EXTRA_STR2", "There");
215 
216         Set<PhoneAccountHandle> restriction = new HashSet<>(10);
217         for (int i = 0; i < 10; i++) {
218             restriction.add(makeQuickAccountHandleForUser("id" + i, USER_HANDLE_10));
219         }
220 
221         PhoneAccount input = makeQuickAccountBuilder("id0", 0, USER_HANDLE_10)
222                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
223                 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
224                 .setExtras(testBundle)
225                 .setIsEnabled(true)
226                 .setSimultaneousCallingRestriction(restriction)
227                 .build();
228         PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml,
229                 mContext, mTelephonyFeatureFlags, mFeatureFlags);
230 
231         assertPhoneAccountEquals(input, result);
232     }
233 
234     @MediumTest
235     @Test
testPhoneAccountParsing_simultaneousCallingRestrictionOnOffFlag()236     public void testPhoneAccountParsing_simultaneousCallingRestrictionOnOffFlag() throws Exception {
237         // Start the test with the flag on
238         doReturn(true).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
239         // workaround: UserManager converts the user to a serial and back, we need to mock this
240         // behavior, unfortunately: USER_HANDLE_10 <-> 10L
241         UserManager userManager = mContext.getSystemService(UserManager.class);
242         doReturn(10L).when(userManager).getSerialNumberForUser(eq(USER_HANDLE_10));
243         doReturn(USER_HANDLE_10).when(userManager).getUserForSerialNumber(eq(10L));
244         Bundle testBundle = new Bundle();
245         testBundle.putInt("EXTRA_INT_1", 1);
246         testBundle.putInt("EXTRA_INT_100", 100);
247         testBundle.putBoolean("EXTRA_BOOL_TRUE", true);
248         testBundle.putBoolean("EXTRA_BOOL_FALSE", false);
249         testBundle.putString("EXTRA_STR1", "Hello");
250         testBundle.putString("EXTRA_STR2", "There");
251 
252         Set<PhoneAccountHandle> restriction = new HashSet<>(10);
253         for (int i = 0; i < 10; i++) {
254             restriction.add(makeQuickAccountHandleForUser("id" + i, USER_HANDLE_10));
255         }
256 
257         PhoneAccount input = makeQuickAccountBuilder("id0", 0, USER_HANDLE_10)
258                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
259                 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
260                 .setExtras(testBundle)
261                 .setIsEnabled(true)
262                 .setSimultaneousCallingRestriction(restriction)
263                 .build();
264         byte[] xmlData = toXml(input, PhoneAccountRegistrar.sPhoneAccountXml, mContext,
265                 mTelephonyFeatureFlags);
266         // Simulate turning off the flag after reboot
267         doReturn(false).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
268         PhoneAccount result = fromXml(xmlData, PhoneAccountRegistrar.sPhoneAccountXml, mContext,
269                 mTelephonyFeatureFlags, mFeatureFlags);
270 
271         assertNotNull(result);
272         assertFalse(result.hasSimultaneousCallingRestriction());
273     }
274 
275     @MediumTest
276     @Test
testPhoneAccountParsing_simultaneousCallingRestrictionOffOnFlag()277     public void testPhoneAccountParsing_simultaneousCallingRestrictionOffOnFlag() throws Exception {
278         // Start the test with the flag on
279         doReturn(false).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
280         Bundle testBundle = new Bundle();
281         testBundle.putInt("EXTRA_INT_1", 1);
282         testBundle.putInt("EXTRA_INT_100", 100);
283         testBundle.putBoolean("EXTRA_BOOL_TRUE", true);
284         testBundle.putBoolean("EXTRA_BOOL_FALSE", false);
285         testBundle.putString("EXTRA_STR1", "Hello");
286         testBundle.putString("EXTRA_STR2", "There");
287 
288         PhoneAccount input = makeQuickAccountBuilder("id0", 0, USER_HANDLE_10)
289                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
290                 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
291                 .setExtras(testBundle)
292                 .setIsEnabled(true)
293                 .build();
294         byte[] xmlData = toXml(input, PhoneAccountRegistrar.sPhoneAccountXml, mContext,
295                 mTelephonyFeatureFlags);
296         // Simulate turning on the flag after reboot
297         doReturn(true).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
298         PhoneAccount result = fromXml(xmlData, PhoneAccountRegistrar.sPhoneAccountXml, mContext,
299                 mTelephonyFeatureFlags, mFeatureFlags);
300 
301         assertPhoneAccountEquals(input, result);
302     }
303 
304     @SmallTest
305     @Test
testFilterPhoneAccountForTest()306     public void testFilterPhoneAccountForTest() throws Exception {
307         ComponentName componentA = new ComponentName("a", "a");
308         ComponentName componentB1 = new ComponentName("b", "b1");
309         ComponentName componentB2 = new ComponentName("b", "b2");
310         ComponentName componentC = new ComponentName("c", "c");
311 
312         PhoneAccount simAccountA = new PhoneAccount.Builder(
313                 makeQuickAccountHandle(componentA, "1"), "1")
314                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
315                 .setIsEnabled(true)
316                 .build();
317 
318         List<PhoneAccount> accountAList = new ArrayList<>();
319         accountAList.add(simAccountA);
320 
321         PhoneAccount simAccountB1 = new PhoneAccount.Builder(
322                 makeQuickAccountHandle(componentB1, "2"), "2")
323                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
324                 .setIsEnabled(true)
325                 .build();
326 
327         PhoneAccount simAccountB2 = new PhoneAccount.Builder(
328                 makeQuickAccountHandle(componentB2, "3"), "3")
329                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
330                 .setIsEnabled(true)
331                 .build();
332 
333         List<PhoneAccount> accountBList = new ArrayList<>();
334         accountBList.add(simAccountB1);
335         accountBList.add(simAccountB2);
336 
337         PhoneAccount simAccountC = new PhoneAccount.Builder(
338                 makeQuickAccountHandle(componentC, "4"), "4")
339                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
340                 .setIsEnabled(true)
341                 .build();
342 
343         List<PhoneAccount> accountCList = new ArrayList<>();
344         accountCList.add(simAccountC);
345 
346         List<PhoneAccount> allAccounts = new ArrayList<>();
347         allAccounts.addAll(accountAList);
348         allAccounts.addAll(accountBList);
349         allAccounts.addAll(accountCList);
350 
351         assertEquals(allAccounts, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
352 
353         mRegistrar.setTestPhoneAccountPackageNameFilter(componentA.getPackageName());
354         assertEquals(accountAList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
355 
356         mRegistrar.setTestPhoneAccountPackageNameFilter(componentB1.getPackageName());
357         assertEquals(accountBList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
358 
359         mRegistrar.setTestPhoneAccountPackageNameFilter(componentC.getPackageName());
360         assertEquals(accountCList, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
361 
362         mRegistrar.setTestPhoneAccountPackageNameFilter(null);
363         assertEquals(allAccounts, mRegistrar.filterRestrictedPhoneAccounts(allAccounts));
364     }
365 
366     @MediumTest
367     @Test
testDefaultPhoneAccountHandleEmptyGroup()368     public void testDefaultPhoneAccountHandleEmptyGroup() throws Exception {
369         DefaultPhoneAccountHandle input = new DefaultPhoneAccountHandle(Process.myUserHandle(),
370                 makeQuickAccountHandle("i1"), "");
371         UserManager userManager = mContext.getSystemService(UserManager.class);
372         when(userManager.getSerialNumberForUser(input.userHandle))
373                 .thenReturn(0L);
374         when(userManager.getUserForSerialNumber(0L))
375                 .thenReturn(input.userHandle);
376         DefaultPhoneAccountHandle result = roundTripXml(this, input,
377                 PhoneAccountRegistrar.sDefaultPhoneAccountHandleXml, mContext,
378                 mTelephonyFeatureFlags, mFeatureFlags);
379 
380         assertDefaultPhoneAccountHandleEquals(input, result);
381     }
382 
383     /**
384      * Test to ensure non-supported values
385      * @throws Exception
386      */
387     @MediumTest
388     @Test
testPhoneAccountExtrasEdge()389     public void testPhoneAccountExtrasEdge() throws Exception {
390         Bundle testBundle = new Bundle();
391         // Ensure null values for string are not persisted.
392         testBundle.putString("EXTRA_STR2", null);
393         //
394 
395         // Ensure unsupported data types are not persisted.
396         testBundle.putShort("EXTRA_SHORT", (short) 2);
397         testBundle.putByte("EXTRA_BYTE", (byte) 1);
398         testBundle.putParcelable("EXTRA_PARC", new Rect(1, 1, 1, 1));
399         // Put in something valid so the bundle exists.
400         testBundle.putString("EXTRA_OK", "OK");
401 
402         PhoneAccount input = makeQuickAccountBuilder("id0", 0, null)
403                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
404                 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
405                 .setExtras(testBundle)
406                 .build();
407         PhoneAccount result = roundTripXml(this, input, PhoneAccountRegistrar.sPhoneAccountXml,
408                 mContext, mTelephonyFeatureFlags, mFeatureFlags);
409 
410         Bundle extras = result.getExtras();
411         assertFalse(extras.keySet().contains("EXTRA_STR2"));
412         assertFalse(extras.keySet().contains("EXTRA_SHORT"));
413         assertFalse(extras.keySet().contains("EXTRA_BYTE"));
414         assertFalse(extras.keySet().contains("EXTRA_PARC"));
415     }
416 
417     @MediumTest
418     @Test
testState()419     public void testState() throws Exception {
420         PhoneAccountRegistrar.State input = makeQuickState();
421         PhoneAccountRegistrar.State result = roundTripXml(this, input,
422                 PhoneAccountRegistrar.sStateXml, mContext, mTelephonyFeatureFlags, mFeatureFlags);
423         assertStateEquals(input, result);
424     }
425 
registerAndEnableAccount(PhoneAccount account)426     private void registerAndEnableAccount(PhoneAccount account) {
427         mRegistrar.registerPhoneAccount(account);
428         mRegistrar.enablePhoneAccount(account.getAccountHandle(), true);
429     }
430 
431     @MediumTest
432     @Test
testAccounts()433     public void testAccounts() throws Exception {
434         int i = 0;
435 
436         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
437                 Mockito.mock(IConnectionService.class));
438 
439         registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++, null)
440                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
441                         | PhoneAccount.CAPABILITY_CALL_PROVIDER)
442                 .build());
443         registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++, null)
444                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
445                         | PhoneAccount.CAPABILITY_CALL_PROVIDER)
446                 .build());
447         registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++, null)
448                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
449                         | PhoneAccount.CAPABILITY_CALL_PROVIDER)
450                 .build());
451         registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++, null)
452                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
453                 .build());
454         registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++, USER_HANDLE_10)
455                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
456                         | PhoneAccount.CAPABILITY_CALL_PROVIDER)
457                 .build());
458         registerAndEnableAccount(makeQuickAccountBuilder("id" + i, i++, USER_HANDLE_10)
459                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
460                 .build());
461 
462         assertEquals(6, mRegistrar.
463                 getAllPhoneAccounts(null, true).size());
464         assertEquals(4, mRegistrar.getCallCapablePhoneAccounts(null, false,
465                 null, true).size());
466         assertEquals(null, mRegistrar.getSimCallManagerOfCurrentUser());
467         assertEquals(null, mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
468                 PhoneAccount.SCHEME_TEL));
469     }
470 
471     /**
472      * Verify when a {@link android.telecom.ConnectionService} is disabled or cannot be resolved,
473      * all phone accounts are unregistered when calling
474      * {@link  PhoneAccountRegistrar#cleanupAndGetVerifiedAccounts(PhoneAccount)}.
475      */
476     @Test
testCannotResolveServiceUnregistersAccounts()477     public void testCannotResolveServiceUnregistersAccounts() throws Exception {
478         ComponentName componentName = makeQuickConnectionServiceComponentName();
479         PhoneAccount account = makeQuickAccountBuilder("0", 0, USER_HANDLE_10)
480                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
481                         | PhoneAccount.CAPABILITY_CALL_PROVIDER).build();
482         // add the ConnectionService and register a single phone account for it
483         mComponentContextFixture.addConnectionService(componentName,
484                 Mockito.mock(IConnectionService.class));
485         registerAndEnableAccount(account);
486         // verify the start state
487         assertEquals(1,
488                 mRegistrar.getRegisteredAccountsForPackageName(componentName.getPackageName(),
489                         USER_HANDLE_10).size());
490         // remove the ConnectionService so that the account cannot be resolved anymore
491         mComponentContextFixture.removeConnectionService(componentName,
492                 Mockito.mock(IConnectionService.class));
493         // verify the account is unregistered when fetching the phone accounts for the package
494         assertEquals(1,
495                 mRegistrar.getRegisteredAccountsForPackageName(componentName.getPackageName(),
496                         USER_HANDLE_10).size());
497         assertEquals(0,
498                 mRegistrar.cleanupAndGetVerifiedAccounts(account).size());
499         assertEquals(0,
500                 mRegistrar.getRegisteredAccountsForPackageName(componentName.getPackageName(),
501                         USER_HANDLE_10).size());
502     }
503 
504     /**
505      * Verify that if a client adds both the {@link
506      * PhoneAccount#CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS} capability AND is backed by a
507      * {@link android.telecom.ConnectionService}, a {@link IllegalArgumentException} is thrown.
508      */
509     @Test
testConnectionServiceAndTransactionalAccount()510     public void testConnectionServiceAndTransactionalAccount() throws Exception {
511         PhoneAccount account = makeQuickAccountBuilder("0", 0, USER_HANDLE_10)
512                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED
513                         | PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS).build();
514         mComponentContextFixture.addConnectionService(
515                 makeQuickConnectionServiceComponentName(),
516                 Mockito.mock(IConnectionService.class));
517         try {
518             registerAndEnableAccount(account);
519             fail("failed to throw IllegalArgumentException");
520         } catch (IllegalArgumentException e) {
521             // test passed, ignore Exception.
522         }
523     }
524 
525     @MediumTest
526     @Test
testSimCallManager()527     public void testSimCallManager() throws Exception {
528         // TODO
529     }
530 
531     @MediumTest
532     @Test
testDefaultOutgoing()533     public void testDefaultOutgoing() throws Exception {
534         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
535                 Mockito.mock(IConnectionService.class));
536 
537         // By default, there is no default outgoing account (nothing has been registered)
538         assertNull(
539                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
540 
541         // Register one tel: account
542         PhoneAccountHandle telAccount = makeQuickAccountHandle("tel_acct");
543         registerAndEnableAccount(new PhoneAccount.Builder(telAccount, "tel_acct")
544                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
545                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
546                 .build());
547         PhoneAccountHandle defaultAccount =
548                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL);
549         assertEquals(telAccount, defaultAccount);
550 
551         // Add a SIP account, make sure tel: doesn't change
552         PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct");
553         registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct")
554                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
555                 .addSupportedUriScheme(PhoneAccount.SCHEME_SIP)
556                 .build());
557         defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
558                 PhoneAccount.SCHEME_SIP);
559         assertEquals(sipAccount, defaultAccount);
560         defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
561                 PhoneAccount.SCHEME_TEL);
562         assertEquals(telAccount, defaultAccount);
563 
564         // Add a connection manager, make sure tel: doesn't change
565         PhoneAccountHandle connectionManager = makeQuickAccountHandle("mgr_acct");
566         registerAndEnableAccount(new PhoneAccount.Builder(connectionManager, "mgr_acct")
567                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
568                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
569                 .build());
570         defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
571                 PhoneAccount.SCHEME_TEL);
572         assertEquals(telAccount, defaultAccount);
573 
574         // Unregister the tel: account, make sure there is no tel: default now.
575         mRegistrar.unregisterPhoneAccount(telAccount);
576         assertNull(
577                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
578     }
579 
580     @MediumTest
581     @Test
testReplacePhoneAccountByGroup()582     public void testReplacePhoneAccountByGroup() throws Exception {
583         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
584                 Mockito.mock(IConnectionService.class));
585 
586         // By default, there is no default outgoing account (nothing has been registered)
587         assertNull(
588                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
589 
590         // Register one tel: account
591         PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1");
592         registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
593                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
594                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
595                 .setGroupId("testGroup")
596                 .build());
597         mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
598         PhoneAccountHandle defaultAccount =
599                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL);
600         assertEquals(telAccount1, defaultAccount);
601 
602         // Add call capable SIP account, make sure tel: doesn't change
603         PhoneAccountHandle sipAccount = makeQuickAccountHandle("sip_acct");
604         registerAndEnableAccount(new PhoneAccount.Builder(sipAccount, "sip_acct")
605                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
606                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
607                 .build());
608         defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
609                 PhoneAccount.SCHEME_TEL);
610         assertEquals(telAccount1, defaultAccount);
611 
612         // Replace tel: account with another in the same Group
613         PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2");
614         registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2")
615                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
616                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
617                 .setGroupId("testGroup")
618                 .build());
619         defaultAccount = mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
620                 PhoneAccount.SCHEME_TEL);
621         assertEquals(telAccount2, defaultAccount);
622         assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount1));
623     }
624 
625     @MediumTest
626     @Test
testAddSameDefault()627     public void testAddSameDefault() throws Exception {
628         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
629                 Mockito.mock(IConnectionService.class));
630 
631         // By default, there is no default outgoing account (nothing has been registered)
632         assertNull(
633                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
634 
635         // Register one tel: account
636         PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1");
637         registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
638                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
639                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
640                 .setGroupId("testGroup")
641                 .build());
642         mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
643         PhoneAccountHandle defaultAccount =
644                 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
645         assertEquals(telAccount1, defaultAccount);
646         mRegistrar.unregisterPhoneAccount(telAccount1);
647 
648         // Register Emergency Account and unregister
649         PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct");
650         registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct")
651                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
652                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
653                 .build());
654         defaultAccount =
655                 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
656         assertNull(defaultAccount);
657         mRegistrar.unregisterPhoneAccount(emerAccount);
658 
659         // Re-register the same account and make sure the default is in place
660         registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
661                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
662                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
663                 .setGroupId("testGroup")
664                 .build());
665         defaultAccount =
666                 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
667         assertEquals(telAccount1, defaultAccount);
668     }
669 
670     @MediumTest
671     @Test
testAddSameGroup()672     public void testAddSameGroup() throws Exception {
673         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
674                 Mockito.mock(IConnectionService.class));
675 
676         // By default, there is no default outgoing account (nothing has been registered)
677         assertNull(
678                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL));
679 
680         // Register one tel: account
681         PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1");
682         registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
683                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
684                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
685                 .setGroupId("testGroup")
686                 .build());
687         mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
688         PhoneAccountHandle defaultAccount =
689                 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
690         assertEquals(telAccount1, defaultAccount);
691         mRegistrar.unregisterPhoneAccount(telAccount1);
692 
693         // Register Emergency Account and unregister
694         PhoneAccountHandle emerAccount = makeQuickAccountHandle("emer_acct");
695         registerAndEnableAccount(new PhoneAccount.Builder(emerAccount, "emer_acct")
696                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
697                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
698                 .build());
699         defaultAccount =
700                 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
701         assertNull(defaultAccount);
702         mRegistrar.unregisterPhoneAccount(emerAccount);
703 
704         // Re-register a new account with the same group
705         PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2");
706         registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2")
707                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
708                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
709                 .setGroupId("testGroup")
710                 .build());
711         defaultAccount =
712                 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
713         assertEquals(telAccount2, defaultAccount);
714     }
715 
716     @MediumTest
717     @Test
testAddSameGroupButDifferentComponent()718     public void testAddSameGroupButDifferentComponent() throws Exception {
719         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
720                 Mockito.mock(IConnectionService.class));
721 
722         // By default, there is no default outgoing account (nothing has been registered)
723         assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
724                 PhoneAccount.SCHEME_TEL));
725 
726         // Register one tel: account
727         PhoneAccountHandle telAccount1 = makeQuickAccountHandle("tel_acct1");
728         registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
729                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
730                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
731                 .setGroupId("testGroup")
732                 .build());
733         mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
734         PhoneAccountHandle defaultAccount =
735                 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
736         assertEquals(telAccount1, defaultAccount);
737         assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1));
738 
739         // Register a new account with the same group, but different Component, so don't replace
740         // Default
741         PhoneAccountHandle telAccount2 =  makeQuickAccountHandle(
742                 new ComponentName("other1", "other2"), "tel_acct2");
743         registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2")
744                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
745                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
746                 .setGroupId("testGroup")
747                 .build());
748         assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount2));
749 
750         defaultAccount =
751                 mRegistrar.getUserSelectedOutgoingPhoneAccount(Process.myUserHandle());
752         assertEquals(telAccount1, defaultAccount);
753     }
754 
755     @MediumTest
756     @Test
testAddSameGroupButDifferentComponent2()757     public void testAddSameGroupButDifferentComponent2() throws Exception {
758         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
759                 Mockito.mock(IConnectionService.class));
760 
761         // By default, there is no default outgoing account (nothing has been registered)
762         assertNull(mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
763                 PhoneAccount.SCHEME_TEL));
764 
765         // Register first tel: account
766         PhoneAccountHandle telAccount1 =  makeQuickAccountHandle(
767                 new ComponentName("other1", "other2"), "tel_acct1");
768         registerAndEnableAccount(new PhoneAccount.Builder(telAccount1, "tel_acct1")
769                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
770                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
771                 .setGroupId("testGroup")
772                 .build());
773         assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1));
774         mRegistrar.setUserSelectedOutgoingPhoneAccount(telAccount1, Process.myUserHandle());
775 
776         // Register second account with the same group, but a second Component, so don't replace
777         // Default
778         PhoneAccountHandle telAccount2 = makeQuickAccountHandle("tel_acct2");
779         registerAndEnableAccount(new PhoneAccount.Builder(telAccount2, "tel_acct2")
780                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
781                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
782                 .setGroupId("testGroup")
783                 .build());
784 
785         PhoneAccountHandle defaultAccount =
786                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL);
787         assertEquals(telAccount1, defaultAccount);
788 
789         // Register third account with the second component name, but same group id
790         PhoneAccountHandle telAccount3 = makeQuickAccountHandle("tel_acct3");
791         registerAndEnableAccount(new PhoneAccount.Builder(telAccount3, "tel_acct3")
792                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
793                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
794                 .setGroupId("testGroup")
795                 .build());
796 
797         // Make sure that the default account is still the original PhoneAccount and that the
798         // second PhoneAccount with the second ComponentName was replaced by the third PhoneAccount
799         defaultAccount =
800                 mRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(PhoneAccount.SCHEME_TEL);
801         assertEquals(telAccount1, defaultAccount);
802 
803         assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount1));
804         assertNull(mRegistrar.getPhoneAccountUnchecked(telAccount2));
805         assertNotNull(mRegistrar.getPhoneAccountUnchecked(telAccount3));
806     }
807 
808     @MediumTest
809     @Test
testPhoneAccountParceling()810     public void testPhoneAccountParceling() throws Exception {
811         PhoneAccountHandle handle = makeQuickAccountHandle("foo");
812         roundTripPhoneAccount(new PhoneAccount.Builder(handle, null).build());
813         roundTripPhoneAccount(new PhoneAccount.Builder(handle, "foo").build());
814         roundTripPhoneAccount(
815                 new PhoneAccount.Builder(handle, "foo")
816                         .setAddress(Uri.parse("tel:123456"))
817                         .setCapabilities(23)
818                         .setHighlightColor(0xf0f0f0)
819                         .setIcon(Icon.createWithResource(
820                                 "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call))
821                         // TODO: set icon tint (0xfefefe)
822                         .setShortDescription("short description")
823                         .setSubscriptionAddress(Uri.parse("tel:2345678"))
824                         .setSupportedUriSchemes(Arrays.asList("tel", "sip"))
825                         .setGroupId("testGroup")
826                         .build());
827         roundTripPhoneAccount(
828                 new PhoneAccount.Builder(handle, "foo")
829                         .setAddress(Uri.parse("tel:123456"))
830                         .setCapabilities(23)
831                         .setHighlightColor(0xf0f0f0)
832                         .setIcon(Icon.createWithBitmap(
833                                 BitmapFactory.decodeResource(
834                                         InstrumentationRegistry.getContext().getResources(),
835                                         R.drawable.stat_sys_phone_call)))
836                         .setShortDescription("short description")
837                         .setSubscriptionAddress(Uri.parse("tel:2345678"))
838                         .setSupportedUriSchemes(Arrays.asList("tel", "sip"))
839                         .setGroupId("testGroup")
840                         .build());
841     }
842 
843     /**
844      * Tests ability to register a self-managed PhoneAccount; verifies that the user defined label
845      * is overridden.
846      * @throws Exception
847      */
848     @MediumTest
849     @Test
testSelfManagedPhoneAccount()850     public void testSelfManagedPhoneAccount() throws Exception {
851         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
852                 Mockito.mock(IConnectionService.class));
853 
854         PhoneAccountHandle selfManagedHandle =  makeQuickAccountHandle(
855                 new ComponentName("self", "managed"), "selfie1");
856 
857         PhoneAccount selfManagedAccount = new PhoneAccount.Builder(selfManagedHandle, "Wrong")
858                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
859                 .build();
860 
861         mRegistrar.registerPhoneAccount(selfManagedAccount);
862 
863         PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(selfManagedHandle);
864         assertEquals(TEST_LABEL, registeredAccount.getLabel());
865     }
866 
867     @MediumTest
868     @Test
testSecurityExceptionIsThrownWhenSelfManagedLacksPermissions()869     public void testSecurityExceptionIsThrownWhenSelfManagedLacksPermissions() {
870         PhoneAccountHandle handle = makeQuickAccountHandle(
871                 new ComponentName("self", "managed"), "selfie1");
872 
873         PhoneAccount accountWithoutCapability = new PhoneAccount.Builder(handle, "label")
874                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
875                 .build();
876 
877         assertFalse(mRegistrar.hasTransactionalCallCapabilities(accountWithoutCapability));
878 
879         try {
880             mRegistrar.registerPhoneAccount(accountWithoutCapability);
881             fail("should not be able to register account");
882         } catch (SecurityException securityException) {
883             // test pass
884         } finally {
885             mRegistrar.unregisterPhoneAccount(handle);
886         }
887     }
888 
889     @MediumTest
890     @Test
testSelfManagedPhoneAccountWithTransactionalOperations()891     public void testSelfManagedPhoneAccountWithTransactionalOperations() {
892         PhoneAccountHandle handle = makeQuickAccountHandle(
893                 new ComponentName("self", "managed"), "selfie1");
894 
895         PhoneAccount accountWithCapability = new PhoneAccount.Builder(handle, "label")
896                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
897                         PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS)
898                 .build();
899 
900         assertTrue(mRegistrar.hasTransactionalCallCapabilities(accountWithCapability));
901 
902         try {
903             mRegistrar.registerPhoneAccount(accountWithCapability);
904             PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(handle);
905             assertEquals(TEST_LABEL, registeredAccount.getLabel().toString());
906         } finally {
907             mRegistrar.unregisterPhoneAccount(handle);
908         }
909     }
910 
911     @MediumTest
912     @Test
testRegisterPhoneAccountAmendsSelfManagedCapabilityInternally()913     public void testRegisterPhoneAccountAmendsSelfManagedCapabilityInternally() {
914         // GIVEN
915         PhoneAccountHandle handle = makeQuickAccountHandle(
916                 new ComponentName("self", "managed"), "selfie1");
917         PhoneAccount accountWithCapability = new PhoneAccount.Builder(handle, "label")
918                 .setCapabilities(
919                         PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS)
920                 .build();
921 
922         assertTrue(mRegistrar.hasTransactionalCallCapabilities(accountWithCapability));
923 
924         try {
925             // WHEN
926             mRegistrar.registerPhoneAccount(accountWithCapability);
927             PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(handle);
928             // THEN
929             assertEquals(PhoneAccount.CAPABILITY_SELF_MANAGED, (registeredAccount.getCapabilities()
930                     & PhoneAccount.CAPABILITY_SELF_MANAGED));
931         } finally {
932             mRegistrar.unregisterPhoneAccount(handle);
933         }
934     }
935 
936     /**
937      * Tests to ensure that when registering a self-managed PhoneAccount, it cannot also be defined
938      * as a call provider, connection manager, or sim subscription.
939      * @throws Exception
940      */
941     @MediumTest
942     @Test
testSelfManagedCapabilityOverride()943     public void testSelfManagedCapabilityOverride() throws Exception {
944         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
945                 Mockito.mock(IConnectionService.class));
946 
947         PhoneAccountHandle selfManagedHandle =  makeQuickAccountHandle(
948                 new ComponentName("self", "managed"), "selfie1");
949 
950         PhoneAccount selfManagedAccount = new PhoneAccount.Builder(selfManagedHandle, TEST_LABEL)
951                 .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED |
952                         PhoneAccount.CAPABILITY_CALL_PROVIDER |
953                         PhoneAccount.CAPABILITY_CONNECTION_MANAGER |
954                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
955                 .build();
956 
957         mRegistrar.registerPhoneAccount(selfManagedAccount);
958 
959         PhoneAccount registeredAccount = mRegistrar.getPhoneAccountUnchecked(selfManagedHandle);
960         assertEquals(PhoneAccount.CAPABILITY_SELF_MANAGED, registeredAccount.getCapabilities());
961     }
962 
963     @MediumTest
964     @Test
testSortSimFirst()965     public void testSortSimFirst() throws Exception {
966         ComponentName componentA = new ComponentName("a", "a");
967         ComponentName componentB = new ComponentName("b", "b");
968         mComponentContextFixture.addConnectionService(componentA,
969                 Mockito.mock(IConnectionService.class));
970         mComponentContextFixture.addConnectionService(componentB,
971                 Mockito.mock(IConnectionService.class));
972 
973         PhoneAccount simAccount = new PhoneAccount.Builder(
974                 makeQuickAccountHandle(componentB, "2"), "2")
975                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
976                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
977                 .setIsEnabled(true)
978                 .build();
979 
980         PhoneAccount nonSimAccount = new PhoneAccount.Builder(
981                 makeQuickAccountHandle(componentA, "1"), "1")
982                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
983                 .setIsEnabled(true)
984                 .build();
985 
986         registerAndEnableAccount(nonSimAccount);
987         registerAndEnableAccount(simAccount);
988 
989         List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle(), false);
990         assertTrue(accounts.get(0).getLabel().toString().equals("2"));
991         assertTrue(accounts.get(1).getLabel().toString().equals("1"));
992     }
993 
994     @MediumTest
995     @Test
testSortBySortOrder()996     public void testSortBySortOrder() throws Exception {
997         ComponentName componentA = new ComponentName("a", "a");
998         ComponentName componentB = new ComponentName("b", "b");
999         ComponentName componentC = new ComponentName("c", "c");
1000         mComponentContextFixture.addConnectionService(componentA,
1001                 Mockito.mock(IConnectionService.class));
1002         mComponentContextFixture.addConnectionService(componentB,
1003                 Mockito.mock(IConnectionService.class));
1004         mComponentContextFixture.addConnectionService(componentC,
1005                 Mockito.mock(IConnectionService.class));
1006 
1007         Bundle account1Extras = new Bundle();
1008         account1Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 1);
1009         PhoneAccount account1 = new PhoneAccount.Builder(
1010                 makeQuickAccountHandle(componentA, "c"), "c")
1011                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1012                 .setExtras(account1Extras)
1013                 .build();
1014 
1015         Bundle account2Extras = new Bundle();
1016         account2Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 2);
1017         PhoneAccount account2 = new PhoneAccount.Builder(
1018                 makeQuickAccountHandle(componentB, "b"), "b")
1019                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1020                 .setExtras(account2Extras)
1021                 .build();
1022 
1023         PhoneAccount account3 = new PhoneAccount.Builder(
1024                 makeQuickAccountHandle(componentC, "c"), "a")
1025                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1026                 .build();
1027 
1028         registerAndEnableAccount(account3);
1029         registerAndEnableAccount(account2);
1030         registerAndEnableAccount(account1);
1031 
1032         List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle(), false);
1033         assertTrue(accounts.get(0).getLabel().toString().equals("c"));
1034         assertTrue(accounts.get(1).getLabel().toString().equals("b"));
1035         assertTrue(accounts.get(2).getLabel().toString().equals("a"));
1036     }
1037 
1038     @MediumTest
1039     @Test
testSortByLabel()1040     public void testSortByLabel() throws Exception {
1041         ComponentName componentA = new ComponentName("a", "a");
1042         ComponentName componentB = new ComponentName("b", "b");
1043         ComponentName componentC = new ComponentName("c", "c");
1044         mComponentContextFixture.addConnectionService(componentA,
1045                 Mockito.mock(IConnectionService.class));
1046         mComponentContextFixture.addConnectionService(componentB,
1047                 Mockito.mock(IConnectionService.class));
1048         mComponentContextFixture.addConnectionService(componentC,
1049                 Mockito.mock(IConnectionService.class));
1050 
1051         PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle(componentA, "c"),
1052                 "c")
1053                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1054                 .build();
1055 
1056         PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle(componentB, "b"),
1057                 "b")
1058                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1059                 .build();
1060 
1061         PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle(componentC, "a"),
1062                 "a")
1063                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1064                 .build();
1065 
1066         registerAndEnableAccount(account1);
1067         registerAndEnableAccount(account2);
1068         registerAndEnableAccount(account3);
1069 
1070         List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle(), false);
1071         assertTrue(accounts.get(0).getLabel().toString().equals("a"));
1072         assertTrue(accounts.get(1).getLabel().toString().equals("b"));
1073         assertTrue(accounts.get(2).getLabel().toString().equals("c"));
1074     }
1075 
1076     @MediumTest
1077     @Test
testSortAll()1078     public void testSortAll() throws Exception {
1079         ComponentName componentA = new ComponentName("a", "a");
1080         ComponentName componentB = new ComponentName("b", "b");
1081         ComponentName componentC = new ComponentName("c", "c");
1082         ComponentName componentW = new ComponentName("w", "w");
1083         ComponentName componentX = new ComponentName("x", "x");
1084         ComponentName componentY = new ComponentName("y", "y");
1085         ComponentName componentZ = new ComponentName("z", "z");
1086         mComponentContextFixture.addConnectionService(componentA,
1087                 Mockito.mock(IConnectionService.class));
1088         mComponentContextFixture.addConnectionService(componentB,
1089                 Mockito.mock(IConnectionService.class));
1090         mComponentContextFixture.addConnectionService(componentC,
1091                 Mockito.mock(IConnectionService.class));
1092         mComponentContextFixture.addConnectionService(componentW,
1093                 Mockito.mock(IConnectionService.class));
1094         mComponentContextFixture.addConnectionService(componentX,
1095                 Mockito.mock(IConnectionService.class));
1096         mComponentContextFixture.addConnectionService(componentY,
1097                 Mockito.mock(IConnectionService.class));
1098         mComponentContextFixture.addConnectionService(componentZ,
1099                 Mockito.mock(IConnectionService.class));
1100 
1101         Bundle account1Extras = new Bundle();
1102         account1Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 2);
1103         PhoneAccount account1 = new PhoneAccount.Builder(makeQuickAccountHandle(
1104                 makeQuickConnectionServiceComponentName(), "y"), "y")
1105                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
1106                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
1107                 .setExtras(account1Extras)
1108                 .build();
1109 
1110         Bundle account2Extras = new Bundle();
1111         account2Extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, 1);
1112         PhoneAccount account2 = new PhoneAccount.Builder(makeQuickAccountHandle(
1113                 makeQuickConnectionServiceComponentName(), "z"), "z")
1114                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
1115                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
1116                 .setExtras(account2Extras)
1117                 .build();
1118 
1119         PhoneAccount account3 = new PhoneAccount.Builder(makeQuickAccountHandle(
1120                 makeQuickConnectionServiceComponentName(), "x"), "x")
1121                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
1122                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
1123                 .build();
1124 
1125         PhoneAccount account4 = new PhoneAccount.Builder(makeQuickAccountHandle(
1126                 makeQuickConnectionServiceComponentName(), "w"), "w")
1127                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
1128                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
1129                 .build();
1130 
1131         PhoneAccount account5 = new PhoneAccount.Builder(makeQuickAccountHandle(
1132                 makeQuickConnectionServiceComponentName(), "b"), "b")
1133                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1134                 .build();
1135 
1136         PhoneAccount account6 = new PhoneAccount.Builder(makeQuickAccountHandle(
1137                 makeQuickConnectionServiceComponentName(), "c"), "a")
1138                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1139                 .build();
1140 
1141         registerAndEnableAccount(account1);
1142         registerAndEnableAccount(account2);
1143         registerAndEnableAccount(account3);
1144         registerAndEnableAccount(account4);
1145         registerAndEnableAccount(account5);
1146         registerAndEnableAccount(account6);
1147 
1148         List<PhoneAccount> accounts = mRegistrar.getAllPhoneAccounts(Process.myUserHandle(), false);
1149         // Sim accts ordered by sort order first
1150         assertTrue(accounts.get(0).getLabel().toString().equals("z"));
1151         assertTrue(accounts.get(1).getLabel().toString().equals("y"));
1152 
1153         // Sim accts with no sort order next
1154         assertTrue(accounts.get(2).getLabel().toString().equals("w"));
1155         assertTrue(accounts.get(3).getLabel().toString().equals("x"));
1156 
1157         // Other accts sorted by label next
1158         assertTrue(accounts.get(4).getLabel().toString().equals("a"));
1159         assertTrue(accounts.get(5).getLabel().toString().equals("b"));
1160     }
1161 
1162     /**
1163      * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle)}
1164      * to ensure disabled accounts are filtered out of results when requested.
1165      * @throws Exception
1166      */
1167     @MediumTest
1168     @Test
testGetByEnabledState()1169     public void testGetByEnabledState() throws Exception {
1170         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1171                 Mockito.mock(IConnectionService.class));
1172         mRegistrar.registerPhoneAccount(makeQuickAccountBuilder("id1", 1, null)
1173                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1174                 .build());
1175 
1176         assertEquals(0, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL,
1177                 false /* includeDisabled */, Process.myUserHandle(), false).size());
1178         assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL,
1179                 true /* includeDisabled */, Process.myUserHandle(), false).size());
1180     }
1181 
1182     /**
1183      * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle)}
1184      * to ensure scheme filtering operates.
1185      * @throws Exception
1186      */
1187     @MediumTest
1188     @Test
testGetByScheme()1189     public void testGetByScheme() throws Exception {
1190         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1191                 Mockito.mock(IConnectionService.class));
1192         registerAndEnableAccount(makeQuickAccountBuilder("id1", 1, null)
1193                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1194                 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP))
1195                 .build());
1196         registerAndEnableAccount(makeQuickAccountBuilder("id2", 2, null)
1197                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1198                 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL))
1199                 .build());
1200 
1201         assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP,
1202                 false /* includeDisabled */, Process.myUserHandle(), false).size());
1203         assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_TEL,
1204                 false /* includeDisabled */, Process.myUserHandle(), false).size());
1205         assertEquals(2, mRegistrar.getCallCapablePhoneAccounts(null, false /* includeDisabled */,
1206                 Process.myUserHandle(), false).size());
1207     }
1208 
1209     /**
1210      * Tests {@link PhoneAccountRegistrar#getCallCapablePhoneAccounts(String, boolean, UserHandle,
1211      * int)} to ensure capability filtering operates.
1212      * @throws Exception
1213      */
1214     @MediumTest
1215     @Test
testGetByCapability()1216     public void testGetByCapability() throws Exception {
1217         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1218                 Mockito.mock(IConnectionService.class));
1219         registerAndEnableAccount(makeQuickAccountBuilder("id1", 1, null)
1220                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER
1221                         | PhoneAccount.CAPABILITY_VIDEO_CALLING)
1222                 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP))
1223                 .build());
1224         registerAndEnableAccount(makeQuickAccountBuilder("id2", 2, null)
1225                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
1226                 .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_SIP))
1227                 .build());
1228 
1229         assertEquals(1, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP,
1230                 false /* includeDisabled */, Process.myUserHandle(), false).size(),
1231                 PhoneAccount.CAPABILITY_VIDEO_CALLING);
1232         assertEquals(2, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP,
1233                 false /* includeDisabled */, Process.myUserHandle(), false)
1234                 .size(), 0 /* none extra */);
1235         assertEquals(0, mRegistrar.getCallCapablePhoneAccounts(PhoneAccount.SCHEME_SIP,
1236                 false /* includeDisabled */, Process.myUserHandle(), false).size(),
1237                 PhoneAccount.CAPABILITY_RTT);
1238     }
1239 
1240     /**
1241      * Tests {@link PhoneAccount#equals(Object)} operator.
1242      * @throws Exception
1243      */
1244     @MediumTest
1245     @Test
testPhoneAccountEquality()1246     public void testPhoneAccountEquality() throws Exception {
1247         PhoneAccountHandle handle = new PhoneAccountHandle(new ComponentName("foo", "bar"), "id");
1248         PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, "label");
1249         builder.addSupportedUriScheme("tel");
1250         builder.setAddress(Uri.fromParts("tel", "6505551212", null));
1251         builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER);
1252         Bundle extras = new Bundle();
1253         extras.putInt("INT", 1);
1254         extras.putString("STR", "str");
1255         builder.setExtras(extras);
1256         builder.setGroupId("group");
1257         builder.setHighlightColor(1);
1258         builder.setShortDescription("short");
1259         builder.setSubscriptionAddress(Uri.fromParts("tel", "6505551213", null));
1260         builder.setSupportedAudioRoutes(2);
1261 
1262         PhoneAccount account1 = builder.build();
1263         PhoneAccount account2 = builder.build();
1264         assertEquals(account1, account2);
1265     }
1266 
1267     /**
1268      * Tests {@link PhoneAccountHandle#areFromSamePackage(PhoneAccountHandle,
1269      * PhoneAccountHandle)} comparison.
1270      */
1271     @SmallTest
1272     @Test
testSamePhoneAccountHandlePackage()1273     public void testSamePhoneAccountHandlePackage() {
1274         PhoneAccountHandle a = new PhoneAccountHandle(new ComponentName("packageA", "class1"),
1275                 "id1");
1276         PhoneAccountHandle b = new PhoneAccountHandle(new ComponentName("packageA", "class2"),
1277                 "id2");
1278         PhoneAccountHandle c = new PhoneAccountHandle(new ComponentName("packageA", "class1"),
1279                 "id3");
1280         PhoneAccountHandle d = new PhoneAccountHandle(new ComponentName("packageB", "class1"),
1281                 "id1");
1282 
1283         assertTrue(PhoneAccountHandle.areFromSamePackage(null, null));
1284         assertTrue(PhoneAccountHandle.areFromSamePackage(a, b));
1285         assertTrue(PhoneAccountHandle.areFromSamePackage(a, c));
1286         assertTrue(PhoneAccountHandle.areFromSamePackage(b, c));
1287         assertFalse(PhoneAccountHandle.areFromSamePackage(a, d));
1288         assertFalse(PhoneAccountHandle.areFromSamePackage(b, d));
1289         assertFalse(PhoneAccountHandle.areFromSamePackage(c, d));
1290         assertFalse(PhoneAccountHandle.areFromSamePackage(a, null));
1291         assertFalse(PhoneAccountHandle.areFromSamePackage(b, null));
1292         assertFalse(PhoneAccountHandle.areFromSamePackage(c, null));
1293         assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
1294         assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
1295         assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
1296     }
1297 
1298     /**
1299      * Tests {@link PhoneAccountRegistrar#cleanupOrphanedPhoneAccounts } cleans up / deletes an
1300      * orphan account.
1301      */
1302     @Test
testCleanUpOrphanAccounts()1303     public void testCleanUpOrphanAccounts() throws Exception {
1304         // GIVEN
1305         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1306                 Mockito.mock(IConnectionService.class));
1307         UserManager userManager = mContext.getSystemService(UserManager.class);
1308 
1309         List<UserHandle> users = Arrays.asList(new UserHandle(0),
1310                 new UserHandle(1000));
1311 
1312         PhoneAccount pa1 = new PhoneAccount.Builder(
1313                 new PhoneAccountHandle(new ComponentName(PACKAGE_1, COMPONENT_NAME), "1234",
1314                         users.get(0)), "l1").build();
1315         PhoneAccount pa2 = new PhoneAccount.Builder(
1316                 new PhoneAccountHandle(new ComponentName(PACKAGE_2, COMPONENT_NAME), "5678",
1317                         users.get(1)), "l2").build();
1318 
1319 
1320         registerAndEnableAccount(pa1);
1321         registerAndEnableAccount(pa2);
1322 
1323         assertEquals(1, mRegistrar.getAllPhoneAccounts(users.get(0), false).size());
1324         assertEquals(1, mRegistrar.getAllPhoneAccounts(users.get(1), false).size());
1325 
1326 
1327         // WHEN
1328         when(mContext.getPackageManager().getPackageInfo(PACKAGE_1, 0))
1329                 .thenReturn(new PackageInfo());
1330 
1331         when(mContext.getPackageManager().getPackageInfo(PACKAGE_2, 0))
1332                 .thenThrow(new PackageManager.NameNotFoundException());
1333 
1334         when(userManager.getSerialNumberForUser(users.get(0)))
1335                 .thenReturn(0L);
1336 
1337         when(userManager.getSerialNumberForUser(users.get(1)))
1338                 .thenReturn(-1L);
1339 
1340         // THEN
1341         int deletedAccounts = mRegistrar.cleanupOrphanedPhoneAccounts();
1342         assertEquals(1, deletedAccounts);
1343     }
1344 
1345     @Test
testGetSimPhoneAccountsFromSimCallManager()1346     public void testGetSimPhoneAccountsFromSimCallManager() throws Exception {
1347         // Register the SIM PhoneAccounts
1348         mComponentContextFixture.addConnectionService(
1349                 makeQuickConnectionServiceComponentName(), Mockito.mock(IConnectionService.class));
1350         PhoneAccount sim1Account = makeQuickSimAccount(1);
1351         PhoneAccountHandle sim1Handle = sim1Account.getAccountHandle();
1352         registerAndEnableAccount(sim1Account);
1353         PhoneAccount sim2Account = makeQuickSimAccount(2);
1354         PhoneAccountHandle sim2Handle = sim2Account.getAccountHandle();
1355         registerAndEnableAccount(sim2Account);
1356 
1357         assertEquals(
1358             List.of(sim1Handle, sim2Handle), mRegistrar.getSimPhoneAccountsOfCurrentUser());
1359 
1360         // Set up the SIM call manager app + carrier configs
1361         ComponentName simCallManagerComponent =
1362                 new ComponentName("com.carrier.app", "CarrierConnectionService");
1363         PhoneAccountHandle simCallManagerHandle =
1364                 makeQuickAccountHandle(simCallManagerComponent, "sim-call-manager");
1365         setSimCallManagerCarrierConfig(
1366                 1, new ComponentName("com.other.carrier", "OtherConnectionService"));
1367         setSimCallManagerCarrierConfig(2, simCallManagerComponent);
1368 
1369         // Since SIM 1 names another app, so we only get the handle for SIM 2
1370         assertEquals(
1371                 List.of(sim2Handle),
1372                 mRegistrar.getSimPhoneAccountsFromSimCallManager(simCallManagerHandle));
1373         // We do exact component matching, not just package name matching
1374         assertEquals(
1375                 List.of(),
1376                 mRegistrar.getSimPhoneAccountsFromSimCallManager(
1377                         makeQuickAccountHandle(
1378                                 new ComponentName("com.carrier.app", "SomeOtherUnrelatedService"),
1379                                 "same-pkg-but-diff-svc")));
1380 
1381         // Results are identical after we register the PhoneAccount
1382         mComponentContextFixture.addConnectionService(
1383                 simCallManagerComponent, Mockito.mock(IConnectionService.class));
1384         PhoneAccount simCallManagerAccount =
1385                 new PhoneAccount.Builder(simCallManagerHandle, "SIM call manager")
1386                         .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
1387                         .build();
1388         mRegistrar.registerPhoneAccount(simCallManagerAccount);
1389         assertEquals(
1390                 List.of(sim2Handle),
1391                 mRegistrar.getSimPhoneAccountsFromSimCallManager(simCallManagerHandle));
1392     }
1393 
1394     @Test
testMaybeNotifyTelephonyForVoiceServiceState()1395     public void testMaybeNotifyTelephonyForVoiceServiceState() throws Exception {
1396         // Register the SIM PhoneAccounts
1397         mComponentContextFixture.addConnectionService(
1398                 makeQuickConnectionServiceComponentName(), Mockito.mock(IConnectionService.class));
1399         PhoneAccount sim1Account = makeQuickSimAccount(1);
1400         registerAndEnableAccount(sim1Account);
1401         PhoneAccount sim2Account = makeQuickSimAccount(2);
1402         registerAndEnableAccount(sim2Account);
1403         // Telephony is notified by default when new SIM accounts are registered
1404         verify(mComponentContextFixture.getTelephonyManager(), times(2))
1405                 .setVoiceServiceStateOverride(false);
1406         clearInvocations(mComponentContextFixture.getTelephonyManager());
1407 
1408         // Set up the SIM call manager app + carrier configs
1409         ComponentName simCallManagerComponent =
1410                 new ComponentName("com.carrier.app", "CarrierConnectionService");
1411         PhoneAccountHandle simCallManagerHandle =
1412                 makeQuickAccountHandle(simCallManagerComponent, "sim-call-manager");
1413         mComponentContextFixture.addConnectionService(
1414                 simCallManagerComponent, Mockito.mock(IConnectionService.class));
1415         setSimCallManagerCarrierConfig(1, simCallManagerComponent);
1416         setSimCallManagerCarrierConfig(2, simCallManagerComponent);
1417 
1418         // When the SIM call manager is registered without the SUPPORTS capability, telephony is
1419         // still notified for consistency (e.g. runtime capability removal + re-registration).
1420         PhoneAccount simCallManagerAccount =
1421                 new PhoneAccount.Builder(simCallManagerHandle, "SIM call manager")
1422                         .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
1423                         .build();
1424         mRegistrar.registerPhoneAccount(simCallManagerAccount);
1425         verify(mComponentContextFixture.getTelephonyManager(), times(2))
1426                 .setVoiceServiceStateOverride(false);
1427         clearInvocations(mComponentContextFixture.getTelephonyManager());
1428 
1429         // Adding the SUPPORTS capability causes the SIMs to get notified with false again for
1430         // consistency purposes
1431         simCallManagerAccount =
1432                 copyPhoneAccountAndAddCapabilities(
1433                         simCallManagerAccount,
1434                         PhoneAccount.CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS);
1435         mRegistrar.registerPhoneAccount(simCallManagerAccount);
1436         verify(mComponentContextFixture.getTelephonyManager(), times(2))
1437                 .setVoiceServiceStateOverride(false);
1438         clearInvocations(mComponentContextFixture.getTelephonyManager());
1439 
1440         // Adding the AVAILABLE capability updates the SIMs again, this time with hasService = true
1441         simCallManagerAccount =
1442                 copyPhoneAccountAndAddCapabilities(
1443                         simCallManagerAccount, PhoneAccount.CAPABILITY_VOICE_CALLING_AVAILABLE);
1444         mRegistrar.registerPhoneAccount(simCallManagerAccount);
1445         verify(mComponentContextFixture.getTelephonyManager(), times(2))
1446                 .setVoiceServiceStateOverride(true);
1447         clearInvocations(mComponentContextFixture.getTelephonyManager());
1448 
1449         // Removing a SIM account does nothing, regardless of SIM call manager capabilities
1450         mRegistrar.unregisterPhoneAccount(sim1Account.getAccountHandle());
1451         verify(mComponentContextFixture.getTelephonyManager(), never())
1452                 .setVoiceServiceStateOverride(anyBoolean());
1453         clearInvocations(mComponentContextFixture.getTelephonyManager());
1454 
1455         // Adding a SIM account while a SIM call manager with both capabilities is registered causes
1456         // a call to telephony with hasService = true
1457         mRegistrar.registerPhoneAccount(sim1Account);
1458         verify(mComponentContextFixture.getTelephonyManager(), times(1))
1459                 .setVoiceServiceStateOverride(true);
1460         clearInvocations(mComponentContextFixture.getTelephonyManager());
1461 
1462         // Removing the SIM call manager while it has both capabilities causes a call to telephony
1463         // with hasService = false
1464         mRegistrar.unregisterPhoneAccount(simCallManagerHandle);
1465         verify(mComponentContextFixture.getTelephonyManager(), times(2))
1466                 .setVoiceServiceStateOverride(false);
1467         clearInvocations(mComponentContextFixture.getTelephonyManager());
1468 
1469         // Removing the SIM call manager while it has the SUPPORTS capability but not AVAILABLE
1470         // still causes a call to telephony with hasService = false for consistency
1471         simCallManagerAccount =
1472                 copyPhoneAccountAndRemoveCapabilities(
1473                         simCallManagerAccount, PhoneAccount.CAPABILITY_VOICE_CALLING_AVAILABLE);
1474         mRegistrar.registerPhoneAccount(simCallManagerAccount);
1475         clearInvocations(mComponentContextFixture.getTelephonyManager()); // from re-registration
1476         mRegistrar.unregisterPhoneAccount(simCallManagerHandle);
1477         verify(mComponentContextFixture.getTelephonyManager(), times(2))
1478                 .setVoiceServiceStateOverride(false);
1479         clearInvocations(mComponentContextFixture.getTelephonyManager());
1480 
1481         // Finally, removing the SIM call manager while it has neither capability still causes a
1482         // call to telephony with hasService = false for consistency
1483         simCallManagerAccount =
1484                 copyPhoneAccountAndRemoveCapabilities(
1485                         simCallManagerAccount,
1486                         PhoneAccount.CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS);
1487         mRegistrar.registerPhoneAccount(simCallManagerAccount);
1488         clearInvocations(mComponentContextFixture.getTelephonyManager()); // from re-registration
1489         mRegistrar.unregisterPhoneAccount(simCallManagerHandle);
1490         verify(mComponentContextFixture.getTelephonyManager(), times(2))
1491                 .setVoiceServiceStateOverride(false);
1492         clearInvocations(mComponentContextFixture.getTelephonyManager());
1493     }
1494 
1495     /**
1496      * Test PhoneAccountHandle Migration Logic.
1497      */
1498     @Test
testPhoneAccountMigration()1499     public void testPhoneAccountMigration() throws Exception {
1500         PhoneAccountRegistrar.State testState = makeQuickStateWithTelephonyPhoneAccountHandle();
1501         final int mTestPhoneAccountHandleSubIdInt = 123;
1502         // Mock SubscriptionManager
1503         SubscriptionInfo subscriptionInfo = new SubscriptionInfo(
1504                 mTestPhoneAccountHandleSubIdInt, "id0", 1, "a", "b", 1, 1, "test",
1505                         1, null, null, null, null, false, null, null);
1506         List<SubscriptionInfo> subscriptionInfoList = new ArrayList<>();
1507         subscriptionInfoList.add(subscriptionInfo);
1508         when(mSubscriptionManager.getAllSubscriptionInfoList()).thenReturn(subscriptionInfoList);
1509         mRegistrar.migratePhoneAccountHandle(testState);
1510         Collection<DefaultPhoneAccountHandle> defaultPhoneAccountHandles
1511                 = testState.defaultOutgoingAccountHandles.values();
1512         DefaultPhoneAccountHandle defaultPhoneAccountHandle
1513                 = defaultPhoneAccountHandles.iterator().next();
1514         assertEquals(Integer.toString(mTestPhoneAccountHandleSubIdInt),
1515                 defaultPhoneAccountHandle.phoneAccountHandle.getId());
1516     }
1517 
1518     /**
1519      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1520      * {@link PhoneAccountHandle} with a { PhoneAccountHandle#packageName} that is over the
1521      * character limit set
1522      */
1523     @Test
testInvalidPhoneAccountHandlePackageNameThrowsException()1524     public void testInvalidPhoneAccountHandlePackageNameThrowsException() {
1525         // GIVEN
1526         String invalidPackageName = INVALID_STR;
1527         PhoneAccountHandle handle = makeQuickAccountHandle(
1528                 new ComponentName(invalidPackageName, this.getClass().getName()), TEST_ID);
1529         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle);
1530 
1531         // THEN
1532         try {
1533             PhoneAccount account = builder.build();
1534             assertEquals(invalidPackageName,
1535                     account.getAccountHandle().getComponentName().getPackageName());
1536             mRegistrar.registerPhoneAccount(account);
1537             fail("failed to throw IllegalArgumentException");
1538         } catch (IllegalArgumentException e) {
1539             // pass test
1540         } finally {
1541             mRegistrar.unregisterPhoneAccount(handle);
1542         }
1543     }
1544 
1545     /**
1546      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1547      * {@link PhoneAccountHandle} with a { PhoneAccountHandle#className} that is over the
1548      * character limit set
1549      */
1550     @Test
testInvalidPhoneAccountHandleClassNameThrowsException()1551     public void testInvalidPhoneAccountHandleClassNameThrowsException() {
1552         // GIVEN
1553         String invalidClassName = INVALID_STR;
1554         PhoneAccountHandle handle = makeQuickAccountHandle(
1555                 new ComponentName(this.getClass().getPackageName(), invalidClassName), TEST_ID);
1556         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle);
1557 
1558         // THEN
1559         try {
1560             PhoneAccount account = builder.build();
1561             assertEquals(invalidClassName,
1562                     account.getAccountHandle().getComponentName().getClassName());
1563             mRegistrar.registerPhoneAccount(account);
1564             fail("failed to throw IllegalArgumentException");
1565         } catch (IllegalArgumentException e) {
1566             // pass test
1567         } finally {
1568             mRegistrar.unregisterPhoneAccount(handle);
1569         }
1570     }
1571 
1572     /**
1573      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1574      * {@link PhoneAccountHandle} with a { PhoneAccount#mId} that is over the character limit set
1575      */
1576     @Test
testInvalidPhoneAccountHandleIdThrowsException()1577     public void testInvalidPhoneAccountHandleIdThrowsException() {
1578         // GIVEN
1579         String invalidId = INVALID_STR;
1580         PhoneAccountHandle handle = makeQuickAccountHandle(invalidId);
1581         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle);
1582 
1583         // THEN
1584         try {
1585             PhoneAccount account = builder.build();
1586             assertEquals(invalidId, account.getAccountHandle().getId());
1587             mRegistrar.registerPhoneAccount(account);
1588             fail("failed to throw IllegalArgumentException");
1589         } catch (IllegalArgumentException e) {
1590             // pass test
1591         } finally {
1592             mRegistrar.unregisterPhoneAccount(handle);
1593         }
1594     }
1595 
1596     /**
1597      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1598      * {@link PhoneAccount} with a { PhoneAccount#mLabel} that is over the character limit set
1599      */
1600     @Test
testInvalidLabelThrowsException()1601     public void testInvalidLabelThrowsException() {
1602         // GIVEN
1603         String invalidLabel = INVALID_STR;
1604         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1605         PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, invalidLabel)
1606                 .setCapabilities(PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS);
1607 
1608         // WHEN
1609         when(mAppLabelProxy.getAppLabel(anyString())).thenReturn(invalidLabel);
1610 
1611         // THEN
1612         try {
1613             PhoneAccount account = builder.build();
1614             assertEquals(invalidLabel, account.getLabel());
1615             mRegistrar.registerPhoneAccount(account);
1616             fail("failed to throw IllegalArgumentException");
1617         } catch (IllegalArgumentException e) {
1618             // pass test
1619         } finally {
1620             mRegistrar.unregisterPhoneAccount(handle);
1621         }
1622     }
1623 
1624     /**
1625      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1626      * {@link PhoneAccount} with a {PhoneAccount#mShortDescription} that is over the character
1627      * limit set
1628      */
1629     @Test
testInvalidShortDescriptionThrowsException()1630     public void testInvalidShortDescriptionThrowsException() {
1631         // GIVEN
1632         String invalidShortDescription = INVALID_STR;
1633         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1634         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle)
1635                 .setShortDescription(invalidShortDescription);
1636 
1637         // THEN
1638         try {
1639             PhoneAccount account = builder.build();
1640             assertEquals(invalidShortDescription, account.getShortDescription());
1641             mRegistrar.registerPhoneAccount(account);
1642             fail("failed to throw IllegalArgumentException");
1643         } catch (IllegalArgumentException e) {
1644             // pass test
1645         } finally {
1646             mRegistrar.unregisterPhoneAccount(handle);
1647         }
1648     }
1649 
1650     /**
1651      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1652      * {@link PhoneAccount} with a {PhoneAccount#mGroupId} that is over the character limit set
1653      */
1654     @Test
testInvalidGroupIdThrowsException()1655     public void testInvalidGroupIdThrowsException() {
1656         // GIVEN
1657         String invalidGroupId = INVALID_STR;
1658         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1659         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle)
1660                 .setGroupId(invalidGroupId);
1661 
1662         // THEN
1663         try {
1664             PhoneAccount account = builder.build();
1665             assertEquals(invalidGroupId, account.getGroupId());
1666             mRegistrar.registerPhoneAccount(account);
1667             fail("failed to throw IllegalArgumentException");
1668         } catch (IllegalArgumentException e) {
1669             // pass test
1670         } finally {
1671             mRegistrar.unregisterPhoneAccount(handle);
1672         }
1673     }
1674 
1675     /**
1676      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1677      * {@link PhoneAccount} with a {PhoneAccount#mExtras} that is over the character limit set
1678      */
1679     @Test
testInvalidExtraStringKeyThrowsException()1680     public void testInvalidExtraStringKeyThrowsException() {
1681         // GIVEN
1682         String invalidBundleKey = INVALID_STR;
1683         String keyValue = "value";
1684         Bundle extras = new Bundle();
1685         extras.putString(invalidBundleKey, keyValue);
1686         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1687         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle)
1688                 .setExtras(extras);
1689 
1690         // THEN
1691         try {
1692             PhoneAccount account = builder.build();
1693             assertEquals(keyValue, account.getExtras().getString(invalidBundleKey));
1694             mRegistrar.registerPhoneAccount(account);
1695             fail("failed to throw IllegalArgumentException");
1696         } catch (IllegalArgumentException e) {
1697             // pass test
1698         } finally {
1699             mRegistrar.unregisterPhoneAccount(handle);
1700         }
1701     }
1702 
1703     /**
1704      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1705      * {@link PhoneAccount} with a {PhoneAccount#mExtras} that is over the character limit set
1706      */
1707     @Test
testInvalidExtraStringValueThrowsException()1708     public void testInvalidExtraStringValueThrowsException() {
1709         // GIVEN
1710         String extrasKey = "ExtrasStringKey";
1711         String invalidBundleValue = INVALID_STR;
1712         Bundle extras = new Bundle();
1713         extras.putString(extrasKey, invalidBundleValue);
1714         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1715         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle)
1716                 .setExtras(extras);
1717 
1718         // THEN
1719         try {
1720             PhoneAccount account = builder.build();
1721             assertEquals(invalidBundleValue, account.getExtras().getString(extrasKey));
1722             mRegistrar.registerPhoneAccount(account);
1723             fail("failed to throw IllegalArgumentException");
1724         } catch (IllegalArgumentException e) {
1725             // pass test
1726         } finally {
1727             mRegistrar.unregisterPhoneAccount(handle);
1728         }
1729     }
1730 
1731     /**
1732      * Test that an {@link IllegalArgumentException} is thrown when a package registers a
1733      * {@link PhoneAccount} with a {PhoneAccount#mExtras} that is over the (key,value) pair limit
1734      */
1735     @Test
testInvalidExtraElementsExceedsLimitAndThrowsException()1736     public void testInvalidExtraElementsExceedsLimitAndThrowsException() {
1737         // GIVEN
1738         int invalidBundleExtrasLimit =
1739                 PhoneAccountRegistrar.MAX_PHONE_ACCOUNT_EXTRAS_KEY_PAIR_LIMIT + 1;
1740         Bundle extras = new Bundle();
1741         for (int i = 0; i < invalidBundleExtrasLimit; i++) {
1742             extras.putString(UUID.randomUUID().toString(), "value");
1743         }
1744         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1745         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle)
1746                 .setExtras(extras);
1747         // THEN
1748         try {
1749             PhoneAccount account = builder.build();
1750             assertEquals(invalidBundleExtrasLimit, account.getExtras().size());
1751             mRegistrar.registerPhoneAccount(account);
1752             fail("failed to throw IllegalArgumentException");
1753         } catch (IllegalArgumentException e) {
1754             // Test Pass
1755         } finally {
1756             mRegistrar.unregisterPhoneAccount(handle);
1757         }
1758     }
1759 
1760     /**
1761      * Ensure an IllegalArgumentException is thrown when adding more than 10 schemes for a single
1762      * account
1763      */
1764     @Test
testLimitOnSchemeCount()1765     public void testLimitOnSchemeCount() {
1766         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1767         PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, TEST_LABEL);
1768         for (int i = 0; i < PhoneAccountRegistrar.MAX_PHONE_ACCOUNT_REGISTRATIONS + 1; i++) {
1769             builder.addSupportedUriScheme(Integer.toString(i));
1770         }
1771         try {
1772             mRegistrar.enforceLimitsOnSchemes(builder.build());
1773             fail("should have hit exception in enforceLimitOnSchemes");
1774         } catch (IllegalArgumentException e) {
1775             // pass test
1776         }
1777     }
1778 
1779     /**
1780      * Ensure an IllegalArgumentException is thrown when adding more 256 chars for a single
1781      * account
1782      */
1783     @Test
testLimitOnSchemeLength()1784     public void testLimitOnSchemeLength() {
1785         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1786         PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, TEST_LABEL);
1787         builder.addSupportedUriScheme(INVALID_STR);
1788         try {
1789             mRegistrar.enforceLimitsOnSchemes(builder.build());
1790             fail("should have hit exception in enforceLimitOnSchemes");
1791         } catch (IllegalArgumentException e) {
1792             // pass test
1793         }
1794     }
1795 
1796     /**
1797      * Ensure an IllegalArgumentException is thrown when adding too many PhoneAccountHandles to
1798      * a PhoneAccount.
1799      */
1800     @Test
testLimitOnSimultaneousCallingRestriction_tooManyElements()1801     public void testLimitOnSimultaneousCallingRestriction_tooManyElements() throws Exception {
1802         doReturn(true).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
1803         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1804                 Mockito.mock(IConnectionService.class));
1805         Set<PhoneAccountHandle> tooManyElements = new HashSet<>(11);
1806         for (int i = 0; i < 11; i++) {
1807             tooManyElements.add(makeQuickAccountHandle(TEST_ID + i));
1808         }
1809         PhoneAccount tooManyRestrictionsPA = new PhoneAccount.Builder(
1810                 makeQuickAccountHandle(TEST_ID), TEST_LABEL)
1811                 .setSimultaneousCallingRestriction(tooManyElements)
1812                 .build();
1813         try {
1814             mRegistrar.registerPhoneAccount(tooManyRestrictionsPA);
1815             fail("should have hit registrations exception in "
1816                     + "enforceSimultaneousCallingRestrictionLimit");
1817         } catch (IllegalArgumentException e) {
1818             // pass test
1819         }
1820     }
1821 
1822     /**
1823      * Ensure an IllegalArgumentException is thrown when adding a PhoneAccountHandle where the
1824      * package name field is too large.
1825      */
1826     @Test
testLimitOnSimultaneousCallingRestriction_InvalidPackageName()1827     public void testLimitOnSimultaneousCallingRestriction_InvalidPackageName() throws Exception {
1828         doReturn(true).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
1829         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1830                 Mockito.mock(IConnectionService.class));
1831         Set<PhoneAccountHandle> invalidElement = new HashSet<>(1);
1832         invalidElement.add(new PhoneAccountHandle(new ComponentName(INVALID_STR, "Class"),
1833                 TEST_ID));
1834         PhoneAccount invalidRestrictionPA = new PhoneAccount.Builder(
1835                 makeQuickAccountHandle(TEST_ID), TEST_LABEL)
1836                 .setSimultaneousCallingRestriction(invalidElement)
1837                 .build();
1838         try {
1839             mRegistrar.registerPhoneAccount(invalidRestrictionPA);
1840             fail("should have hit package name size limit exception in "
1841                     + "enforceSimultaneousCallingRestrictionLimit");
1842         } catch (IllegalArgumentException e) {
1843             // pass test
1844         }
1845     }
1846 
1847     /**
1848      * Ensure an IllegalArgumentException is thrown when adding a PhoneAccountHandle where the
1849      * class name field is too large.
1850      */
1851     @Test
testLimitOnSimultaneousCallingRestriction_InvalidClassName()1852     public void testLimitOnSimultaneousCallingRestriction_InvalidClassName() throws Exception {
1853         doReturn(true).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
1854         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1855                 Mockito.mock(IConnectionService.class));
1856         Set<PhoneAccountHandle> invalidElement = new HashSet<>(1);
1857         invalidElement.add(new PhoneAccountHandle(new ComponentName("pkg", INVALID_STR),
1858                 TEST_ID));
1859         PhoneAccount invalidRestrictionPA = new PhoneAccount.Builder(
1860                 makeQuickAccountHandle(TEST_ID), TEST_LABEL)
1861                 .setSimultaneousCallingRestriction(invalidElement)
1862                 .build();
1863         try {
1864             mRegistrar.registerPhoneAccount(invalidRestrictionPA);
1865             fail("should have hit class name size limit exception in "
1866                     + "enforceSimultaneousCallingRestrictionLimit");
1867         } catch (IllegalArgumentException e) {
1868             // pass test
1869         }
1870     }
1871 
1872     /**
1873      * Ensure an IllegalArgumentException is thrown when adding a PhoneAccountHandle where the
1874      * ID field is too large.
1875      */
1876     @Test
testLimitOnSimultaneousCallingRestriction_InvalidIdSize()1877     public void testLimitOnSimultaneousCallingRestriction_InvalidIdSize() throws Exception {
1878         doReturn(true).when(mTelephonyFeatureFlags).simultaneousCallingIndications();
1879         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1880                 Mockito.mock(IConnectionService.class));
1881         Set<PhoneAccountHandle> invalidIdElement = new HashSet<>(1);
1882         invalidIdElement.add(new PhoneAccountHandle(makeQuickConnectionServiceComponentName(),
1883                 INVALID_STR));
1884         PhoneAccount invalidRestrictionPA = new PhoneAccount.Builder(
1885                 makeQuickAccountHandle(TEST_ID), TEST_LABEL)
1886                 .setSimultaneousCallingRestriction(invalidIdElement)
1887                 .build();
1888         try {
1889             mRegistrar.registerPhoneAccount(invalidRestrictionPA);
1890             fail("should have hit ID size limit exception in "
1891                     + "enforceSimultaneousCallingRestrictionLimit");
1892         } catch (IllegalArgumentException e) {
1893             // pass test
1894         }
1895     }
1896 
1897     /**
1898      * Ensure an IllegalArgumentException is thrown when adding an address over the limit
1899      */
1900     @Test
testLimitOnAddress()1901     public void testLimitOnAddress() {
1902         String text = "a".repeat(100);
1903         PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID);
1904         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(handle)
1905                 .setAddress(Uri.fromParts(text, text, text));
1906         try {
1907             mRegistrar.registerPhoneAccount(builder.build());
1908             fail("failed to throw IllegalArgumentException");
1909         } catch (IllegalArgumentException e) {
1910             // pass test
1911         }
1912         finally {
1913             mRegistrar.unregisterPhoneAccount(handle);
1914         }
1915     }
1916 
1917     /**
1918      * Ensure an IllegalArgumentException is thrown when an Icon that throws an IOException is given
1919      */
1920     @Test
testLimitOnIcon()1921     public void testLimitOnIcon() throws Exception {
1922         Icon mockIcon = mock(Icon.class);
1923         // GIVEN
1924         PhoneAccount.Builder builder = makeBuilderWithBindCapabilities(
1925                 makeQuickAccountHandle(TEST_ID)).setIcon(mockIcon);
1926         try {
1927             // WHEN
1928             doThrow(new IOException())
1929                     .when(mockIcon).writeToStream(any(OutputStream.class));
1930             //THEN
1931             mRegistrar.enforceIconSizeLimit(builder.build());
1932             fail("failed to throw IllegalArgumentException");
1933         } catch (IllegalArgumentException e) {
1934             // pass test
1935             assertTrue(e.getMessage().contains(PhoneAccountRegistrar.ICON_ERROR_MSG));
1936         }
1937     }
1938 
1939     /**
1940      * Ensure an IllegalArgumentException is thrown when providing a SubscriptionAddress that
1941      * exceeds the PhoneAccountRegistrar limit.
1942      */
1943     @Test
testLimitOnSubscriptionAddress()1944     public void testLimitOnSubscriptionAddress() throws Exception {
1945         String text = "a".repeat(100);
1946         PhoneAccount.Builder builder =  new PhoneAccount.Builder(makeQuickAccountHandle(TEST_ID),
1947                 TEST_LABEL).setSubscriptionAddress(Uri.fromParts(text, text, text));
1948         try {
1949             mRegistrar.enforceCharacterLimit(builder.build());
1950             fail("failed to throw IllegalArgumentException");
1951         } catch (IllegalArgumentException e) {
1952             // pass test
1953         }
1954     }
1955 
1956     /**
1957      * PhoneAccounts with CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS do not require a
1958      * ConnectionService. Ensure that such an account can be registered and fetched.
1959      */
1960     @Test
testFetchingTransactionalAccounts()1961     public void testFetchingTransactionalAccounts() {
1962         PhoneAccount account = makeBuilderWithBindCapabilities(
1963                 makeQuickAccountHandle(TEST_ID)).build();
1964 
1965         try {
1966             assertEquals(0, mRegistrar.getAllPhoneAccounts(null, true).size());
1967             registerAndEnableAccount(account);
1968             assertEquals(1, mRegistrar.getAllPhoneAccounts(null, true).size());
1969         } finally {
1970             mRegistrar.unregisterPhoneAccount(account.getAccountHandle());
1971         }
1972     }
1973 
1974     @Test
testGetPhoneAccountAcrossUsers()1975     public void testGetPhoneAccountAcrossUsers() throws Exception {
1976         when(mTelephonyFeatureFlags.workProfileApiSplit()).thenReturn(true);
1977         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
1978                 Mockito.mock(IConnectionService.class));
1979 
1980         PhoneAccount accountForCurrent = makeQuickAccountBuilder("id_0", 0, UserHandle.CURRENT)
1981                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
1982                         | PhoneAccount.CAPABILITY_CALL_PROVIDER).build();
1983         PhoneAccount accountForAll = makeQuickAccountBuilder("id_0", 0, UserHandle.ALL)
1984                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
1985                         | PhoneAccount.CAPABILITY_CALL_PROVIDER
1986                         | PhoneAccount.CAPABILITY_MULTI_USER).build();
1987         PhoneAccount accountForWorkProfile = makeQuickAccountBuilder("id_1", 1, USER_HANDLE_10)
1988                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER
1989                         | PhoneAccount.CAPABILITY_CALL_PROVIDER).build();
1990 
1991         registerAndEnableAccount(accountForCurrent);
1992         registerAndEnableAccount(accountForAll);
1993         registerAndEnableAccount(accountForWorkProfile);
1994 
1995         List<PhoneAccount> accountsForUser = mRegistrar.getPhoneAccounts(0, 0,
1996                 null, null, false, USER_HANDLE_10, false, false);
1997         List<PhoneAccount> accountsVisibleUser = mRegistrar.getPhoneAccounts(0, 0,
1998                 null, null, false, USER_HANDLE_10, false, true);
1999         List<PhoneAccount> accountsAcrossUser = mRegistrar.getPhoneAccounts(0, 0,
2000                 null, null, false, USER_HANDLE_10, true, false);
2001 
2002         // Return the account exactly matching the user if it exists
2003         assertEquals(1, accountsForUser.size());
2004         assertTrue(accountsForUser.contains(accountForWorkProfile));
2005         // The accounts visible to the user without across user permission
2006         assertEquals(2, accountsVisibleUser.size());
2007         assertTrue(accountsVisibleUser.containsAll(accountsForUser));
2008         assertTrue(accountsVisibleUser.contains(accountForAll));
2009         // The accounts visible to the user with across user permission
2010         assertEquals(3, accountsAcrossUser.size());
2011         assertTrue(accountsAcrossUser.containsAll(accountsVisibleUser));
2012         assertTrue(accountsAcrossUser.contains(accountForCurrent));
2013 
2014         mRegistrar.unregisterPhoneAccount(accountForWorkProfile.getAccountHandle());
2015 
2016         accountsForUser = mRegistrar.getPhoneAccounts(0, 0,
2017                 null, null, false, USER_HANDLE_10, false, false);
2018 
2019         // Return the account visible for the user if no account exactly matches the user
2020         assertEquals(1, accountsForUser.size());
2021         assertTrue(accountsForUser.contains(accountForAll));
2022     }
2023 
2024     @SmallTest
2025     @Test
testGetSubscriptionIdForPhoneAccountWhenNoTelephony()2026     public void testGetSubscriptionIdForPhoneAccountWhenNoTelephony() throws Exception {
2027         mComponentContextFixture.addConnectionService(makeQuickConnectionServiceComponentName(),
2028                 Mockito.mock(IConnectionService.class));
2029 
2030         PhoneAccount simAccount =
2031                 makeQuickAccountBuilder("simzor", 1, null)
2032                         .setCapabilities(
2033                                 PhoneAccount.CAPABILITY_CALL_PROVIDER
2034                                         | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
2035                         .setIsEnabled(true)
2036                         .build();
2037         registerAndEnableAccount(simAccount);
2038         when(mComponentContextFixture.getTelephonyManager()
2039                 .getSubscriptionId(any(PhoneAccountHandle.class)))
2040                 .thenThrow(new UnsupportedOperationException("Bee-boop"));
2041         assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
2042                 mRegistrar.getSubscriptionIdForPhoneAccount(simAccount.getAccountHandle()));
2043 
2044         // One more thing; we'll test
2045         doThrow(new UnsupportedOperationException("Bee boop!"))
2046                 .when(mComponentContextFixture.getSubscriptionManager())
2047                 .setDefaultVoiceSubscriptionId(anyInt());
2048         mRegistrar.setUserSelectedOutgoingPhoneAccount(simAccount.getAccountHandle(),
2049                 simAccount.getAccountHandle().getUserHandle());
2050 
2051         // There is nothing to verify, we just want to ensure that we didn't crash.
2052     }
2053 
makeBuilderWithBindCapabilities(PhoneAccountHandle handle)2054     private static PhoneAccount.Builder makeBuilderWithBindCapabilities(PhoneAccountHandle handle) {
2055         return new PhoneAccount.Builder(handle, TEST_LABEL)
2056                 .setCapabilities(PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS);
2057     }
2058 
makeQuickConnectionServiceComponentName()2059     private static ComponentName makeQuickConnectionServiceComponentName() {
2060         return new ComponentName(
2061                 "com.android.server.telecom.tests",
2062                 "com.android.server.telecom.tests.MockConnectionService");
2063     }
2064 
makeQuickAccountHandle(String id)2065     private static PhoneAccountHandle makeQuickAccountHandle(String id) {
2066         return makeQuickAccountHandle(makeQuickConnectionServiceComponentName(), id);
2067     }
2068 
makeQuickAccountHandle(ComponentName name, String id)2069     private static PhoneAccountHandle makeQuickAccountHandle(ComponentName name, String id) {
2070         return new PhoneAccountHandle(name, id, Process.myUserHandle());
2071     }
2072 
makeQuickAccountHandleForUser( String id, UserHandle userHandle)2073     private static PhoneAccountHandle makeQuickAccountHandleForUser(
2074             String id, UserHandle userHandle) {
2075         return new PhoneAccountHandle(makeQuickConnectionServiceComponentName(), id, userHandle);
2076     }
2077 
makeQuickAccountBuilder( String id, int idx, UserHandle userHandle)2078     private PhoneAccount.Builder makeQuickAccountBuilder(
2079             String id, int idx, UserHandle userHandle) {
2080         return new PhoneAccount.Builder(
2081                 userHandle == null
2082                         ? makeQuickAccountHandle(id)
2083                         : makeQuickAccountHandleForUser(id, userHandle),
2084                 "label" + idx);
2085     }
2086 
copyPhoneAccountAndOverrideCapabilities( PhoneAccount base, int newCapabilities)2087     private static PhoneAccount copyPhoneAccountAndOverrideCapabilities(
2088             PhoneAccount base, int newCapabilities) {
2089         return base.toBuilder().setCapabilities(newCapabilities).build();
2090     }
2091 
copyPhoneAccountAndAddCapabilities( PhoneAccount base, int capabilitiesToAdd)2092     private static PhoneAccount copyPhoneAccountAndAddCapabilities(
2093             PhoneAccount base, int capabilitiesToAdd) {
2094         return copyPhoneAccountAndOverrideCapabilities(
2095                 base, base.getCapabilities() | capabilitiesToAdd);
2096     }
2097 
copyPhoneAccountAndRemoveCapabilities( PhoneAccount base, int capabilitiesToRemove)2098     private static PhoneAccount copyPhoneAccountAndRemoveCapabilities(
2099             PhoneAccount base, int capabilitiesToRemove) {
2100         return copyPhoneAccountAndOverrideCapabilities(
2101                 base, base.getCapabilities() & ~capabilitiesToRemove);
2102     }
2103 
makeQuickAccount(String id, int idx)2104     private PhoneAccount makeQuickAccount(String id, int idx) {
2105         return makeQuickAccountBuilder(id, idx, null)
2106                 .setAddress(Uri.parse("http://foo.com/" + idx))
2107                 .setSubscriptionAddress(Uri.parse("tel:555-000" + idx))
2108                 .setCapabilities(idx)
2109                 .setIcon(Icon.createWithResource(
2110                             "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call))
2111                 .setShortDescription("desc" + idx)
2112                 .setIsEnabled(true)
2113                 .build();
2114     }
2115 
2116     /**
2117      * Similar to {@link #makeQuickAccount}, but also hooks up {@code TelephonyManager} so that it
2118      * returns {@code simId} as the account's subscriptionId.
2119      */
makeQuickSimAccount(int simId)2120     private PhoneAccount makeQuickSimAccount(int simId) {
2121         PhoneAccount simAccount =
2122                 makeQuickAccountBuilder("sim" + simId, simId, null)
2123                         .setCapabilities(
2124                                 PhoneAccount.CAPABILITY_CALL_PROVIDER
2125                                         | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
2126                         .setIsEnabled(true)
2127                         .build();
2128         when(mComponentContextFixture
2129                         .getTelephonyManager()
2130                         .getSubscriptionId(simAccount.getAccountHandle()))
2131                 .thenReturn(simId);
2132         // mComponentContextFixture already sets up the createForSubscriptionId self-reference
2133         when(mComponentContextFixture
2134                         .getTelephonyManager()
2135                         .createForPhoneAccountHandle(simAccount.getAccountHandle()))
2136                 .thenReturn(mComponentContextFixture.getTelephonyManager());
2137         return simAccount;
2138     }
2139 
2140     /**
2141      * Hooks up carrier config to point to {@code simCallManagerComponent} for the given {@code
2142      * subscriptionId}.
2143      */
setSimCallManagerCarrierConfig( int subscriptionId, @Nullable ComponentName simCallManagerComponent)2144     private void setSimCallManagerCarrierConfig(
2145             int subscriptionId, @Nullable ComponentName simCallManagerComponent) {
2146         PersistableBundle config = new PersistableBundle();
2147         config.putString(
2148                 CarrierConfigManager.KEY_DEFAULT_SIM_CALL_MANAGER_STRING,
2149                 simCallManagerComponent != null ? simCallManagerComponent.flattenToString() : null);
2150         when(mComponentContextFixture.getCarrierConfigManager().getConfigForSubId(subscriptionId))
2151                 .thenReturn(config);
2152     }
2153 
roundTripPhoneAccount(PhoneAccount original)2154     private static void roundTripPhoneAccount(PhoneAccount original) throws Exception {
2155         PhoneAccount copy = null;
2156 
2157         {
2158             Parcel parcel = Parcel.obtain();
2159             parcel.writeParcelable(original, 0);
2160             parcel.setDataPosition(0);
2161             copy = parcel.readParcelable(PhoneAccountRegistrarTest.class.getClassLoader());
2162             parcel.recycle();
2163         }
2164 
2165         assertPhoneAccountEquals(original, copy);
2166     }
2167 
roundTripXml( Object self, T input, PhoneAccountRegistrar.XmlSerialization<T> xml, Context context, FeatureFlags telephonyFeatureFlags, com.android.server.telecom.flags.FeatureFlags telecomFeatureFlags)2168     private static <T> T roundTripXml(
2169             Object self,
2170             T input,
2171             PhoneAccountRegistrar.XmlSerialization<T> xml,
2172             Context context,
2173             FeatureFlags telephonyFeatureFlags,
2174             com.android.server.telecom.flags.FeatureFlags telecomFeatureFlags)
2175             throws Exception {
2176         Log.d(self, "Input = %s", input);
2177 
2178         byte[] data = toXml(input, xml, context, telephonyFeatureFlags);
2179 
2180         Log.i(self, "====== XML data ======\n%s", new String(data));
2181 
2182         T result = fromXml(data, xml, context, telephonyFeatureFlags, telecomFeatureFlags);
2183 
2184         Log.i(self, "result = " + result);
2185 
2186         return result;
2187     }
2188 
toXml(T input, PhoneAccountRegistrar.XmlSerialization<T> xml, Context context, FeatureFlags telephonyFeatureFlags)2189     private static <T> byte[] toXml(T input, PhoneAccountRegistrar.XmlSerialization<T> xml,
2190             Context context, FeatureFlags telephonyFeatureFlags) throws Exception {
2191         XmlSerializer serializer = new FastXmlSerializer();
2192         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2193         serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
2194         xml.writeToXml(input, serializer, context, telephonyFeatureFlags);
2195         serializer.flush();
2196         return baos.toByteArray();
2197     }
2198 
fromXml(byte[] data, PhoneAccountRegistrar.XmlSerialization<T> xml, Context context, FeatureFlags telephonyFeatureFlags, com.android.server.telecom.flags.FeatureFlags telecomFeatureFlags)2199     private static <T> T fromXml(byte[] data, PhoneAccountRegistrar.XmlSerialization<T> xml,
2200             Context context, FeatureFlags telephonyFeatureFlags,
2201             com.android.server.telecom.flags.FeatureFlags telecomFeatureFlags) throws Exception {
2202         XmlPullParser parser = Xml.newPullParser();
2203         parser.setInput(new BufferedInputStream(new ByteArrayInputStream(data)), null);
2204         parser.nextTag();
2205         return xml.readFromXml(parser, MAX_VERSION, context,
2206                 telephonyFeatureFlags, telecomFeatureFlags);
2207 
2208     }
2209 
assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b)2210     private static void assertPhoneAccountHandleEquals(PhoneAccountHandle a, PhoneAccountHandle b) {
2211         if (a != b) {
2212             assertEquals(
2213                     a.getComponentName().getPackageName(),
2214                     b.getComponentName().getPackageName());
2215             assertEquals(
2216                     a.getComponentName().getClassName(),
2217                     b.getComponentName().getClassName());
2218             assertEquals(a.getId(), b.getId());
2219         }
2220     }
2221 
assertIconEquals(Icon a, Icon b)2222     private static void assertIconEquals(Icon a, Icon b) {
2223         if (a != b) {
2224             if (a != null && b != null) {
2225                 assertEquals(a.toString(), b.toString());
2226             } else {
2227                 fail("Icons not equal: " + a + ", " + b);
2228             }
2229         }
2230     }
2231 
assertDefaultPhoneAccountHandleEquals(DefaultPhoneAccountHandle a, DefaultPhoneAccountHandle b)2232     private static void assertDefaultPhoneAccountHandleEquals(DefaultPhoneAccountHandle a,
2233             DefaultPhoneAccountHandle b) {
2234         if (a != b) {
2235             if (a!= null && b != null) {
2236                 assertEquals(a.userHandle, b.userHandle);
2237                 assertPhoneAccountHandleEquals(a.phoneAccountHandle, b.phoneAccountHandle);
2238             } else {
2239                 fail("Default phone account handles are not equal: " + a + ", " + b);
2240             }
2241         }
2242     }
2243 
assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b)2244     private static void assertPhoneAccountEquals(PhoneAccount a, PhoneAccount b) {
2245         if (a != b) {
2246             if (a != null && b != null) {
2247                 assertPhoneAccountHandleEquals(a.getAccountHandle(), b.getAccountHandle());
2248                 assertEquals(a.getAddress(), b.getAddress());
2249                 assertEquals(a.getSubscriptionAddress(), b.getSubscriptionAddress());
2250                 assertEquals(a.getCapabilities(), b.getCapabilities());
2251                 assertIconEquals(a.getIcon(), b.getIcon());
2252                 assertEquals(a.getHighlightColor(), b.getHighlightColor());
2253                 assertEquals(a.getLabel(), b.getLabel());
2254                 assertEquals(a.getShortDescription(), b.getShortDescription());
2255                 assertEquals(a.getSupportedUriSchemes(), b.getSupportedUriSchemes());
2256                 assertBundlesEqual(a.getExtras(), b.getExtras());
2257                 assertEquals(a.isEnabled(), b.isEnabled());
2258                 assertEquals(a.hasSimultaneousCallingRestriction(),
2259                         b.hasSimultaneousCallingRestriction());
2260                 if (a.hasSimultaneousCallingRestriction()) {
2261                     assertEquals(a.getSimultaneousCallingRestriction(),
2262                             b.getSimultaneousCallingRestriction());
2263                 }
2264             } else {
2265                 fail("Phone accounts not equal: " + a + ", " + b);
2266             }
2267         }
2268     }
2269 
assertBundlesEqual(Bundle a, Bundle b)2270     private static void assertBundlesEqual(Bundle a, Bundle b) {
2271         if (a == null && b == null) {
2272             return;
2273         }
2274 
2275         assertNotNull(a);
2276         assertNotNull(b);
2277         Set<String> keySetA = a.keySet();
2278         Set<String> keySetB = b.keySet();
2279 
2280         assertTrue("Bundle keys not the same", keySetA.containsAll(keySetB));
2281         assertTrue("Bundle keys not the same", keySetB.containsAll(keySetA));
2282 
2283         for (String keyA : keySetA) {
2284             assertEquals("Bundle value not the same", a.get(keyA), b.get(keyA));
2285         }
2286     }
2287 
assertStateEquals( PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b)2288     private static void assertStateEquals(
2289             PhoneAccountRegistrar.State a, PhoneAccountRegistrar.State b) {
2290         assertEquals(a.defaultOutgoingAccountHandles.size(),
2291                 b.defaultOutgoingAccountHandles.size());
2292         for (Map.Entry<UserHandle, DefaultPhoneAccountHandle> e :
2293                 a.defaultOutgoingAccountHandles.entrySet()) {
2294             assertDefaultPhoneAccountHandleEquals(e.getValue(),
2295                     b.defaultOutgoingAccountHandles.get(e.getKey()));
2296         }
2297         assertEquals(a.accounts.size(), b.accounts.size());
2298         for (int i = 0; i < a.accounts.size(); i++) {
2299             assertPhoneAccountEquals(a.accounts.get(i), b.accounts.get(i));
2300         }
2301     }
2302 
makeQuickStateWithTelephonyPhoneAccountHandle()2303     private PhoneAccountRegistrar.State makeQuickStateWithTelephonyPhoneAccountHandle() {
2304         UserManager userManager = mContext.getSystemService(UserManager.class);
2305         PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State();
2306         s.accounts.add(makeQuickAccount("id0", 0));
2307         s.accounts.add(makeQuickAccount("id1", 1));
2308         s.accounts.add(makeQuickAccount("id2", 2));
2309         PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(new ComponentName(
2310                 "com.android.phone",
2311                         "com.android.services.telephony.TelephonyConnectionService"), "id0");
2312         UserHandle userHandle = phoneAccountHandle.getUserHandle();
2313         when(userManager.getSerialNumberForUser(userHandle))
2314             .thenReturn(0L);
2315         when(userManager.getUserForSerialNumber(0L))
2316             .thenReturn(userHandle);
2317         s.defaultOutgoingAccountHandles
2318             .put(userHandle, new DefaultPhoneAccountHandle(userHandle, phoneAccountHandle,
2319                 "testGroup"));
2320         return s;
2321     }
2322 
makeQuickState()2323     private PhoneAccountRegistrar.State makeQuickState() {
2324         UserManager userManager = mContext.getSystemService(UserManager.class);
2325         PhoneAccountRegistrar.State s = new PhoneAccountRegistrar.State();
2326         s.accounts.add(makeQuickAccount("id0", 0));
2327         s.accounts.add(makeQuickAccount("id1", 1));
2328         s.accounts.add(makeQuickAccount("id2", 2));
2329         PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(
2330                 new ComponentName("pkg0", "cls0"), "id0");
2331         UserHandle userHandle = phoneAccountHandle.getUserHandle();
2332         when(userManager.getSerialNumberForUser(userHandle))
2333                 .thenReturn(0L);
2334         when(userManager.getUserForSerialNumber(0L))
2335                 .thenReturn(userHandle);
2336         s.defaultOutgoingAccountHandles
2337                 .put(userHandle, new DefaultPhoneAccountHandle(userHandle, phoneAccountHandle,
2338                         "testGroup"));
2339         return s;
2340     }
2341 }
2342