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