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