InCallControllerTests.java revision 7c9283261ad4fdbc5ebbb74257671388f9c758c7
1/*
2 * Copyright (C) 2016 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 android.Manifest;
20import android.content.ComponentName;
21import android.content.ContentResolver;
22import android.content.Context;
23import android.content.Intent;
24import android.content.ServiceConnection;
25import android.content.pm.PackageManager;
26import android.content.pm.ResolveInfo;
27import android.content.pm.ServiceInfo;
28import android.content.res.Resources;
29import android.os.Bundle;
30import android.os.IBinder;
31import android.os.UserHandle;
32import android.telecom.InCallService;
33import android.telecom.ParcelableCall;
34import android.telecom.PhoneAccountHandle;
35import android.telecom.TelecomManager;
36import android.test.mock.MockContext;
37import android.test.suitebuilder.annotation.MediumTest;
38import android.text.TextUtils;
39
40import com.android.internal.telecom.IInCallAdapter;
41import com.android.internal.telecom.IInCallService;
42import com.android.server.telecom.Analytics;
43import com.android.server.telecom.BluetoothHeadsetProxy;
44import com.android.server.telecom.Call;
45import com.android.server.telecom.CallsManager;
46import com.android.server.telecom.DefaultDialerCache;
47import com.android.server.telecom.InCallController;
48import com.android.server.telecom.PhoneAccountRegistrar;
49import com.android.server.telecom.R;
50import com.android.server.telecom.SystemStateProvider;
51import com.android.server.telecom.TelecomSystem;
52import com.android.server.telecom.Timeouts;
53
54import org.mockito.ArgumentCaptor;
55import org.mockito.Mock;
56import org.mockito.MockitoAnnotations;
57import org.mockito.invocation.InvocationOnMock;
58import org.mockito.stubbing.Answer;
59
60import java.util.Collections;
61import java.util.LinkedList;
62
63import static org.mockito.Matchers.any;
64import static org.mockito.Matchers.anyInt;
65import static org.mockito.Matchers.anyString;
66import static org.mockito.Matchers.eq;
67import static org.mockito.Mockito.doAnswer;
68import static org.mockito.Mockito.doReturn;
69import static org.mockito.Mockito.mock;
70import static org.mockito.Mockito.never;
71import static org.mockito.Mockito.times;
72import static org.mockito.Mockito.when;
73import static org.mockito.Mockito.verify;
74
75public class InCallControllerTests extends TelecomTestCase {
76    @Mock CallsManager mMockCallsManager;
77    @Mock PhoneAccountRegistrar mMockPhoneAccountRegistrar;
78    @Mock BluetoothHeadsetProxy mMockBluetoothHeadset;
79    @Mock SystemStateProvider mMockSystemStateProvider;
80    @Mock PackageManager mMockPackageManager;
81    @Mock Call mMockCall;
82    @Mock Resources mMockResources;
83    @Mock MockContext mMockContext;
84    @Mock Timeouts.Adapter mTimeoutsAdapter;
85    @Mock DefaultDialerCache mDefaultDialerCache;
86
87    private static final int CURRENT_USER_ID = 900973;
88    private static final String DEF_PKG = "defpkg";
89    private static final String DEF_CLASS = "defcls";
90    private static final String SYS_PKG = "syspkg";
91    private static final String SYS_CLASS = "syscls";
92    private static final PhoneAccountHandle PA_HANDLE =
93            new PhoneAccountHandle(new ComponentName("pa_pkg", "pa_cls"), "pa_id");
94
95    private UserHandle mUserHandle = UserHandle.of(CURRENT_USER_ID);
96    private InCallController mInCallController;
97    private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {};
98
99    @Override
100    public void setUp() throws Exception {
101        super.setUp();
102        MockitoAnnotations.initMocks(this);
103        when(mMockCall.getAnalytics()).thenReturn(new Analytics.CallInfo());
104        doReturn(mMockResources).when(mMockContext).getResources();
105        doReturn(SYS_PKG).when(mMockResources).getString(R.string.ui_default_package);
106        doReturn(SYS_CLASS).when(mMockResources).getString(R.string.incall_default_class);
107        mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
108                mMockSystemStateProvider, mDefaultDialerCache, mTimeoutsAdapter);
109    }
110
111    @Override
112    public void tearDown() throws Exception {
113        super.tearDown();
114    }
115
116    @MediumTest
117    public void testBindToService_NoServicesFound_IncomingCall() throws Exception {
118        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
119        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
120        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
121        when(mMockCall.isIncoming()).thenReturn(true);
122        when(mMockCall.isExternalCall()).thenReturn(false);
123
124        setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
125        mInCallController.bindToServices(mMockCall);
126
127        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
128        verify(mMockContext).bindServiceAsUser(
129                bindIntentCaptor.capture(),
130                any(ServiceConnection.class),
131                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
132                eq(UserHandle.CURRENT));
133
134        Intent bindIntent = bindIntentCaptor.getValue();
135        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
136        assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
137        assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
138        assertNull(bindIntent.getExtras());
139    }
140
141    @MediumTest
142    public void testBindToService_NoServicesFound_OutgoingCall() throws Exception {
143        Bundle callExtras = new Bundle();
144        callExtras.putBoolean("whatever", true);
145
146        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
147        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
148        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
149        when(mMockCall.isIncoming()).thenReturn(false);
150        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
151        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
152        when(mMockCall.isExternalCall()).thenReturn(false);
153
154        Intent queryIntent = new Intent(InCallService.SERVICE_INTERFACE);
155        setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
156        mInCallController.bindToServices(mMockCall);
157
158        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
159        verify(mMockContext).bindServiceAsUser(
160                bindIntentCaptor.capture(),
161                any(ServiceConnection.class),
162                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
163                eq(UserHandle.CURRENT));
164
165        Intent bindIntent = bindIntentCaptor.getValue();
166        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
167        assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
168        assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
169        assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
170                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
171        assertEquals(callExtras, bindIntent.getExtras().getParcelable(
172                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
173    }
174
175    @MediumTest
176    public void testBindToService_DefaultDialer_NoEmergency() throws Exception {
177        Bundle callExtras = new Bundle();
178        callExtras.putBoolean("whatever", true);
179
180        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
181        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
182        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
183        when(mMockCall.isIncoming()).thenReturn(false);
184        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
185        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
186        when(mMockCall.isExternalCall()).thenReturn(false);
187        when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
188                .thenReturn(DEF_PKG);
189        when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
190                anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
191
192        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
193        mInCallController.bindToServices(mMockCall);
194
195        // Query for the different InCallServices
196        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
197        verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
198                queryIntentCaptor.capture(),
199                eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
200
201        // Verify call for default dialer InCallService
202        assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
203        // Verify call for car-mode InCallService
204        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
205        // Verify call for non-UI InCallServices
206        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
207
208        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
209        verify(mMockContext, times(1)).bindServiceAsUser(
210                bindIntentCaptor.capture(),
211                any(ServiceConnection.class),
212                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
213                eq(UserHandle.CURRENT));
214
215        Intent bindIntent = bindIntentCaptor.getValue();
216        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
217        assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
218        assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
219        assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
220                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
221        assertEquals(callExtras, bindIntent.getExtras().getParcelable(
222                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
223    }
224
225    @MediumTest
226    public void testBindToService_SystemDialer_Emergency() throws Exception {
227        Bundle callExtras = new Bundle();
228        callExtras.putBoolean("whatever", true);
229
230        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
231        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
232        when(mMockCallsManager.hasEmergencyCall()).thenReturn(true);
233        when(mMockCall.isIncoming()).thenReturn(false);
234        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
235        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
236        when(mMockCall.isExternalCall()).thenReturn(false);
237        when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
238                .thenReturn(DEF_PKG);
239        when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
240                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
241                eq(UserHandle.CURRENT))).thenReturn(true);
242
243        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
244
245        mInCallController.bindToServices(mMockCall);
246
247        // Query for the different InCallServices
248        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
249        verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
250                queryIntentCaptor.capture(),
251                eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
252
253        // Verify call for default dialer InCallService
254        assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
255        // Verify call for car-mode InCallService
256        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
257        // Verify call for non-UI InCallServices
258        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
259
260        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
261        verify(mMockContext, times(1)).bindServiceAsUser(
262                bindIntentCaptor.capture(),
263                any(ServiceConnection.class),
264                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
265                eq(UserHandle.CURRENT));
266
267        Intent bindIntent = bindIntentCaptor.getValue();
268        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
269        assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
270        assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
271        assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
272                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
273        assertEquals(callExtras, bindIntent.getExtras().getParcelable(
274                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
275    }
276
277    @MediumTest
278    public void testBindToService_DefaultDialer_FallBackToSystem() throws Exception {
279        Bundle callExtras = new Bundle();
280        callExtras.putBoolean("whatever", true);
281
282        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
283        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
284        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
285        when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
286        when(mMockCallsManager.getAudioState()).thenReturn(null);
287        when(mMockCallsManager.canAddCall()).thenReturn(false);
288        when(mMockCall.isIncoming()).thenReturn(false);
289        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
290        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
291        when(mMockCall.isExternalCall()).thenReturn(false);
292        when(mMockCall.getConferenceableCalls()).thenReturn(Collections.emptyList());
293        when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
294                .thenReturn(DEF_PKG);
295        when(mMockContext.bindServiceAsUser(
296                any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
297                .thenReturn(true);
298
299        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
300        mInCallController.bindToServices(mMockCall);
301
302        // Query for the different InCallServices
303        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
304        verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
305                queryIntentCaptor.capture(),
306                eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
307
308        // Verify call for default dialer InCallService
309        assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
310        // Verify call for car-mode InCallService
311        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
312        // Verify call for non-UI InCallServices
313        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
314
315        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
316        ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
317                ArgumentCaptor.forClass(ServiceConnection.class);
318        verify(mMockContext, times(1)).bindServiceAsUser(
319                bindIntentCaptor.capture(),
320                serviceConnectionCaptor.capture(),
321                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
322                eq(UserHandle.CURRENT));
323
324        Intent bindIntent = bindIntentCaptor.getValue();
325        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
326        assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
327        assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
328        assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
329                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
330        assertEquals(callExtras, bindIntent.getExtras().getParcelable(
331                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
332
333        // We have a ServiceConnection for the default dialer, lets start the connection, and then
334        // simulate a crash so that we fallback to system.
335        ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
336        ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
337        IBinder mockBinder = mock(IBinder.class);
338        IInCallService mockInCallService = mock(IInCallService.class);
339        when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
340
341
342        // Start the connection with IInCallService
343        serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
344        verify(mockInCallService).setInCallAdapter(any(IInCallAdapter.class));
345
346        // Now crash the damn thing!
347        serviceConnection.onServiceDisconnected(defDialerComponentName);
348
349        ArgumentCaptor<Intent> bindIntentCaptor2 = ArgumentCaptor.forClass(Intent.class);
350        verify(mMockContext, times(2)).bindServiceAsUser(
351                bindIntentCaptor2.capture(),
352                any(ServiceConnection.class),
353                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
354                eq(UserHandle.CURRENT));
355
356        bindIntent = bindIntentCaptor2.getValue();
357        assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
358        assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
359    }
360
361    /**
362     * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
363     * supports external calls.
364     */
365    @MediumTest
366    public void testBindToService_IncludeExternal() throws Exception {
367        setupMocks(true /* isExternalCall */);
368        setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
369        mInCallController.bindToServices(mMockCall);
370
371        // Query for the different InCallServices
372        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
373        verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
374                queryIntentCaptor.capture(),
375                eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
376
377        // Verify call for default dialer InCallService
378        assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
379        // Verify call for car-mode InCallService
380        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
381        // Verify call for non-UI InCallServices
382        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
383
384        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
385        verify(mMockContext, times(1)).bindServiceAsUser(
386                bindIntentCaptor.capture(),
387                any(ServiceConnection.class),
388                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
389                eq(UserHandle.CURRENT));
390
391        Intent bindIntent = bindIntentCaptor.getValue();
392        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
393        assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
394        assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
395    }
396
397    /**
398     * Make sure that if a call goes away before the in-call service finishes binding and another
399     * call gets connected soon after, the new call will still be sent to the in-call service.
400     */
401    @MediumTest
402    public void testUnbindDueToCallDisconnect() throws Exception {
403        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
404        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
405        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
406        when(mMockCall.isIncoming()).thenReturn(true);
407        when(mMockCall.isExternalCall()).thenReturn(false);
408        when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
409        when(mMockContext.bindServiceAsUser(
410                any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
411                .thenReturn(true);
412        when(mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(any(ContentResolver.class)))
413                .thenReturn(500L);
414
415        when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
416        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
417        mInCallController.bindToServices(mMockCall);
418
419        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
420        ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
421                ArgumentCaptor.forClass(ServiceConnection.class);
422        verify(mMockContext, times(1)).bindServiceAsUser(
423                bindIntentCaptor.capture(),
424                serviceConnectionCaptor.capture(),
425                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
426                eq(UserHandle.CURRENT));
427
428        // Pretend that the call has gone away.
429        when(mMockCallsManager.getCalls()).thenReturn(Collections.emptyList());
430        mInCallController.onCallRemoved(mMockCall);
431
432        // Start the connection, make sure we don't unbind, and make sure that we don't send
433        // anything to the in-call service yet.
434        ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
435        ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
436        IBinder mockBinder = mock(IBinder.class);
437        IInCallService mockInCallService = mock(IInCallService.class);
438        when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
439
440        serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
441        verify(mockInCallService).setInCallAdapter(any(IInCallAdapter.class));
442        verify(mMockContext, never()).unbindService(serviceConnection);
443        verify(mockInCallService, never()).addCall(any(ParcelableCall.class));
444
445        // Now, we add in the call again and make sure that it's sent to the InCallService.
446        when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
447        mInCallController.onCallAdded(mMockCall);
448        verify(mockInCallService).addCall(any(ParcelableCall.class));
449    }
450
451    private void setupMocks(boolean isExternalCall) {
452        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
453        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
454        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
455        when(mMockCall.isIncoming()).thenReturn(false);
456        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
457        when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
458        when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
459                anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
460        when(mMockCall.isExternalCall()).thenReturn(isExternalCall);
461    }
462
463    private ResolveInfo getDefResolveInfo(final boolean includeExternalCalls) {
464        return new ResolveInfo() {{
465            serviceInfo = new ServiceInfo();
466            serviceInfo.packageName = DEF_PKG;
467            serviceInfo.name = DEF_CLASS;
468            serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
469            serviceInfo.metaData = new Bundle();
470            serviceInfo.metaData.putBoolean(
471                    TelecomManager.METADATA_IN_CALL_SERVICE_UI, true);
472            if (includeExternalCalls) {
473                serviceInfo.metaData.putBoolean(
474                        TelecomManager.METADATA_INCLUDE_EXTERNAL_CALLS, true);
475            }
476        }};
477    }
478
479    private ResolveInfo getSysResolveinfo() {
480        return new ResolveInfo() {{
481            serviceInfo = new ServiceInfo();
482            serviceInfo.packageName = SYS_PKG;
483            serviceInfo.name = SYS_CLASS;
484            serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
485        }};
486    }
487
488    private void setupMockPackageManager(final boolean useDefaultDialer,
489            final boolean useSystemDialer, final boolean includeExternalCalls) {
490
491        doAnswer(new Answer() {
492            @Override
493            public Object answer(InvocationOnMock invocation) throws Throwable {
494                Object[] args = invocation.getArguments();
495                Intent intent = (Intent) args[0];
496                String packageName = intent.getPackage();
497                ComponentName componentName = intent.getComponent();
498                if (componentName != null) {
499                    packageName = componentName.getPackageName();
500                }
501                LinkedList<ResolveInfo> resolveInfo = new LinkedList<ResolveInfo>();
502                if (!TextUtils.isEmpty(packageName)) {
503                    if ((TextUtils.isEmpty(packageName) || packageName.equals(DEF_PKG)) &&
504                            useDefaultDialer) {
505                        resolveInfo.add(getDefResolveInfo(includeExternalCalls));
506                    }
507
508                    if ((TextUtils.isEmpty(packageName) || packageName.equals(SYS_PKG)) &&
509                           useSystemDialer) {
510                        resolveInfo.add(getSysResolveinfo());
511                    }
512                }
513                return resolveInfo;
514            }
515        }).when(mMockPackageManager).queryIntentServicesAsUser(
516                any(Intent.class), eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
517    }
518}
519