TelecomServiceImplTest.java revision b4b190704925898789467a94f041723976558c9b
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.telecom.tests;
18
19import static android.Manifest.permission.CALL_PHONE;
20import static android.Manifest.permission.MODIFY_PHONE_STATE;
21import static android.Manifest.permission.READ_PHONE_STATE;
22import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
23
24import android.app.ActivityManager;
25import android.app.AppOpsManager;
26import android.content.ComponentName;
27import android.content.Context;
28import android.content.Intent;
29import android.content.pm.ApplicationInfo;
30import android.content.pm.PackageManager;
31import android.net.Uri;
32import android.os.Binder;
33import android.os.Bundle;
34import android.os.RemoteException;
35import android.os.UserHandle;
36import android.os.UserManager;
37import android.telecom.PhoneAccount;
38import android.telecom.PhoneAccountHandle;
39import android.telecom.TelecomManager;
40import android.telecom.VideoProfile;
41import android.telephony.TelephonyManager;
42import android.test.suitebuilder.annotation.SmallTest;
43
44import com.android.internal.telecom.ITelecomService;
45import com.android.server.telecom.Call;
46import com.android.server.telecom.CallIntentProcessor;
47import com.android.server.telecom.CallState;
48import com.android.server.telecom.CallsManager;
49import com.android.server.telecom.DefaultDialerCache;
50import com.android.server.telecom.PhoneAccountRegistrar;
51import com.android.server.telecom.TelecomServiceImpl;
52import com.android.server.telecom.TelecomSystem;
53import com.android.server.telecom.components.UserCallIntentProcessor;
54import com.android.server.telecom.components.UserCallIntentProcessorFactory;
55
56import org.mockito.ArgumentCaptor;
57import org.mockito.ArgumentMatcher;
58import org.mockito.Mock;
59import org.mockito.internal.matchers.VarargMatcher;
60
61import java.util.ArrayList;
62import java.util.Collection;
63import java.util.List;
64
65import static android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION;
66import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
67import static org.mockito.Matchers.any;
68import static org.mockito.Matchers.anyBoolean;
69import static org.mockito.Matchers.anyInt;
70import static org.mockito.Matchers.anyString;
71import static org.mockito.Matchers.argThat;
72import static org.mockito.Matchers.eq;
73import static org.mockito.Matchers.isNull;
74import static org.mockito.Mockito.doNothing;
75import static org.mockito.Mockito.doReturn;
76import static org.mockito.Mockito.doThrow;
77import static org.mockito.Mockito.mock;
78import static org.mockito.Mockito.never;
79import static org.mockito.Mockito.spy;
80import static org.mockito.Mockito.verify;
81import static org.mockito.Mockito.when;
82
83public class TelecomServiceImplTest extends TelecomTestCase {
84    public static class CallIntentProcessAdapterFake implements CallIntentProcessor.Adapter {
85        @Override
86        public void processOutgoingCallIntent(Context context, CallsManager callsManager,
87                Intent intent) {
88
89        }
90
91        @Override
92        public void processIncomingCallIntent(CallsManager callsManager, Intent intent) {
93
94        }
95
96        @Override
97        public void processUnknownCallIntent(CallsManager callsManager, Intent intent) {
98
99        }
100    }
101
102    public static class SubscriptionManagerAdapterFake
103            implements TelecomServiceImpl.SubscriptionManagerAdapter {
104        @Override
105        public int getDefaultVoiceSubId() {
106            return 0;
107        }
108    }
109
110    private static class AnyStringIn extends ArgumentMatcher<String> {
111        private Collection<String> mStrings;
112        public AnyStringIn(Collection<String> strings) {
113            this.mStrings = strings;
114        }
115
116        @Override
117        public boolean matches(Object string) {
118            return mStrings.contains(string);
119        }
120    }
121
122    private static class IntVarArgMatcher extends ArgumentMatcher<int[]> implements VarargMatcher {
123        @Override
124        public boolean matches(Object argument) {
125            return true;
126        }
127    }
128
129    private ITelecomService.Stub mTSIBinder;
130    private AppOpsManager mAppOpsManager;
131    private UserManager mUserManager;
132
133    @Mock private CallsManager mFakeCallsManager;
134    @Mock private PhoneAccountRegistrar mFakePhoneAccountRegistrar;
135    @Mock private TelecomManager mTelecomManager;
136    private CallIntentProcessor.Adapter mCallIntentProcessorAdapter =
137            spy(new CallIntentProcessAdapterFake());
138    @Mock private DefaultDialerCache mDefaultDialerCache;
139    private TelecomServiceImpl.SubscriptionManagerAdapter mSubscriptionManagerAdapter =
140            spy(new SubscriptionManagerAdapterFake());
141    @Mock private UserCallIntentProcessor mUserCallIntentProcessor;
142
143    private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };
144
145    private static final String DEFAULT_DIALER_PACKAGE = "com.google.android.dialer";
146    private static final UserHandle USER_HANDLE_16 = new UserHandle(16);
147    private static final UserHandle USER_HANDLE_17 = new UserHandle(17);
148    private static final PhoneAccountHandle TEL_PA_HANDLE_16 = new PhoneAccountHandle(
149            new ComponentName("test", "telComponentName"), "0", USER_HANDLE_16);
150    private static final PhoneAccountHandle SIP_PA_HANDLE_17 = new PhoneAccountHandle(
151            new ComponentName("test", "sipComponentName"), "1", USER_HANDLE_17);
152    private static final PhoneAccountHandle TEL_PA_HANDLE_CURRENT = new PhoneAccountHandle(
153            new ComponentName("test", "telComponentName"), "2", Binder.getCallingUserHandle());
154    private static final PhoneAccountHandle SIP_PA_HANDLE_CURRENT = new PhoneAccountHandle(
155            new ComponentName("test", "sipComponentName"), "3", Binder.getCallingUserHandle());
156
157    @Override
158    public void setUp() throws Exception {
159        super.setUp();
160        mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
161        mComponentContextFixture.putBooleanResource(
162                com.android.internal.R.bool.config_voice_capable, true);
163
164        doReturn(mContext).when(mContext).getApplicationContext();
165        doNothing().when(mContext).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class),
166                anyString());
167        TelecomServiceImpl telecomServiceImpl = new TelecomServiceImpl(
168                mContext,
169                mFakeCallsManager,
170                mFakePhoneAccountRegistrar,
171                mCallIntentProcessorAdapter,
172                new UserCallIntentProcessorFactory() {
173                    @Override
174                    public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
175                        return mUserCallIntentProcessor;
176                    }
177                },
178                mDefaultDialerCache,
179                mSubscriptionManagerAdapter,
180                mLock);
181        mTSIBinder = telecomServiceImpl.getBinder();
182        mComponentContextFixture.setTelecomManager(mTelecomManager);
183        when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
184        when(mTelecomManager.getSystemDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
185
186        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
187        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
188
189        when(mDefaultDialerCache.getDefaultDialerApplication(anyInt()))
190                .thenReturn(DEFAULT_DIALER_PACKAGE);
191        when(mDefaultDialerCache.isDefaultOrSystemDialer(eq(DEFAULT_DIALER_PACKAGE), anyInt()))
192                .thenReturn(true);
193    }
194
195    @SmallTest
196    public void testGetDefaultOutgoingPhoneAccount() throws RemoteException {
197        when(mFakePhoneAccountRegistrar
198                .getOutgoingPhoneAccountForScheme(eq("tel"), any(UserHandle.class)))
199                .thenReturn(TEL_PA_HANDLE_16);
200        when(mFakePhoneAccountRegistrar
201                .getOutgoingPhoneAccountForScheme(eq("sip"), any(UserHandle.class)))
202                .thenReturn(SIP_PA_HANDLE_17);
203        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
204
205        PhoneAccountHandle returnedHandleTel
206                = mTSIBinder.getDefaultOutgoingPhoneAccount("tel", DEFAULT_DIALER_PACKAGE);
207        assertEquals(TEL_PA_HANDLE_16, returnedHandleTel);
208
209        PhoneAccountHandle returnedHandleSip
210                = mTSIBinder.getDefaultOutgoingPhoneAccount("sip", DEFAULT_DIALER_PACKAGE);
211        assertEquals(SIP_PA_HANDLE_17, returnedHandleSip);
212    }
213
214    @SmallTest
215    public void testGetDefaultOutgoingPhoneAccountFailure() throws RemoteException {
216        // make sure that the list of user profiles doesn't include anything the PhoneAccountHandles
217        // are associated with
218
219        when(mFakePhoneAccountRegistrar
220                .getOutgoingPhoneAccountForScheme(eq("tel"), any(UserHandle.class)))
221                .thenReturn(TEL_PA_HANDLE_16);
222        when(mFakePhoneAccountRegistrar.getPhoneAccountUnchecked(TEL_PA_HANDLE_16)).thenReturn(
223                makePhoneAccount(TEL_PA_HANDLE_16).build());
224        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_READ_PHONE_STATE), anyInt(), anyString()))
225                .thenReturn(AppOpsManager.MODE_IGNORED);
226        doThrow(new SecurityException()).when(mContext)
227                .enforceCallingOrSelfPermission(eq(READ_PRIVILEGED_PHONE_STATE), anyString());
228
229        PhoneAccountHandle returnedHandleTel
230                = mTSIBinder.getDefaultOutgoingPhoneAccount("tel", "");
231        assertNull(returnedHandleTel);
232    }
233
234    @SmallTest
235    public void testGetUserSelectedOutgoingPhoneAccount() throws RemoteException {
236        when(mFakePhoneAccountRegistrar.getUserSelectedOutgoingPhoneAccount(any(UserHandle.class)))
237                .thenReturn(TEL_PA_HANDLE_16);
238        when(mFakePhoneAccountRegistrar.getPhoneAccountUnchecked(TEL_PA_HANDLE_16)).thenReturn(
239                makeMultiUserPhoneAccount(TEL_PA_HANDLE_16).build());
240
241        PhoneAccountHandle returnedHandle
242                = mTSIBinder.getUserSelectedOutgoingPhoneAccount();
243        assertEquals(TEL_PA_HANDLE_16, returnedHandle);
244    }
245
246    @SmallTest
247    public void testSetUserSelectedOutgoingPhoneAccount() throws RemoteException {
248        mTSIBinder.setUserSelectedOutgoingPhoneAccount(TEL_PA_HANDLE_16);
249        verify(mFakePhoneAccountRegistrar)
250                .setUserSelectedOutgoingPhoneAccount(eq(TEL_PA_HANDLE_16), any(UserHandle.class));
251    }
252
253    @SmallTest
254    public void testSetUserSelectedOutgoingPhoneAccountFailure() throws RemoteException {
255        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
256                anyString(), anyString());
257        try {
258            mTSIBinder.setUserSelectedOutgoingPhoneAccount(TEL_PA_HANDLE_16);
259        } catch (SecurityException e) {
260            // desired result
261        }
262        verify(mFakePhoneAccountRegistrar, never())
263                .setUserSelectedOutgoingPhoneAccount(
264                        any(PhoneAccountHandle.class), any(UserHandle.class));
265    }
266
267    @SmallTest
268    public void testGetCallCapablePhoneAccounts() throws RemoteException {
269        List<PhoneAccountHandle> fullPHList = new ArrayList<PhoneAccountHandle>() {{
270            add(TEL_PA_HANDLE_16);
271            add(SIP_PA_HANDLE_17);
272        }};
273
274        List<PhoneAccountHandle> smallPHList = new ArrayList<PhoneAccountHandle>() {{
275            add(SIP_PA_HANDLE_17);
276        }};
277        // Returns all phone accounts when getCallCapablePhoneAccounts is called.
278        when(mFakePhoneAccountRegistrar
279                .getCallCapablePhoneAccounts(anyString(), eq(true), any(UserHandle.class)))
280                .thenReturn(fullPHList);
281        // Returns only enabled phone accounts when getCallCapablePhoneAccounts is called.
282        when(mFakePhoneAccountRegistrar
283                .getCallCapablePhoneAccounts(anyString(), eq(false), any(UserHandle.class)))
284                .thenReturn(smallPHList);
285        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
286
287        assertEquals(fullPHList,
288                mTSIBinder.getCallCapablePhoneAccounts(true, DEFAULT_DIALER_PACKAGE));
289        assertEquals(smallPHList,
290                mTSIBinder.getCallCapablePhoneAccounts(false, DEFAULT_DIALER_PACKAGE));
291    }
292
293    @SmallTest
294    public void testGetCallCapablePhoneAccountsFailure() throws RemoteException {
295        List<String> enforcedPermissions = new ArrayList<String>() {{
296            add(READ_PHONE_STATE);
297            add(READ_PRIVILEGED_PHONE_STATE);
298        }};
299        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
300                argThat(new AnyStringIn(enforcedPermissions)), anyString());
301
302        List<PhoneAccountHandle> result = null;
303        try {
304            result = mTSIBinder.getCallCapablePhoneAccounts(true, "");
305        } catch (SecurityException e) {
306            // intended behavior
307        }
308        assertNull(result);
309        verify(mFakePhoneAccountRegistrar, never())
310                .getCallCapablePhoneAccounts(anyString(), anyBoolean(), any(UserHandle.class));
311    }
312
313    @SmallTest
314    public void testGetPhoneAccountsSupportingScheme() throws RemoteException {
315        List<PhoneAccountHandle> sipPHList = new ArrayList<PhoneAccountHandle>() {{
316            add(SIP_PA_HANDLE_17);
317        }};
318
319        List<PhoneAccountHandle> telPHList = new ArrayList<PhoneAccountHandle>() {{
320            add(TEL_PA_HANDLE_16);
321        }};
322        when(mFakePhoneAccountRegistrar
323                .getCallCapablePhoneAccounts(eq("tel"), anyBoolean(), any(UserHandle.class)))
324                .thenReturn(telPHList);
325        when(mFakePhoneAccountRegistrar
326                .getCallCapablePhoneAccounts(eq("sip"), anyBoolean(), any(UserHandle.class)))
327                .thenReturn(sipPHList);
328        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
329
330        assertEquals(telPHList,
331                mTSIBinder.getPhoneAccountsSupportingScheme("tel", DEFAULT_DIALER_PACKAGE));
332        assertEquals(sipPHList,
333                mTSIBinder.getPhoneAccountsSupportingScheme("sip", DEFAULT_DIALER_PACKAGE));
334    }
335
336    @SmallTest
337    public void testGetPhoneAccountsForPackage() throws RemoteException {
338        List<PhoneAccountHandle> phoneAccountHandleList = new ArrayList<PhoneAccountHandle>() {{
339            add(TEL_PA_HANDLE_16);
340            add(SIP_PA_HANDLE_17);
341        }};
342        when(mFakePhoneAccountRegistrar
343                .getPhoneAccountsForPackage(anyString(), any(UserHandle.class)))
344                .thenReturn(phoneAccountHandleList);
345        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
346        assertEquals(phoneAccountHandleList,
347                mTSIBinder.getPhoneAccountsForPackage(
348                        TEL_PA_HANDLE_16.getComponentName().getPackageName()));
349    }
350
351    @SmallTest
352    public void testGetPhoneAccount() throws RemoteException {
353        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17);
354        assertEquals(TEL_PA_HANDLE_16, mTSIBinder.getPhoneAccount(TEL_PA_HANDLE_16)
355                .getAccountHandle());
356        assertEquals(SIP_PA_HANDLE_17, mTSIBinder.getPhoneAccount(SIP_PA_HANDLE_17)
357                .getAccountHandle());
358    }
359
360    @SmallTest
361    public void testGetAllPhoneAccounts() throws RemoteException {
362        List<PhoneAccount> phoneAccountList = new ArrayList<PhoneAccount>() {{
363            add(makePhoneAccount(TEL_PA_HANDLE_16).build());
364            add(makePhoneAccount(SIP_PA_HANDLE_17).build());
365        }};
366        when(mFakePhoneAccountRegistrar.getAllPhoneAccounts(any(UserHandle.class)))
367                .thenReturn(phoneAccountList);
368
369        assertEquals(2, mTSIBinder.getAllPhoneAccounts().size());
370    }
371
372    @SmallTest
373    public void testRegisterPhoneAccount() throws RemoteException {
374        String packageNameToUse = "com.android.officialpackage";
375        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
376                packageNameToUse, "cs"), "test", Binder.getCallingUserHandle());
377        PhoneAccount phoneAccount = makePhoneAccount(phHandle).build();
378        doReturn(PackageManager.PERMISSION_GRANTED)
379                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
380
381        registerPhoneAccountTestHelper(phoneAccount, true);
382    }
383
384    @SmallTest
385    public void testRegisterPhoneAccountWithoutModifyPermission() throws RemoteException {
386        // tests the case where the package does not have MODIFY_PHONE_STATE but is
387        // registering its own phone account as a third-party connection service
388        String packageNameToUse = "com.thirdparty.connectionservice";
389        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
390                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
391        PhoneAccount phoneAccount = makePhoneAccount(phHandle).build();
392
393        doReturn(PackageManager.PERMISSION_DENIED)
394                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
395        PackageManager pm = mContext.getPackageManager();
396        when(pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE)).thenReturn(true);
397
398        registerPhoneAccountTestHelper(phoneAccount, true);
399    }
400
401    @SmallTest
402    public void testRegisterPhoneAccountWithoutModifyPermissionFailure() throws RemoteException {
403        // tests the case where the third party package should not be allowed to register a phone
404        // account due to the lack of modify permission.
405        String packageNameToUse = "com.thirdparty.connectionservice";
406        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
407                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
408        PhoneAccount phoneAccount = makePhoneAccount(phHandle).build();
409
410        doReturn(PackageManager.PERMISSION_DENIED)
411                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
412        PackageManager pm = mContext.getPackageManager();
413        when(pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE)).thenReturn(false);
414
415        registerPhoneAccountTestHelper(phoneAccount, false);
416    }
417
418    @SmallTest
419    public void testRegisterPhoneAccountWithoutSimSubscriptionPermissionFailure()
420            throws RemoteException {
421        String packageNameToUse = "com.thirdparty.connectionservice";
422        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
423                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
424        PhoneAccount phoneAccount = makePhoneAccount(phHandle)
425                .setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION).build();
426
427        doReturn(PackageManager.PERMISSION_GRANTED)
428                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
429        doThrow(new SecurityException())
430                .when(mContext)
431                .enforceCallingOrSelfPermission(eq(REGISTER_SIM_SUBSCRIPTION), anyString());
432
433        registerPhoneAccountTestHelper(phoneAccount, false);
434    }
435
436    @SmallTest
437    public void testRegisterPhoneAccountWithoutMultiUserPermissionFailure()
438            throws Exception {
439        String packageNameToUse = "com.thirdparty.connectionservice";
440        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
441                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
442        PhoneAccount phoneAccount = makeMultiUserPhoneAccount(phHandle).build();
443
444        doReturn(PackageManager.PERMISSION_GRANTED)
445                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
446
447        PackageManager packageManager = mContext.getPackageManager();
448        when(packageManager.getApplicationInfo(packageNameToUse, PackageManager.GET_META_DATA))
449                .thenReturn(new ApplicationInfo());
450
451        registerPhoneAccountTestHelper(phoneAccount, false);
452    }
453
454    private void registerPhoneAccountTestHelper(PhoneAccount testPhoneAccount,
455            boolean shouldSucceed) throws RemoteException {
456        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
457        boolean didExceptionOccur = false;
458        try {
459            mTSIBinder.registerPhoneAccount(testPhoneAccount);
460        } catch (Exception e) {
461            didExceptionOccur = true;
462        }
463
464        if (shouldSucceed) {
465            assertFalse(didExceptionOccur);
466            verify(mFakePhoneAccountRegistrar).registerPhoneAccount(testPhoneAccount);
467            verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
468                    anyString());
469
470            Intent capturedIntent = intentCaptor.getValue();
471            assertEquals(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED,
472                    capturedIntent.getAction());
473            Bundle intentExtras = capturedIntent.getExtras();
474            assertEquals(1, intentExtras.size());
475            assertEquals(testPhoneAccount.getAccountHandle(),
476                    intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
477        } else {
478            assertTrue(didExceptionOccur);
479            verify(mFakePhoneAccountRegistrar, never())
480                    .registerPhoneAccount(any(PhoneAccount.class));
481            verify(mContext, never())
482                    .sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), anyString());
483        }
484    }
485
486    @SmallTest
487    public void testUnregisterPhoneAccount() throws RemoteException {
488        String packageNameToUse = "com.android.officialpackage";
489        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
490                packageNameToUse, "cs"), "test", Binder.getCallingUserHandle());
491
492        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
493        doReturn(PackageManager.PERMISSION_GRANTED)
494                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
495
496        mTSIBinder.unregisterPhoneAccount(phHandle);
497        verify(mFakePhoneAccountRegistrar).unregisterPhoneAccount(phHandle);
498        verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
499                anyString());
500        Intent capturedIntent = intentCaptor.getValue();
501        assertEquals(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED,
502                capturedIntent.getAction());
503        Bundle intentExtras = capturedIntent.getExtras();
504        assertEquals(1, intentExtras.size());
505        assertEquals(phHandle, intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
506    }
507
508    @SmallTest
509    public void testUnregisterPhoneAccountFailure() throws RemoteException {
510        String packageNameToUse = "com.thirdparty.connectionservice";
511        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
512                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
513
514        doReturn(PackageManager.PERMISSION_DENIED)
515                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
516        PackageManager pm = mContext.getPackageManager();
517        when(pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE)).thenReturn(false);
518
519        try {
520            mTSIBinder.unregisterPhoneAccount(phHandle);
521        } catch (UnsupportedOperationException e) {
522            // expected behavior
523        }
524        verify(mFakePhoneAccountRegistrar, never())
525                .unregisterPhoneAccount(any(PhoneAccountHandle.class));
526        verify(mContext, never())
527                .sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), anyString());
528    }
529
530    @SmallTest
531    public void testAddNewIncomingCall() throws Exception {
532        PhoneAccount phoneAccount = makePhoneAccount(TEL_PA_HANDLE_CURRENT).build();
533        phoneAccount.setIsEnabled(true);
534        doReturn(phoneAccount).when(mFakePhoneAccountRegistrar).getPhoneAccount(
535                eq(TEL_PA_HANDLE_CURRENT), any(UserHandle.class));
536        doNothing().when(mAppOpsManager).checkPackage(anyInt(), anyString());
537        Bundle extras = createSampleExtras();
538
539        mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_CURRENT, extras);
540
541        addCallTestHelper(TelecomManager.ACTION_INCOMING_CALL,
542                CallIntentProcessor.KEY_IS_INCOMING_CALL, extras, false);
543    }
544
545    @SmallTest
546    public void testAddNewIncomingCallFailure() throws Exception {
547        try {
548            mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_16, null);
549        } catch (SecurityException e) {
550            // expected
551        }
552
553        doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
554
555        try {
556            mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_CURRENT, null);
557        } catch (SecurityException e) {
558            // expected
559        }
560
561        // Verify that neither of these attempts got through
562        verify(mCallIntentProcessorAdapter, never())
563                .processIncomingCallIntent(any(CallsManager.class), any(Intent.class));
564    }
565
566    @SmallTest
567    public void testAddNewUnknownCall() throws Exception {
568        PhoneAccount phoneAccount = makePhoneAccount(TEL_PA_HANDLE_CURRENT).build();
569        phoneAccount.setIsEnabled(true);
570        doReturn(phoneAccount).when(mFakePhoneAccountRegistrar).getPhoneAccount(
571                eq(TEL_PA_HANDLE_CURRENT), any(UserHandle.class));
572        doNothing().when(mAppOpsManager).checkPackage(anyInt(), anyString());
573        Bundle extras = createSampleExtras();
574
575        mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_CURRENT, extras);
576
577        addCallTestHelper(TelecomManager.ACTION_NEW_UNKNOWN_CALL,
578                CallIntentProcessor.KEY_IS_UNKNOWN_CALL, extras, true);
579    }
580
581    @SmallTest
582    public void testAddNewUnknownCallFailure() throws Exception {
583        try {
584            mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_16, null);
585        } catch (SecurityException e) {
586            // expected
587        }
588
589        doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
590
591        try {
592            mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_CURRENT, null);
593        } catch (SecurityException e) {
594            // expected
595        }
596
597        // Verify that neither of these attempts got through
598        verify(mCallIntentProcessorAdapter, never())
599                .processIncomingCallIntent(any(CallsManager.class), any(Intent.class));
600    }
601
602    private void addCallTestHelper(String expectedAction, String extraCallKey,
603            Bundle expectedExtras, boolean isUnknown) {
604        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
605        if (isUnknown) {
606            verify(mCallIntentProcessorAdapter).processUnknownCallIntent(any(CallsManager.class),
607                    intentCaptor.capture());
608        } else {
609            verify(mCallIntentProcessorAdapter).processIncomingCallIntent(any(CallsManager.class),
610                    intentCaptor.capture());
611        }
612        Intent capturedIntent = intentCaptor.getValue();
613        assertEquals(expectedAction, capturedIntent.getAction());
614        Bundle intentExtras = capturedIntent.getExtras();
615        assertEquals(TEL_PA_HANDLE_CURRENT,
616                intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
617        assertTrue(intentExtras.getBoolean(extraCallKey));
618
619        if (isUnknown) {
620            for (String expectedKey : expectedExtras.keySet()) {
621                assertTrue(intentExtras.containsKey(expectedKey));
622                assertEquals(expectedExtras.get(expectedKey), intentExtras.get(expectedKey));
623            }
624        }
625        else {
626            assertTrue(areBundlesEqual(expectedExtras,
627                    (Bundle) intentExtras.get(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS)));
628        }
629    }
630
631    @SmallTest
632    public void testPlaceCallWithNonEmergencyPermission() throws Exception {
633        Uri handle = Uri.parse("tel:6505551234");
634        Bundle extras = createSampleExtras();
635
636        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
637                .thenReturn(AppOpsManager.MODE_ALLOWED);
638        doReturn(PackageManager.PERMISSION_GRANTED)
639                .when(mContext).checkCallingPermission(CALL_PHONE);
640
641        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
642        placeCallTestHelper(handle, extras, true);
643    }
644
645    @SmallTest
646    public void testPlaceCallWithAppOpsOff() throws Exception {
647        Uri handle = Uri.parse("tel:6505551234");
648        Bundle extras = createSampleExtras();
649
650        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
651                .thenReturn(AppOpsManager.MODE_IGNORED);
652        doReturn(PackageManager.PERMISSION_GRANTED)
653                .when(mContext).checkCallingPermission(CALL_PHONE);
654
655        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
656        placeCallTestHelper(handle, extras, false);
657    }
658
659    @SmallTest
660    public void testPlaceCallWithNoCallingPermission() throws Exception {
661        Uri handle = Uri.parse("tel:6505551234");
662        Bundle extras = createSampleExtras();
663
664        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
665                .thenReturn(AppOpsManager.MODE_ALLOWED);
666        doReturn(PackageManager.PERMISSION_DENIED)
667                .when(mContext).checkCallingPermission(CALL_PHONE);
668
669        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
670        placeCallTestHelper(handle, extras, false);
671    }
672
673    private void placeCallTestHelper(Uri expectedHandle, Bundle expectedExtras,
674            boolean shouldNonEmergencyBeAllowed) {
675        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
676        verify(mUserCallIntentProcessor).processIntent(intentCaptor.capture(), anyString(),
677                eq(shouldNonEmergencyBeAllowed));
678        Intent capturedIntent = intentCaptor.getValue();
679        assertEquals(Intent.ACTION_CALL, capturedIntent.getAction());
680        assertEquals(expectedHandle, capturedIntent.getData());
681        assertTrue(areBundlesEqual(expectedExtras, capturedIntent.getExtras()));
682    }
683
684    @SmallTest
685    public void testPlaceCallFailure() throws Exception {
686        Uri handle = Uri.parse("tel:6505551234");
687        Bundle extras = createSampleExtras();
688
689        doThrow(new SecurityException())
690                .when(mContext).enforceCallingOrSelfPermission(eq(CALL_PHONE), anyString());
691
692        try {
693            mTSIBinder.placeCall(handle, extras, "arbitrary_package_name");
694        } catch (SecurityException e) {
695            // expected
696        }
697
698        verify(mUserCallIntentProcessor, never())
699                .processIntent(any(Intent.class), anyString(), anyBoolean());
700    }
701
702    @SmallTest
703    public void testSetDefaultDialer() throws Exception {
704        String packageName = "sample.package";
705        int currentUser = ActivityManager.getCurrentUser();
706
707        when(mDefaultDialerCache.setDefaultDialer(eq(packageName), eq(currentUser)))
708                .thenReturn(true);
709
710        mTSIBinder.setDefaultDialer(packageName);
711
712        verify(mDefaultDialerCache).setDefaultDialer(eq(packageName), eq(currentUser));
713        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
714        verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), any(UserHandle.class));
715        Intent capturedIntent = intentCaptor.getValue();
716        assertEquals(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED, capturedIntent.getAction());
717        String packageNameExtra = capturedIntent.getStringExtra(
718                TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME);
719        assertEquals(packageName, packageNameExtra);
720    }
721
722    @SmallTest
723    public void testSetDefaultDialerNoModifyPhoneStatePermission() throws Exception {
724        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
725                eq(MODIFY_PHONE_STATE), anyString());
726        setDefaultDialerFailureTestHelper();
727    }
728
729    @SmallTest
730    public void testSetDefaultDialerNoWriteSecureSettingsPermission() throws Exception {
731        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
732                eq(WRITE_SECURE_SETTINGS), anyString());
733        setDefaultDialerFailureTestHelper();
734    }
735
736    private void setDefaultDialerFailureTestHelper() throws Exception {
737        boolean exceptionThrown = false;
738        try {
739            mTSIBinder.setDefaultDialer(DEFAULT_DIALER_PACKAGE);
740        } catch (SecurityException e) {
741            exceptionThrown = true;
742        }
743        assertTrue(exceptionThrown);
744        verify(mDefaultDialerCache, never()).setDefaultDialer(anyString(), anyInt());
745        verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class));
746    }
747
748    @SmallTest
749    public void testIsVoicemailNumber() throws Exception {
750        String vmNumber = "010";
751        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_CURRENT);
752
753        doReturn(true).when(mFakePhoneAccountRegistrar).isVoiceMailNumber(TEL_PA_HANDLE_CURRENT,
754                vmNumber);
755        assertTrue(mTSIBinder.isVoiceMailNumber(TEL_PA_HANDLE_CURRENT,
756                vmNumber, DEFAULT_DIALER_PACKAGE));
757    }
758
759    @SmallTest
760    public void testIsVoicemailNumberAccountNotVisibleFailure() throws Exception {
761        String vmNumber = "010";
762
763        doReturn(true).when(mFakePhoneAccountRegistrar).isVoiceMailNumber(TEL_PA_HANDLE_CURRENT,
764                vmNumber);
765
766        when(mFakePhoneAccountRegistrar.getPhoneAccount(TEL_PA_HANDLE_CURRENT,
767                Binder.getCallingUserHandle())).thenReturn(null);
768        assertFalse(mTSIBinder
769                .isVoiceMailNumber(TEL_PA_HANDLE_CURRENT, vmNumber, DEFAULT_DIALER_PACKAGE));
770    }
771
772    @SmallTest
773    public void testGetVoicemailNumberWithNullAccountHandle() throws Exception {
774        when(mFakePhoneAccountRegistrar.getPhoneAccount(isNull(PhoneAccountHandle.class),
775                eq(Binder.getCallingUserHandle())))
776                .thenReturn(makePhoneAccount(TEL_PA_HANDLE_CURRENT).build());
777        int subId = 58374;
778        String vmNumber = "543";
779        doReturn(subId).when(mSubscriptionManagerAdapter).getDefaultVoiceSubId();
780
781        TelephonyManager mockTelephonyManager =
782                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
783        when(mockTelephonyManager.getVoiceMailNumber(subId)).thenReturn(vmNumber);
784
785        assertEquals(vmNumber, mTSIBinder.getVoiceMailNumber(null, DEFAULT_DIALER_PACKAGE));
786    }
787
788    @SmallTest
789    public void testGetVoicemailNumberWithNonNullAccountHandle() throws Exception {
790        when(mFakePhoneAccountRegistrar.getPhoneAccount(eq(TEL_PA_HANDLE_CURRENT),
791                eq(Binder.getCallingUserHandle())))
792                .thenReturn(makePhoneAccount(TEL_PA_HANDLE_CURRENT).build());
793        int subId = 58374;
794        String vmNumber = "543";
795
796        TelephonyManager mockTelephonyManager =
797                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
798        when(mockTelephonyManager.getVoiceMailNumber(subId)).thenReturn(vmNumber);
799        when(mFakePhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(TEL_PA_HANDLE_CURRENT))
800                .thenReturn(subId);
801
802        assertEquals(vmNumber,
803                mTSIBinder.getVoiceMailNumber(TEL_PA_HANDLE_CURRENT, DEFAULT_DIALER_PACKAGE));
804    }
805
806    @SmallTest
807    public void testGetLine1Number() throws Exception {
808        int subId = 58374;
809        String line1Number = "9482752023479";
810        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_CURRENT);
811        when(mFakePhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(TEL_PA_HANDLE_CURRENT))
812                .thenReturn(subId);
813        TelephonyManager mockTelephonyManager =
814                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
815        when(mockTelephonyManager.getLine1Number(subId)).thenReturn(line1Number);
816
817        assertEquals(line1Number,
818                mTSIBinder.getLine1Number(TEL_PA_HANDLE_CURRENT, DEFAULT_DIALER_PACKAGE));
819    }
820
821    @SmallTest
822    public void testEndCallWithRingingForegroundCall() throws Exception {
823        Call call = mock(Call.class);
824        when(call.getState()).thenReturn(CallState.RINGING);
825        when(mFakeCallsManager.getForegroundCall()).thenReturn(call);
826        assertTrue(mTSIBinder.endCall());
827        verify(call).reject(false, null);
828    }
829
830    @SmallTest
831    public void testEndCallWithNonRingingForegroundCall() throws Exception {
832        Call call = mock(Call.class);
833        when(call.getState()).thenReturn(CallState.ACTIVE);
834        when(mFakeCallsManager.getForegroundCall()).thenReturn(call);
835        assertTrue(mTSIBinder.endCall());
836        verify(call).disconnect();
837    }
838
839    @SmallTest
840    public void testEndCallWithNoForegroundCall() throws Exception {
841        Call call = mock(Call.class);
842        when(call.getState()).thenReturn(CallState.ACTIVE);
843        when(mFakeCallsManager.getFirstCallWithState(argThat(new IntVarArgMatcher())))
844                .thenReturn(call);
845        assertTrue(mTSIBinder.endCall());
846        verify(call).disconnect();
847    }
848
849    @SmallTest
850    public void testEndCallWithNoCalls() throws Exception {
851        assertFalse(mTSIBinder.endCall());
852    }
853
854    @SmallTest
855    public void testAcceptRingingCall() throws Exception {
856        Call call = mock(Call.class);
857        when(mFakeCallsManager.getFirstCallWithState(any(int[].class)))
858                .thenReturn(call);
859        // Not intended to be a real video state. Here to ensure that the call will be answered
860        // with whatever video state it's currently in.
861        int fakeVideoState = 29578215;
862        when(call.getVideoState()).thenReturn(fakeVideoState);
863        mTSIBinder.acceptRingingCall();
864        verify(call).answer(fakeVideoState);
865    }
866
867    @SmallTest
868    public void testAcceptRingingCallWithValidVideoState() throws Exception {
869        Call call = mock(Call.class);
870        when(mFakeCallsManager.getFirstCallWithState(any(int[].class)))
871                .thenReturn(call);
872        // Not intended to be a real video state. Here to ensure that the call will be answered
873        // with the video state passed in to acceptRingingCallWithVideoState
874        int fakeVideoState = 29578215;
875        int realVideoState = VideoProfile.STATE_RX_ENABLED | VideoProfile.STATE_TX_ENABLED;
876        when(call.getVideoState()).thenReturn(fakeVideoState);
877        mTSIBinder.acceptRingingCallWithVideoState(realVideoState);
878        verify(call).answer(realVideoState);
879    }
880
881    /**
882     * Register phone accounts for the supplied PhoneAccountHandles to make them
883     * visible to all users (via the isVisibleToCaller method in TelecomServiceImpl.
884     * @param handles the handles for which phone accounts should be created for.
885     */
886    private void makeAccountsVisibleToAllUsers(PhoneAccountHandle... handles) {
887        for (PhoneAccountHandle ph : handles) {
888            when(mFakePhoneAccountRegistrar.getPhoneAccountUnchecked(eq(ph))).thenReturn(
889                    makeMultiUserPhoneAccount(ph).build());
890            when(mFakePhoneAccountRegistrar
891                    .getPhoneAccount(eq(ph), any(UserHandle.class), anyBoolean()))
892                    .thenReturn(makeMultiUserPhoneAccount(ph).build());
893            when(mFakePhoneAccountRegistrar
894                    .getPhoneAccount(eq(ph), any(UserHandle.class)))
895                    .thenReturn(makeMultiUserPhoneAccount(ph).build());
896        }
897    }
898
899    private PhoneAccount.Builder makeMultiUserPhoneAccount(PhoneAccountHandle paHandle) {
900        PhoneAccount.Builder paBuilder = makePhoneAccount(paHandle);
901        paBuilder.setCapabilities(PhoneAccount.CAPABILITY_MULTI_USER);
902        return paBuilder;
903    }
904
905    private PhoneAccount.Builder makePhoneAccount(PhoneAccountHandle paHandle) {
906        return new PhoneAccount.Builder(paHandle, "testLabel");
907    }
908
909    private Bundle createSampleExtras() {
910        Bundle extras = new Bundle();
911        extras.putString("test_key", "test_value");
912        return extras;
913    }
914
915    private static boolean areBundlesEqual(Bundle b1, Bundle b2) {
916        for (String key1 : b1.keySet()) {
917            if (!b1.get(key1).equals(b2.get(key1))) {
918                return false;
919            }
920        }
921
922        for (String key2 : b2.keySet()) {
923            if (!b2.get(key2).equals(b1.get(key2))) {
924                return false;
925            }
926        }
927        return true;
928    }
929}
930