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