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