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