blob: 0671a4ed5cbe8f04c71150469cb9d56a3c471b89 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.server.telecom.tests;
import android.Manifest;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.telecom.InCallService;
import android.telecom.ParcelableCall;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.MediumTest;
import android.text.TextUtils;
import com.android.internal.telecom.IInCallAdapter;
import com.android.internal.telecom.IInCallService;
import com.android.server.telecom.Analytics;
import com.android.server.telecom.BluetoothHeadsetProxy;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallsManager;
import com.android.server.telecom.DefaultDialerCache;
import com.android.server.telecom.EmergencyCallHelper;
import com.android.server.telecom.InCallController;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.R;
import com.android.server.telecom.SystemStateProvider;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.Timeouts;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.Collections;
import java.util.LinkedList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
@RunWith(JUnit4.class)
public class InCallControllerTests extends TelecomTestCase {
@Mock CallsManager mMockCallsManager;
@Mock PhoneAccountRegistrar mMockPhoneAccountRegistrar;
@Mock BluetoothHeadsetProxy mMockBluetoothHeadset;
@Mock SystemStateProvider mMockSystemStateProvider;
@Mock PackageManager mMockPackageManager;
@Mock Call mMockCall;
@Mock Resources mMockResources;
@Mock MockContext mMockContext;
@Mock Timeouts.Adapter mTimeoutsAdapter;
@Mock DefaultDialerCache mDefaultDialerCache;
private static final int CURRENT_USER_ID = 900973;
private static final String DEF_PKG = "defpkg";
private static final String DEF_CLASS = "defcls";
private static final String SYS_PKG = "syspkg";
private static final String SYS_CLASS = "syscls";
private static final PhoneAccountHandle PA_HANDLE =
new PhoneAccountHandle(new ComponentName("pa_pkg", "pa_cls"), "pa_id");
private UserHandle mUserHandle = UserHandle.of(CURRENT_USER_ID);
private InCallController mInCallController;
private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {};
private EmergencyCallHelper mEmergencyCallHelper;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
when(mMockCall.getAnalytics()).thenReturn(new Analytics.CallInfo());
doReturn(mMockResources).when(mMockContext).getResources();
doReturn(SYS_PKG).when(mMockResources).getString(R.string.ui_default_package);
doReturn(SYS_CLASS).when(mMockResources).getString(R.string.incall_default_class);
doReturn(true).when(mMockResources).getBoolean(R.bool.grant_location_permission_enabled);
mEmergencyCallHelper = new EmergencyCallHelper(mMockContext, SYS_PKG,
mTimeoutsAdapter);
mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
mMockSystemStateProvider, mDefaultDialerCache, mTimeoutsAdapter,
mEmergencyCallHelper);
}
@Override
@After
public void tearDown() throws Exception {
super.tearDown();
}
@MediumTest
@Test
public void testBindToService_NoServicesFound_IncomingCall() throws Exception {
when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
when(mMockCall.isIncoming()).thenReturn(true);
when(mMockCall.isExternalCall()).thenReturn(false);
when(mTimeoutsAdapter.getEmergencyCallbackWindowMillis(any(ContentResolver.class)))
.thenReturn(300_000L);
setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
mInCallController.bindToServices(mMockCall);
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockContext).bindServiceAsUser(
bindIntentCaptor.capture(),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
Intent bindIntent = bindIntentCaptor.getValue();
assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
assertNull(bindIntent.getExtras());
}
@MediumTest
@Test
public void testBindToService_NoServicesFound_OutgoingCall() throws Exception {
Bundle callExtras = new Bundle();
callExtras.putBoolean("whatever", true);
when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
when(mMockCall.isIncoming()).thenReturn(false);
when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
when(mMockCall.getIntentExtras()).thenReturn(callExtras);
when(mMockCall.isExternalCall()).thenReturn(false);
when(mTimeoutsAdapter.getEmergencyCallbackWindowMillis(any(ContentResolver.class)))
.thenReturn(300_000L);
Intent queryIntent = new Intent(InCallService.SERVICE_INTERFACE);
setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
mInCallController.bindToServices(mMockCall);
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockContext).bindServiceAsUser(
bindIntentCaptor.capture(),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
Intent bindIntent = bindIntentCaptor.getValue();
assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
assertEquals(callExtras, bindIntent.getExtras().getParcelable(
TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
}
@MediumTest
@Test
public void testBindToService_DefaultDialer_NoEmergency() throws Exception {
Bundle callExtras = new Bundle();
callExtras.putBoolean("whatever", true);
when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
when(mMockCall.isIncoming()).thenReturn(false);
when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
when(mMockCall.getIntentExtras()).thenReturn(callExtras);
when(mMockCall.isExternalCall()).thenReturn(false);
when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
.thenReturn(DEF_PKG);
when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
mInCallController.bindToServices(mMockCall);
// Query for the different InCallServices
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
// Verify call for car-mode InCallService
assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
// Verify call for non-UI InCallServices
assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockContext, times(1)).bindServiceAsUser(
bindIntentCaptor.capture(),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
Intent bindIntent = bindIntentCaptor.getValue();
assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
assertEquals(callExtras, bindIntent.getExtras().getParcelable(
TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
}
@MediumTest
@Test
public void testBindToService_SystemDialer_Emergency() throws Exception {
Bundle callExtras = new Bundle();
callExtras.putBoolean("whatever", true);
when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockCallsManager.hasEmergencyCall()).thenReturn(true);
when(mMockCall.isEmergencyCall()).thenReturn(true);
when(mMockCall.isIncoming()).thenReturn(false);
when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
when(mMockCall.getIntentExtras()).thenReturn(callExtras);
when(mMockCall.isExternalCall()).thenReturn(false);
when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
.thenReturn(DEF_PKG);
when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT))).thenReturn(true);
when(mTimeoutsAdapter.getEmergencyCallbackWindowMillis(any(ContentResolver.class)))
.thenReturn(300_000L);
setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
setupMockPackageManagerLocationPermission(SYS_PKG, false /* granted */);
mInCallController.bindToServices(mMockCall);
// Query for the different InCallServices
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
// Verify call for car-mode InCallService
assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
// Verify call for non-UI InCallServices
assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockContext, times(1)).bindServiceAsUser(
bindIntentCaptor.capture(),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
Intent bindIntent = bindIntentCaptor.getValue();
assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
assertEquals(callExtras, bindIntent.getExtras().getParcelable(
TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
verify(mMockPackageManager).grantRuntimePermission(eq(SYS_PKG),
eq(Manifest.permission.ACCESS_FINE_LOCATION), eq(mUserHandle));
// Pretend that the call has gone away.
when(mMockCallsManager.getCalls()).thenReturn(Collections.emptyList());
mInCallController.onCallRemoved(mMockCall);
waitForHandlerAction(new Handler(Looper.getMainLooper()), TelecomSystemTest.TEST_TIMEOUT);
verify(mMockPackageManager).revokeRuntimePermission(eq(SYS_PKG),
eq(Manifest.permission.ACCESS_FINE_LOCATION), eq(mUserHandle));
}
@MediumTest
@Test
public void testBindToService_DefaultDialer_FallBackToSystem() throws Exception {
Bundle callExtras = new Bundle();
callExtras.putBoolean("whatever", true);
when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
when(mMockCallsManager.getAudioState()).thenReturn(null);
when(mMockCallsManager.canAddCall()).thenReturn(false);
when(mMockCall.isIncoming()).thenReturn(false);
when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
when(mMockCall.getIntentExtras()).thenReturn(callExtras);
when(mMockCall.isExternalCall()).thenReturn(false);
when(mMockCall.getConferenceableCalls()).thenReturn(Collections.emptyList());
when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
.thenReturn(DEF_PKG);
when(mMockContext.bindServiceAsUser(
any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
.thenReturn(true);
setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
mInCallController.bindToServices(mMockCall);
// Query for the different InCallServices
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
// Verify call for car-mode InCallService
assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
// Verify call for non-UI InCallServices
assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
ArgumentCaptor.forClass(ServiceConnection.class);
verify(mMockContext, times(1)).bindServiceAsUser(
bindIntentCaptor.capture(),
serviceConnectionCaptor.capture(),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
Intent bindIntent = bindIntentCaptor.getValue();
assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
assertEquals(callExtras, bindIntent.getExtras().getParcelable(
TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
// We have a ServiceConnection for the default dialer, lets start the connection, and then
// simulate a crash so that we fallback to system.
ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
IBinder mockBinder = mock(IBinder.class);
IInCallService mockInCallService = mock(IInCallService.class);
when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
// Start the connection with IInCallService
serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
verify(mockInCallService).setInCallAdapter(any(IInCallAdapter.class));
// Now crash the damn thing!
serviceConnection.onServiceDisconnected(defDialerComponentName);
ArgumentCaptor<Intent> bindIntentCaptor2 = ArgumentCaptor.forClass(Intent.class);
verify(mMockContext, times(2)).bindServiceAsUser(
bindIntentCaptor2.capture(),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
bindIntent = bindIntentCaptor2.getValue();
assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
}
/**
* Ensures that the {@link InCallController} will bind to an {@link InCallService} which
* supports external calls.
*/
@MediumTest
@Test
public void testBindToService_IncludeExternal() throws Exception {
setupMocks(true /* isExternalCall */);
setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
mInCallController.bindToServices(mMockCall);
// Query for the different InCallServices
ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
queryIntentCaptor.capture(),
eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
// Verify call for default dialer InCallService
assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
// Verify call for car-mode InCallService
assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
// Verify call for non-UI InCallServices
assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mMockContext, times(1)).bindServiceAsUser(
bindIntentCaptor.capture(),
any(ServiceConnection.class),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
Intent bindIntent = bindIntentCaptor.getValue();
assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
}
/**
* Make sure that if a call goes away before the in-call service finishes binding and another
* call gets connected soon after, the new call will still be sent to the in-call service.
*/
@MediumTest
@Test
public void testUnbindDueToCallDisconnect() throws Exception {
when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
when(mMockCall.isIncoming()).thenReturn(true);
when(mMockCall.isExternalCall()).thenReturn(false);
when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
when(mMockContext.bindServiceAsUser(nullable(Intent.class),
nullable(ServiceConnection.class), anyInt(), nullable(UserHandle.class)))
.thenReturn(true);
when(mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(
nullable(ContentResolver.class))).thenReturn(500L);
when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
mInCallController.bindToServices(mMockCall);
ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
ArgumentCaptor.forClass(ServiceConnection.class);
verify(mMockContext, times(1)).bindServiceAsUser(
bindIntentCaptor.capture(),
serviceConnectionCaptor.capture(),
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
eq(UserHandle.CURRENT));
// Pretend that the call has gone away.
when(mMockCallsManager.getCalls()).thenReturn(Collections.emptyList());
mInCallController.onCallRemoved(mMockCall);
// Start the connection, make sure we don't unbind, and make sure that we don't send
// anything to the in-call service yet.
ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
IBinder mockBinder = mock(IBinder.class);
IInCallService mockInCallService = mock(IInCallService.class);
when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
verify(mockInCallService).setInCallAdapter(nullable(IInCallAdapter.class));
verify(mMockContext, never()).unbindService(serviceConnection);
verify(mockInCallService, never()).addCall(any(ParcelableCall.class));
// Now, we add in the call again and make sure that it's sent to the InCallService.
when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
mInCallController.onCallAdded(mMockCall);
verify(mockInCallService).addCall(any(ParcelableCall.class));
}
private void setupMocks(boolean isExternalCall) {
when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
when(mMockCall.isIncoming()).thenReturn(false);
when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
when(mMockCall.isExternalCall()).thenReturn(isExternalCall);
}
private ResolveInfo getDefResolveInfo(final boolean includeExternalCalls) {
return new ResolveInfo() {{
serviceInfo = new ServiceInfo();
serviceInfo.packageName = DEF_PKG;
serviceInfo.name = DEF_CLASS;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
serviceInfo.metaData = new Bundle();
serviceInfo.metaData.putBoolean(
TelecomManager.METADATA_IN_CALL_SERVICE_UI, true);
if (includeExternalCalls) {
serviceInfo.metaData.putBoolean(
TelecomManager.METADATA_INCLUDE_EXTERNAL_CALLS, true);
}
}};
}
private ResolveInfo getSysResolveinfo() {
return new ResolveInfo() {{
serviceInfo = new ServiceInfo();
serviceInfo.packageName = SYS_PKG;
serviceInfo.name = SYS_CLASS;
serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
}};
}
private void setupMockPackageManager(final boolean useDefaultDialer,
final boolean useSystemDialer, final boolean includeExternalCalls) {
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Intent intent = (Intent) args[0];
String packageName = intent.getPackage();
ComponentName componentName = intent.getComponent();
if (componentName != null) {
packageName = componentName.getPackageName();
}
LinkedList<ResolveInfo> resolveInfo = new LinkedList<ResolveInfo>();
if (!TextUtils.isEmpty(packageName)) {
if ((TextUtils.isEmpty(packageName) || packageName.equals(DEF_PKG)) &&
useDefaultDialer) {
resolveInfo.add(getDefResolveInfo(includeExternalCalls));
}
if ((TextUtils.isEmpty(packageName) || packageName.equals(SYS_PKG)) &&
useSystemDialer) {
resolveInfo.add(getSysResolveinfo());
}
}
return resolveInfo;
}
}).when(mMockPackageManager).queryIntentServicesAsUser(
any(Intent.class), eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
}
private void setupMockPackageManagerLocationPermission(final String pkg,
final boolean granted) {
when(mMockPackageManager.checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, pkg))
.thenReturn(granted
? PackageManager.PERMISSION_GRANTED
: PackageManager.PERMISSION_DENIED);
}
}