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