Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b463f281 authored by Youming Ye's avatar Youming Ye Committed by Gerrit Code Review
Browse files

Merge "Enable Telecom to bind third party InCallServices."

parents f5ce1490 6fdc9932
Loading
Loading
Loading
Loading
+33 −8
Original line number Original line Diff line number Diff line
@@ -34,7 +34,6 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.UserHandle;
import android.telecom.CallAudioState;
import android.telecom.CallAudioState;
import android.telecom.ConnectionService;
import android.telecom.ConnectionService;
import android.telecom.DefaultDialerManager;
import android.telecom.InCallService;
import android.telecom.InCallService;
import android.telecom.Log;
import android.telecom.Log;
import android.telecom.Logging.Runnable;
import android.telecom.Logging.Runnable;
@@ -717,6 +716,7 @@ public class InCallController extends CallsManagerListenerBase {
    private static final int IN_CALL_SERVICE_TYPE_SYSTEM_UI = 2;
    private static final int IN_CALL_SERVICE_TYPE_SYSTEM_UI = 2;
    private static final int IN_CALL_SERVICE_TYPE_CAR_MODE_UI = 3;
    private static final int IN_CALL_SERVICE_TYPE_CAR_MODE_UI = 3;
    private static final int IN_CALL_SERVICE_TYPE_NON_UI = 4;
    private static final int IN_CALL_SERVICE_TYPE_NON_UI = 4;
    private static final int IN_CALL_SERVICE_TYPE_COMPANION = 5;


    /** The in-call app implementations, see {@link IInCallService}. */
    /** The in-call app implementations, see {@link IInCallService}. */
    private final Map<InCallServiceInfo, IInCallService> mInCallServices = new ArrayMap<>();
    private final Map<InCallServiceInfo, IInCallService> mInCallServices = new ArrayMap<>();
@@ -1146,6 +1146,17 @@ public class InCallController extends CallsManagerListenerBase {
        for (InCallServiceInfo serviceInfo : nonUIInCallComponents) {
        for (InCallServiceInfo serviceInfo : nonUIInCallComponents) {
            nonUIInCalls.add(new InCallServiceBindingConnection(serviceInfo));
            nonUIInCalls.add(new InCallServiceBindingConnection(serviceInfo));
        }
        }
        List<String> callCompanionApps = mCallsManager
                .getRoleManagerAdapter().getCallCompanionApps();
        if (callCompanionApps != null && !callCompanionApps.isEmpty()) {
            for(String pkg : callCompanionApps) {
                InCallServiceInfo info = getInCallServiceComponent(pkg,
                        IN_CALL_SERVICE_TYPE_COMPANION);
                if (info != null) {
                    nonUIInCalls.add(new InCallServiceBindingConnection(info));
                }
            }
        }
        mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(nonUIInCalls);
        mNonUIInCallServiceConnections = new NonUIInCallServiceConnectionCollection(nonUIInCalls);
        mNonUIInCallServiceConnections.connect(call);
        mNonUIInCallServiceConnections.connect(call);
    }
    }
@@ -1159,9 +1170,10 @@ public class InCallController extends CallsManagerListenerBase {
    }
    }


    private InCallServiceInfo getCarModeComponent() {
    private InCallServiceInfo getCarModeComponent() {
        // Seems strange to cast a String to null, but the signatures of getInCallServiceComponent
        // The signatures of getInCallServiceComponent differ in the types of the first parameter,
        // differ in the types of the first parameter, and passing in null is inherently ambiguous.
        // and passing in null is inherently ambiguous. (If no car mode component found)
        return getInCallServiceComponent((String) null, IN_CALL_SERVICE_TYPE_CAR_MODE_UI);
        String defaultCarMode = mCallsManager.getRoleManagerAdapter().getCarModeDialerApp();
        return getInCallServiceComponent(defaultCarMode, IN_CALL_SERVICE_TYPE_CAR_MODE_UI);
    }
    }


    private InCallServiceInfo getInCallServiceComponent(ComponentName componentName, int type) {
    private InCallServiceInfo getInCallServiceComponent(ComponentName componentName, int type) {
@@ -1216,7 +1228,6 @@ public class InCallController extends CallsManagerListenerBase {
                PackageManager.GET_META_DATA,
                PackageManager.GET_META_DATA,
                mCallsManager.getCurrentUserHandle().getIdentifier())) {
                mCallsManager.getCurrentUserHandle().getIdentifier())) {
            ServiceInfo serviceInfo = entry.serviceInfo;
            ServiceInfo serviceInfo = entry.serviceInfo;

            if (serviceInfo != null) {
            if (serviceInfo != null) {
                boolean isExternalCallsSupported = serviceInfo.metaData != null &&
                boolean isExternalCallsSupported = serviceInfo.metaData != null &&
                        serviceInfo.metaData.getBoolean(
                        serviceInfo.metaData.getBoolean(
@@ -1266,6 +1277,14 @@ public class InCallController extends CallsManagerListenerBase {
            return IN_CALL_SERVICE_TYPE_SYSTEM_UI;
            return IN_CALL_SERVICE_TYPE_SYSTEM_UI;
        }
        }


        // Check to see if the service holds permissions or metadata for third party apps.
        boolean hasInCallServiceUIMetadata = serviceInfo.metaData != null &&
                serviceInfo.metaData.containsKey(TelecomManager.METADATA_IN_CALL_SERVICE_UI);
        boolean isThirdPartyCompanionApp = packageManager.checkPermission(
                Manifest.permission.CALL_COMPANION_APP,
                serviceInfo.packageName) == PackageManager.PERMISSION_GRANTED &&
                !hasInCallServiceUIMetadata;

        // Check to see if the service is a car-mode UI type by checking that it has the
        // Check to see if the service is a car-mode UI type by checking that it has the
        // CONTROL_INCALL_EXPERIENCE (to verify it is a system app) and that it has the
        // CONTROL_INCALL_EXPERIENCE (to verify it is a system app) and that it has the
        // car-mode UI metadata.
        // car-mode UI metadata.
@@ -1275,7 +1294,7 @@ public class InCallController extends CallsManagerListenerBase {
        boolean isCarModeUIService = serviceInfo.metaData != null &&
        boolean isCarModeUIService = serviceInfo.metaData != null &&
                serviceInfo.metaData.getBoolean(
                serviceInfo.metaData.getBoolean(
                        TelecomManager.METADATA_IN_CALL_SERVICE_CAR_MODE_UI, false) &&
                        TelecomManager.METADATA_IN_CALL_SERVICE_CAR_MODE_UI, false) &&
                hasControlInCallPermission;
                (hasControlInCallPermission || isThirdPartyCompanionApp);
        if (isCarModeUIService) {
        if (isCarModeUIService) {
            return IN_CALL_SERVICE_TYPE_CAR_MODE_UI;
            return IN_CALL_SERVICE_TYPE_CAR_MODE_UI;
        }
        }
@@ -1293,9 +1312,15 @@ public class InCallController extends CallsManagerListenerBase {


        // Also allow any in-call service that has the control-experience permission (to ensure
        // Also allow any in-call service that has the control-experience permission (to ensure
        // that it is a system app) and doesn't claim to show any UI.
        // that it is a system app) and doesn't claim to show any UI.
        if (hasControlInCallPermission && !isUIService) {
        if (!isUIService) {
            if (hasControlInCallPermission && !isThirdPartyCompanionApp) {
                return IN_CALL_SERVICE_TYPE_NON_UI;
                return IN_CALL_SERVICE_TYPE_NON_UI;
            }
            }
            // Third party companion alls without CONTROL_INCALL_EXPERIENCE permission.
            if (!hasControlInCallPermission && isThirdPartyCompanionApp) {
                return IN_CALL_SERVICE_TYPE_COMPANION;
            }
        }


        // Anything else that remains, we will not bind to.
        // Anything else that remains, we will not bind to.
        Log.i(this, "Skipping binding to %s:%s, control: %b, car-mode: %b, ui: %b",
        Log.i(this, "Skipping binding to %s:%s, control: %b, car-mode: %b, ui: %b",
+3 −1
Original line number Original line Diff line number Diff line
@@ -73,7 +73,9 @@ public class RoleManagerAdapterImpl implements RoleManagerAdapter {


    @Override
    @Override
    public List<String> getCallCompanionApps() {
    public List<String> getCallCompanionApps() {
        List<String> callCompanionApps = getRoleManagerCallCompanionApps();
        List<String> callCompanionApps = new ArrayList<>();
        // List from RoleManager is not resizable. AbstractList.add action is not supported.
        callCompanionApps.addAll(getRoleManagerCallCompanionApps());
        callCompanionApps.addAll(mOverrideCallCompanionApps);
        callCompanionApps.addAll(mOverrideCallCompanionApps);
        return callCompanionApps;
        return callCompanionApps;
    }
    }
+12 −0
Original line number Original line Diff line number Diff line
@@ -26,9 +26,11 @@ import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.Answer;


import android.Manifest;
import android.app.AppOpsManager;
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.app.NotificationManager;
import android.app.StatusBarManager;
import android.app.StatusBarManager;
// import android.app.role.RoleManager;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentResolver;
@@ -71,6 +73,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Locale;
import java.util.Map;
import java.util.Map;


import static org.mockito.ArgumentMatchers.matches;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyInt;
@@ -181,6 +184,9 @@ public class ComponentContextFixture implements TestFixture<Context> {
                    return mCarrierConfigManager;
                    return mCarrierConfigManager;
                case Context.COUNTRY_DETECTOR:
                case Context.COUNTRY_DETECTOR:
                    return mCountryDetector;
                    return mCountryDetector;
                // TODO: RoleManager not ready yet, uncomment when it's merged into aosp.
                // case Context.ROLE_SERVICE:
                //     return mRoleManager;
                default:
                default:
                    return null;
                    return null;
            }
            }
@@ -432,6 +438,7 @@ public class ComponentContextFixture implements TestFixture<Context> {
    private final Map<String, IContentProvider> mIContentProviderByUri = new HashMap<>();
    private final Map<String, IContentProvider> mIContentProviderByUri = new HashMap<>();
    private final Configuration mResourceConfiguration = new Configuration();
    private final Configuration mResourceConfiguration = new Configuration();
    private final ApplicationInfo mTestApplicationInfo = new ApplicationInfo();
    private final ApplicationInfo mTestApplicationInfo = new ApplicationInfo();
    // private final RoleManager mRoleManager = mock(RoleManager.class);


    private TelecomManager mTelecomManager = null;
    private TelecomManager mTelecomManager = null;


@@ -463,6 +470,11 @@ public class ComponentContextFixture implements TestFixture<Context> {
            }
            }
        }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt());
        }).when(mPackageManager).queryIntentServicesAsUser((Intent) any(), anyInt(), anyInt());


        // By default, tests use non-ui apps instead of 3rd party companion apps.
        when(mPackageManager.checkPermission(
                matches(Manifest.permission.CALL_COMPANION_APP), anyString()))
                .thenReturn(PackageManager.PERMISSION_DENIED);

        when(mTelephonyManager.getSubIdForPhoneAccount((PhoneAccount) any())).thenReturn(1);
        when(mTelephonyManager.getSubIdForPhoneAccount((PhoneAccount) any())).thenReturn(1);


        when(mTelephonyManager.getNetworkOperatorName()).thenReturn("label1");
        when(mTelephonyManager.getNetworkOperatorName()).thenReturn("label1");
+150 −4
Original line number Original line Diff line number Diff line
@@ -50,6 +50,7 @@ import com.android.server.telecom.EmergencyCallHelper;
import com.android.server.telecom.InCallController;
import com.android.server.telecom.InCallController;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.R;
import com.android.server.telecom.R;
import com.android.server.telecom.RoleManagerAdapter;
import com.android.server.telecom.SystemStateHelper;
import com.android.server.telecom.SystemStateHelper;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.TelecomSystem;
import com.android.server.telecom.Timeouts;
import com.android.server.telecom.Timeouts;
@@ -65,11 +66,15 @@ import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.Answer;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Collections;
import java.util.LinkedList;
import java.util.LinkedList;
import java.util.List;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.matches;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyInt;
@@ -95,12 +100,17 @@ public class InCallControllerTests extends TelecomTestCase {
    @Mock MockContext mMockContext;
    @Mock MockContext mMockContext;
    @Mock Timeouts.Adapter mTimeoutsAdapter;
    @Mock Timeouts.Adapter mTimeoutsAdapter;
    @Mock DefaultDialerCache mDefaultDialerCache;
    @Mock DefaultDialerCache mDefaultDialerCache;
    @Mock RoleManagerAdapter mMockRoleManagerAdapter;


    private static final int CURRENT_USER_ID = 900973;
    private static final int CURRENT_USER_ID = 900973;
    private static final String DEF_PKG = "defpkg";
    private static final String DEF_PKG = "defpkg";
    private static final String DEF_CLASS = "defcls";
    private static final String DEF_CLASS = "defcls";
    private static final String SYS_PKG = "syspkg";
    private static final String SYS_PKG = "syspkg";
    private static final String SYS_CLASS = "syscls";
    private static final String SYS_CLASS = "syscls";
    private static final String COMPANION_PKG = "cpnpkg";
    private static final String COMPANION_CLASS = "cpncls";
    private static final String CAR_PKG = "carpkg";
    private static final String CAR_CLASS = "carcls";
    private static final PhoneAccountHandle PA_HANDLE =
    private static final PhoneAccountHandle PA_HANDLE =
            new PhoneAccountHandle(new ComponentName("pa_pkg", "pa_cls"), "pa_id");
            new PhoneAccountHandle(new ComponentName("pa_pkg", "pa_cls"), "pa_id");


@@ -121,9 +131,17 @@ public class InCallControllerTests extends TelecomTestCase {
        doReturn(true).when(mMockResources).getBoolean(R.bool.grant_location_permission_enabled);
        doReturn(true).when(mMockResources).getBoolean(R.bool.grant_location_permission_enabled);
        mEmergencyCallHelper = new EmergencyCallHelper(mMockContext, SYS_PKG,
        mEmergencyCallHelper = new EmergencyCallHelper(mMockContext, SYS_PKG,
                mTimeoutsAdapter);
                mTimeoutsAdapter);
        when(mMockCallsManager.getRoleManagerAdapter()).thenReturn(mMockRoleManagerAdapter);
        mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
        mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
                mMockSystemStateHelper, mDefaultDialerCache, mTimeoutsAdapter,
                mMockSystemStateHelper, mDefaultDialerCache, mTimeoutsAdapter,
                mEmergencyCallHelper);
                mEmergencyCallHelper);
        // Companion Apps don't have CONTROL_INCALL_EXPERIENCE permission.
        when(mMockPackageManager.checkPermission(
                matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
                matches(COMPANION_PKG))).thenReturn(PackageManager.PERMISSION_DENIED);
        when(mMockPackageManager.checkPermission(
                matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
                matches(CAR_PKG))).thenReturn(PackageManager.PERMISSION_DENIED);
    }
    }


    @Override
    @Override
@@ -493,6 +511,103 @@ public class InCallControllerTests extends TelecomTestCase {
        verify(mockInCallService).addCall(any(ParcelableCall.class));
        verify(mockInCallService).addCall(any(ParcelableCall.class));
    }
    }


    /**
     * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
     * supports third party companion calls.
     */
    @MediumTest
    public void doNotTestBindToService_Companion() throws Exception {
        setupMocks(true /* isExternalCall */);
        setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);

        List<String> companionAppsList = new ArrayList<>();
        companionAppsList.add(COMPANION_PKG);
        companionAppsList.add(COMPANION_PKG);
        when(mMockRoleManagerAdapter.getCallCompanionApps()).thenReturn(companionAppsList);
        mInCallController.bindToServices(mMockCall);

        // Query for the different InCallServices
        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mMockPackageManager, times(6)).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 system dialer InCallService
        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
        // Verify call for car mode ui InCallServices
        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
        // Verify call for non-UI InCallServices
        assertEquals(null, queryIntentCaptor.getAllValues().get(3).getPackage());
        // Verify call for companion InCallServices
        assertEquals(COMPANION_PKG, queryIntentCaptor.getAllValues().get(4).getPackage());
        assertEquals(COMPANION_PKG, queryIntentCaptor.getAllValues().get(5).getPackage());

        // Bind InCallServices
        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mMockContext, times(3)).bindServiceAsUser(
                bindIntentCaptor.capture(),
                any(ServiceConnection.class),
                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
                eq(UserHandle.CURRENT));
        // Verify bind dialer
        Intent bindIntent = bindIntentCaptor.getAllValues().get(0);
        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
        assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
        assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
        // Verify bind companion apps
        bindIntent = bindIntentCaptor.getAllValues().get(1);
        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
        assertEquals(COMPANION_PKG, bindIntent.getComponent().getPackageName());
        assertEquals(COMPANION_CLASS, bindIntent.getComponent().getClassName());
        bindIntent = bindIntentCaptor.getAllValues().get(2);
        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
        assertEquals(COMPANION_PKG, bindIntent.getComponent().getPackageName());
        assertEquals(COMPANION_CLASS, bindIntent.getComponent().getClassName());
    }

    /**
     * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
     * supports third party car mode ui calls
     */
    @MediumTest
    public void doNotTestBindToService_CarModeUI() throws Exception {
        setupMocks(true /* isExternalCall */);
        setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);

        when(mMockRoleManagerAdapter.getCarModeDialerApp()).thenReturn(CAR_PKG);
        // Enable car mode
        when(mMockSystemStateHelper.isCarMode()).thenReturn(true);
        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 system dialer InCallService
        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
        // Verify call for car mode ui InCallServices
        assertEquals(CAR_PKG, queryIntentCaptor.getAllValues().get(2).getPackage());
        // Verify call for non-UI InCallServices
        assertEquals(null, queryIntentCaptor.getAllValues().get(3).getPackage());

        // Bind InCallServices
        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));
        // Verify bind car mode ui
        Intent bindIntent = bindIntentCaptor.getAllValues().get(0);
        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
        assertEquals(CAR_PKG, bindIntent.getComponent().getPackageName());
        assertEquals(CAR_CLASS, bindIntent.getComponent().getClassName());
    }

    private void setupMocks(boolean isExternalCall) {
    private void setupMocks(boolean isExternalCall) {
        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
@@ -521,6 +636,22 @@ public class InCallControllerTests extends TelecomTestCase {
        }};
        }};
    }
    }


    private ResolveInfo getCarModeResolveinfo(final boolean includeExternalCalls) {
        return new ResolveInfo() {{
            serviceInfo = new ServiceInfo();
            serviceInfo.packageName = CAR_PKG;
            serviceInfo.name = CAR_CLASS;
            serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
            serviceInfo.metaData = new Bundle();
            serviceInfo.metaData.putBoolean(
                    TelecomManager.METADATA_IN_CALL_SERVICE_CAR_MODE_UI, true);
            if (includeExternalCalls) {
                serviceInfo.metaData.putBoolean(
                        TelecomManager.METADATA_INCLUDE_EXTERNAL_CALLS, true);
            }
        }};
    }

    private ResolveInfo getSysResolveinfo() {
    private ResolveInfo getSysResolveinfo() {
        return new ResolveInfo() {{
        return new ResolveInfo() {{
            serviceInfo = new ServiceInfo();
            serviceInfo = new ServiceInfo();
@@ -530,6 +661,15 @@ public class InCallControllerTests extends TelecomTestCase {
        }};
        }};
    }
    }


    private ResolveInfo getCompanionResolveinfo() {
        return new ResolveInfo() {{
            serviceInfo = new ServiceInfo();
            serviceInfo.packageName = COMPANION_PKG;
            serviceInfo.name = COMPANION_CLASS;
            serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
        }};
    }

    private void setupMockPackageManager(final boolean useDefaultDialer,
    private void setupMockPackageManager(final boolean useDefaultDialer,
            final boolean useSystemDialer, final boolean includeExternalCalls) {
            final boolean useSystemDialer, final boolean includeExternalCalls) {


@@ -545,15 +685,21 @@ public class InCallControllerTests extends TelecomTestCase {
                }
                }
                LinkedList<ResolveInfo> resolveInfo = new LinkedList<ResolveInfo>();
                LinkedList<ResolveInfo> resolveInfo = new LinkedList<ResolveInfo>();
                if (!TextUtils.isEmpty(packageName)) {
                if (!TextUtils.isEmpty(packageName)) {
                    if ((TextUtils.isEmpty(packageName) || packageName.equals(DEF_PKG)) &&
                    if (packageName.equals(DEF_PKG) && useDefaultDialer) {
                            useDefaultDialer) {
                        resolveInfo.add(getDefResolveInfo(includeExternalCalls));
                        resolveInfo.add(getDefResolveInfo(includeExternalCalls));
                    }
                    }


                    if ((TextUtils.isEmpty(packageName) || packageName.equals(SYS_PKG)) &&
                    if (packageName.equals(SYS_PKG) && useSystemDialer) {
                           useSystemDialer) {
                        resolveInfo.add(getSysResolveinfo());
                        resolveInfo.add(getSysResolveinfo());
                    }
                    }

                    if (packageName.equals(COMPANION_PKG)) {
                        resolveInfo.add(getCompanionResolveinfo());
                    }

                    if (packageName.equals(CAR_PKG)) {
                        resolveInfo.add(getCarModeResolveinfo(includeExternalCalls));
                    }
                }
                }
                return resolveInfo;
                return resolveInfo;
            }
            }