TelecomServiceImplTest.java revision 4a05d5cc0acedb616ff6d22151f4ccf0043f0810
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            verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
470                    anyString());
471
472            Intent capturedIntent = intentCaptor.getValue();
473            assertEquals(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED,
474                    capturedIntent.getAction());
475            Bundle intentExtras = capturedIntent.getExtras();
476            assertEquals(1, intentExtras.size());
477            assertEquals(testPhoneAccount.getAccountHandle(),
478                    intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
479        } else {
480            assertTrue(didExceptionOccur);
481            verify(mFakePhoneAccountRegistrar, never())
482                    .registerPhoneAccount(any(PhoneAccount.class));
483            verify(mContext, never())
484                    .sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), anyString());
485        }
486    }
487
488    @SmallTest
489    public void testUnregisterPhoneAccount() throws RemoteException {
490        String packageNameToUse = "com.android.officialpackage";
491        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
492                packageNameToUse, "cs"), "test", Binder.getCallingUserHandle());
493
494        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
495        doReturn(PackageManager.PERMISSION_GRANTED)
496                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
497
498        mTSIBinder.unregisterPhoneAccount(phHandle);
499        verify(mFakePhoneAccountRegistrar).unregisterPhoneAccount(phHandle);
500        verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
501                anyString());
502        Intent capturedIntent = intentCaptor.getValue();
503        assertEquals(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED,
504                capturedIntent.getAction());
505        Bundle intentExtras = capturedIntent.getExtras();
506        assertEquals(1, intentExtras.size());
507        assertEquals(phHandle, intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
508    }
509
510    @SmallTest
511    public void testUnregisterPhoneAccountFailure() throws RemoteException {
512        String packageNameToUse = "com.thirdparty.connectionservice";
513        PhoneAccountHandle phHandle = new PhoneAccountHandle(new ComponentName(
514                packageNameToUse, "cs"), "asdf", Binder.getCallingUserHandle());
515
516        doReturn(PackageManager.PERMISSION_DENIED)
517                .when(mContext).checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
518        PackageManager pm = mContext.getPackageManager();
519        when(pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE)).thenReturn(false);
520
521        try {
522            mTSIBinder.unregisterPhoneAccount(phHandle);
523        } catch (UnsupportedOperationException e) {
524            // expected behavior
525        }
526        verify(mFakePhoneAccountRegistrar, never())
527                .unregisterPhoneAccount(any(PhoneAccountHandle.class));
528        verify(mContext, never())
529                .sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), anyString());
530    }
531
532    @SmallTest
533    public void testAddNewIncomingCall() throws Exception {
534        PhoneAccount phoneAccount = makePhoneAccount(TEL_PA_HANDLE_CURRENT).build();
535        phoneAccount.setIsEnabled(true);
536        doReturn(phoneAccount).when(mFakePhoneAccountRegistrar).getPhoneAccount(
537                eq(TEL_PA_HANDLE_CURRENT), any(UserHandle.class));
538        doNothing().when(mAppOpsManager).checkPackage(anyInt(), anyString());
539        Bundle extras = createSampleExtras();
540
541        mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_CURRENT, extras);
542
543        addCallTestHelper(TelecomManager.ACTION_INCOMING_CALL,
544                CallIntentProcessor.KEY_IS_INCOMING_CALL, extras, false);
545    }
546
547    @SmallTest
548    public void testAddNewIncomingCallFailure() throws Exception {
549        try {
550            mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_16, null);
551        } catch (SecurityException e) {
552            // expected
553        }
554
555        doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
556
557        try {
558            mTSIBinder.addNewIncomingCall(TEL_PA_HANDLE_CURRENT, null);
559        } catch (SecurityException e) {
560            // expected
561        }
562
563        // Verify that neither of these attempts got through
564        verify(mCallIntentProcessorAdapter, never())
565                .processIncomingCallIntent(any(CallsManager.class), any(Intent.class));
566    }
567
568    @SmallTest
569    public void testAddNewUnknownCall() throws Exception {
570        PhoneAccount phoneAccount = makePhoneAccount(TEL_PA_HANDLE_CURRENT).build();
571        phoneAccount.setIsEnabled(true);
572        doReturn(phoneAccount).when(mFakePhoneAccountRegistrar).getPhoneAccount(
573                eq(TEL_PA_HANDLE_CURRENT), any(UserHandle.class));
574        doNothing().when(mAppOpsManager).checkPackage(anyInt(), anyString());
575        Bundle extras = createSampleExtras();
576
577        mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_CURRENT, extras);
578
579        addCallTestHelper(TelecomManager.ACTION_NEW_UNKNOWN_CALL,
580                CallIntentProcessor.KEY_IS_UNKNOWN_CALL, extras, true);
581    }
582
583    @SmallTest
584    public void testAddNewUnknownCallFailure() throws Exception {
585        try {
586            mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_16, null);
587        } catch (SecurityException e) {
588            // expected
589        }
590
591        doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString());
592
593        try {
594            mTSIBinder.addNewUnknownCall(TEL_PA_HANDLE_CURRENT, null);
595        } catch (SecurityException e) {
596            // expected
597        }
598
599        // Verify that neither of these attempts got through
600        verify(mCallIntentProcessorAdapter, never())
601                .processIncomingCallIntent(any(CallsManager.class), any(Intent.class));
602    }
603
604    private void addCallTestHelper(String expectedAction, String extraCallKey,
605            Bundle expectedExtras, boolean isUnknown) {
606        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
607        if (isUnknown) {
608            verify(mCallIntentProcessorAdapter).processUnknownCallIntent(any(CallsManager.class),
609                    intentCaptor.capture());
610        } else {
611            verify(mCallIntentProcessorAdapter).processIncomingCallIntent(any(CallsManager.class),
612                    intentCaptor.capture());
613        }
614        Intent capturedIntent = intentCaptor.getValue();
615        assertEquals(expectedAction, capturedIntent.getAction());
616        Bundle intentExtras = capturedIntent.getExtras();
617        assertEquals(TEL_PA_HANDLE_CURRENT,
618                intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
619        assertTrue(intentExtras.getBoolean(extraCallKey));
620
621        if (isUnknown) {
622            for (String expectedKey : expectedExtras.keySet()) {
623                assertTrue(intentExtras.containsKey(expectedKey));
624                assertEquals(expectedExtras.get(expectedKey), intentExtras.get(expectedKey));
625            }
626        }
627        else {
628            assertTrue(areBundlesEqual(expectedExtras,
629                    (Bundle) intentExtras.get(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS)));
630        }
631    }
632
633    @SmallTest
634    public void testPlaceCallWithNonEmergencyPermission() throws Exception {
635        Uri handle = Uri.parse("tel:6505551234");
636        Bundle extras = createSampleExtras();
637
638        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
639                .thenReturn(AppOpsManager.MODE_ALLOWED);
640        doReturn(PackageManager.PERMISSION_GRANTED)
641                .when(mContext).checkCallingPermission(CALL_PHONE);
642
643        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
644        placeCallTestHelper(handle, extras, true);
645    }
646
647    @SmallTest
648    public void testPlaceCallWithAppOpsOff() throws Exception {
649        Uri handle = Uri.parse("tel:6505551234");
650        Bundle extras = createSampleExtras();
651
652        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
653                .thenReturn(AppOpsManager.MODE_IGNORED);
654        doReturn(PackageManager.PERMISSION_GRANTED)
655                .when(mContext).checkCallingPermission(CALL_PHONE);
656
657        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
658        placeCallTestHelper(handle, extras, false);
659    }
660
661    @SmallTest
662    public void testPlaceCallWithNoCallingPermission() throws Exception {
663        Uri handle = Uri.parse("tel:6505551234");
664        Bundle extras = createSampleExtras();
665
666        when(mAppOpsManager.noteOp(eq(AppOpsManager.OP_CALL_PHONE), anyInt(), anyString()))
667                .thenReturn(AppOpsManager.MODE_ALLOWED);
668        doReturn(PackageManager.PERMISSION_DENIED)
669                .when(mContext).checkCallingPermission(CALL_PHONE);
670
671        mTSIBinder.placeCall(handle, extras, DEFAULT_DIALER_PACKAGE);
672        placeCallTestHelper(handle, extras, false);
673    }
674
675    private void placeCallTestHelper(Uri expectedHandle, Bundle expectedExtras,
676            boolean shouldNonEmergencyBeAllowed) {
677        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
678        verify(mUserCallIntentProcessor).processIntent(intentCaptor.capture(), anyString(),
679                eq(shouldNonEmergencyBeAllowed));
680        Intent capturedIntent = intentCaptor.getValue();
681        assertEquals(Intent.ACTION_CALL, capturedIntent.getAction());
682        assertEquals(expectedHandle, capturedIntent.getData());
683        assertTrue(areBundlesEqual(expectedExtras, capturedIntent.getExtras()));
684    }
685
686    @SmallTest
687    public void testPlaceCallFailure() throws Exception {
688        Uri handle = Uri.parse("tel:6505551234");
689        Bundle extras = createSampleExtras();
690
691        doThrow(new SecurityException())
692                .when(mContext).enforceCallingOrSelfPermission(eq(CALL_PHONE), anyString());
693
694        try {
695            mTSIBinder.placeCall(handle, extras, "arbitrary_package_name");
696        } catch (SecurityException e) {
697            // expected
698        }
699
700        verify(mUserCallIntentProcessor, never())
701                .processIntent(any(Intent.class), anyString(), anyBoolean());
702    }
703
704    @SmallTest
705    public void testSetDefaultDialer() throws Exception {
706        String packageName = "sample.package";
707        int currentUser = ActivityManager.getCurrentUser();
708
709        when(mDefaultDialerCache.setDefaultDialer(eq(packageName), eq(currentUser)))
710                .thenReturn(true);
711
712        mTSIBinder.setDefaultDialer(packageName);
713
714        verify(mDefaultDialerCache).setDefaultDialer(eq(packageName), eq(currentUser));
715        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
716        verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), any(UserHandle.class));
717        Intent capturedIntent = intentCaptor.getValue();
718        assertEquals(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED, capturedIntent.getAction());
719        String packageNameExtra = capturedIntent.getStringExtra(
720                TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME);
721        assertEquals(packageName, packageNameExtra);
722    }
723
724    @SmallTest
725    public void testSetDefaultDialerNoModifyPhoneStatePermission() throws Exception {
726        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
727                eq(MODIFY_PHONE_STATE), nullable(String.class));
728        setDefaultDialerFailureTestHelper();
729    }
730
731    @SmallTest
732    public void testSetDefaultDialerNoWriteSecureSettingsPermission() throws Exception {
733        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
734                eq(WRITE_SECURE_SETTINGS), nullable(String.class));
735        setDefaultDialerFailureTestHelper();
736    }
737
738    private void setDefaultDialerFailureTestHelper() throws Exception {
739        boolean exceptionThrown = false;
740        try {
741            mTSIBinder.setDefaultDialer(DEFAULT_DIALER_PACKAGE);
742        } catch (SecurityException e) {
743            exceptionThrown = true;
744        }
745        assertTrue(exceptionThrown);
746        verify(mDefaultDialerCache, never()).setDefaultDialer(anyString(), anyInt());
747        verify(mContext, never()).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class));
748    }
749
750    @SmallTest
751    public void testIsVoicemailNumber() throws Exception {
752        String vmNumber = "010";
753        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_CURRENT);
754
755        doReturn(true).when(mFakePhoneAccountRegistrar).isVoiceMailNumber(TEL_PA_HANDLE_CURRENT,
756                vmNumber);
757        assertTrue(mTSIBinder.isVoiceMailNumber(TEL_PA_HANDLE_CURRENT,
758                vmNumber, DEFAULT_DIALER_PACKAGE));
759    }
760
761    @SmallTest
762    public void testIsVoicemailNumberAccountNotVisibleFailure() throws Exception {
763        String vmNumber = "010";
764
765        doReturn(true).when(mFakePhoneAccountRegistrar).isVoiceMailNumber(TEL_PA_HANDLE_CURRENT,
766                vmNumber);
767
768        when(mFakePhoneAccountRegistrar.getPhoneAccount(TEL_PA_HANDLE_CURRENT,
769                Binder.getCallingUserHandle())).thenReturn(null);
770        assertFalse(mTSIBinder
771                .isVoiceMailNumber(TEL_PA_HANDLE_CURRENT, vmNumber, DEFAULT_DIALER_PACKAGE));
772    }
773
774    @SmallTest
775    public void testGetVoicemailNumberWithNullAccountHandle() throws Exception {
776        when(mFakePhoneAccountRegistrar.getPhoneAccount(isNull(PhoneAccountHandle.class),
777                eq(Binder.getCallingUserHandle())))
778                .thenReturn(makePhoneAccount(TEL_PA_HANDLE_CURRENT).build());
779        int subId = 58374;
780        String vmNumber = "543";
781        doReturn(subId).when(mSubscriptionManagerAdapter).getDefaultVoiceSubId();
782
783        TelephonyManager mockTelephonyManager =
784                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
785        when(mockTelephonyManager.getVoiceMailNumber(subId)).thenReturn(vmNumber);
786
787        assertEquals(vmNumber, mTSIBinder.getVoiceMailNumber(null, DEFAULT_DIALER_PACKAGE));
788    }
789
790    @SmallTest
791    public void testGetVoicemailNumberWithNonNullAccountHandle() throws Exception {
792        when(mFakePhoneAccountRegistrar.getPhoneAccount(eq(TEL_PA_HANDLE_CURRENT),
793                eq(Binder.getCallingUserHandle())))
794                .thenReturn(makePhoneAccount(TEL_PA_HANDLE_CURRENT).build());
795        int subId = 58374;
796        String vmNumber = "543";
797
798        TelephonyManager mockTelephonyManager =
799                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
800        when(mockTelephonyManager.getVoiceMailNumber(subId)).thenReturn(vmNumber);
801        when(mFakePhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(TEL_PA_HANDLE_CURRENT))
802                .thenReturn(subId);
803
804        assertEquals(vmNumber,
805                mTSIBinder.getVoiceMailNumber(TEL_PA_HANDLE_CURRENT, DEFAULT_DIALER_PACKAGE));
806    }
807
808    @SmallTest
809    public void testGetLine1Number() throws Exception {
810        int subId = 58374;
811        String line1Number = "9482752023479";
812        makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_CURRENT);
813        when(mFakePhoneAccountRegistrar.getSubscriptionIdForPhoneAccount(TEL_PA_HANDLE_CURRENT))
814                .thenReturn(subId);
815        TelephonyManager mockTelephonyManager =
816                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
817        when(mockTelephonyManager.getLine1Number(subId)).thenReturn(line1Number);
818
819        assertEquals(line1Number,
820                mTSIBinder.getLine1Number(TEL_PA_HANDLE_CURRENT, DEFAULT_DIALER_PACKAGE));
821    }
822
823    @SmallTest
824    public void testEndCallWithRingingForegroundCall() throws Exception {
825        Call call = mock(Call.class);
826        when(call.getState()).thenReturn(CallState.RINGING);
827        when(mFakeCallsManager.getForegroundCall()).thenReturn(call);
828        assertTrue(mTSIBinder.endCall());
829        verify(call).reject(false, null);
830    }
831
832    @SmallTest
833    public void testEndCallWithNonRingingForegroundCall() throws Exception {
834        Call call = mock(Call.class);
835        when(call.getState()).thenReturn(CallState.ACTIVE);
836        when(mFakeCallsManager.getForegroundCall()).thenReturn(call);
837        assertTrue(mTSIBinder.endCall());
838        verify(call).disconnect();
839    }
840
841    @SmallTest
842    public void testEndCallWithNoForegroundCall() throws Exception {
843        Call call = mock(Call.class);
844        when(call.getState()).thenReturn(CallState.ACTIVE);
845        when(mFakeCallsManager.getFirstCallWithState(argThat(new IntVarArgMatcher())))
846                .thenReturn(call);
847        assertTrue(mTSIBinder.endCall());
848        verify(call).disconnect();
849    }
850
851    @SmallTest
852    public void testEndCallWithNoCalls() throws Exception {
853        assertFalse(mTSIBinder.endCall());
854    }
855
856    @SmallTest
857    public void testAcceptRingingCall() throws Exception {
858        Call call = mock(Call.class);
859        when(mFakeCallsManager.getFirstCallWithState(anyInt())).thenReturn(call);
860        // Not intended to be a real video state. Here to ensure that the call will be answered
861        // with whatever video state it's currently in.
862        int fakeVideoState = 29578215;
863        when(call.getVideoState()).thenReturn(fakeVideoState);
864        mTSIBinder.acceptRingingCall("");
865        verify(call).answer(eq(fakeVideoState));
866    }
867
868    @SmallTest
869    public void testAcceptRingingCallWithValidVideoState() throws Exception {
870        Call call = mock(Call.class);
871        when(mFakeCallsManager.getFirstCallWithState(anyInt())).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    @SmallTest
882    public void testIsInCall() throws Exception {
883        when(mFakeCallsManager.hasOngoingCalls()).thenReturn(true);
884        assertTrue(mTSIBinder.isInCall(DEFAULT_DIALER_PACKAGE));
885    }
886
887    @SmallTest
888    public void testNotIsInCall() throws Exception {
889        when(mFakeCallsManager.hasOngoingCalls()).thenReturn(false);
890        assertFalse(mTSIBinder.isInCall(DEFAULT_DIALER_PACKAGE));
891    }
892
893    @SmallTest
894    public void testIsInCallFail() throws Exception {
895        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
896                anyString(), any());
897        try {
898            mTSIBinder.isInCall("blah");
899            fail();
900        } catch (SecurityException e) {
901            // desired result
902        }
903        verify(mFakeCallsManager, never()).hasOngoingCalls();
904    }
905
906    @SmallTest
907    public void testIsInManagedCall() throws Exception {
908        when(mFakeCallsManager.hasOngoingManagedCalls()).thenReturn(true);
909        assertTrue(mTSIBinder.isInManagedCall(DEFAULT_DIALER_PACKAGE));
910    }
911
912    @SmallTest
913    public void testNotIsInManagedCall() throws Exception {
914        when(mFakeCallsManager.hasOngoingManagedCalls()).thenReturn(false);
915        assertFalse(mTSIBinder.isInManagedCall(DEFAULT_DIALER_PACKAGE));
916    }
917
918    @SmallTest
919    public void testIsInManagedCallFail() throws Exception {
920        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
921                anyString(), any());
922        try {
923            mTSIBinder.isInManagedCall("blah");
924            fail();
925        } catch (SecurityException e) {
926            // desired result
927        }
928        verify(mFakeCallsManager, never()).hasOngoingCalls();
929    }
930
931    /**
932     * Register phone accounts for the supplied PhoneAccountHandles to make them
933     * visible to all users (via the isVisibleToCaller method in TelecomServiceImpl.
934     * @param handles the handles for which phone accounts should be created for.
935     */
936    private void makeAccountsVisibleToAllUsers(PhoneAccountHandle... handles) {
937        for (PhoneAccountHandle ph : handles) {
938            when(mFakePhoneAccountRegistrar.getPhoneAccountUnchecked(eq(ph))).thenReturn(
939                    makeMultiUserPhoneAccount(ph).build());
940            when(mFakePhoneAccountRegistrar
941                    .getPhoneAccount(eq(ph), nullable(UserHandle.class), anyBoolean()))
942                    .thenReturn(makeMultiUserPhoneAccount(ph).build());
943            when(mFakePhoneAccountRegistrar
944                    .getPhoneAccount(eq(ph), nullable(UserHandle.class)))
945                    .thenReturn(makeMultiUserPhoneAccount(ph).build());
946        }
947    }
948
949    private PhoneAccount.Builder makeMultiUserPhoneAccount(PhoneAccountHandle paHandle) {
950        PhoneAccount.Builder paBuilder = makePhoneAccount(paHandle);
951        paBuilder.setCapabilities(PhoneAccount.CAPABILITY_MULTI_USER);
952        return paBuilder;
953    }
954
955    private PhoneAccount.Builder makePhoneAccount(PhoneAccountHandle paHandle) {
956        return new PhoneAccount.Builder(paHandle, "testLabel");
957    }
958
959    private Bundle createSampleExtras() {
960        Bundle extras = new Bundle();
961        extras.putString("test_key", "test_value");
962        return extras;
963    }
964
965    private static boolean areBundlesEqual(Bundle b1, Bundle b2) {
966        for (String key1 : b1.keySet()) {
967            if (!b1.get(key1).equals(b2.get(key1))) {
968                return false;
969            }
970        }
971
972        for (String key2 : b2.keySet()) {
973            if (!b2.get(key2).equals(b1.get(key2))) {
974                return false;
975            }
976        }
977        return true;
978    }
979}
980