From c1a1dbf18e869b6c2ac8f1abe740d7582c046b7c Mon Sep 17 00:00:00 2001 From: Hall Liu Date: Thu, 7 Jan 2021 11:53:43 -0800 Subject: [PATCH] Bind to non-ui incall services for self-mgd calls Bind to non-ui incall services that support self managed calls for a self-managed call, even if the main ui incall service doesn't get bound. Bug: 176883407 Test: atest InCallControllerTests, manual Merged-In: I02745189954e4453ce43e5900d4787513f030084 Change-Id: Ida3889b5be4c0ca98d11890afa5984a106b64c5a (cherry picked from 6c3e04a9b1cfc614365890721fb221784a7f9c03) --- .../server/telecom/InCallController.java | 7 +-- .../telecom/tests/InCallControllerTests.java | 51 ++++++++++++++++++- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java index 954aa4447..53ad45bf1 100644 --- a/src/com/android/server/telecom/InCallController.java +++ b/src/com/android/server/telecom/InCallController.java @@ -1393,11 +1393,12 @@ public class InCallController extends CallsManagerListenerBase { mInCallServiceConnection.chooseInitialInCallService(shouldUseCarModeUI()); - // Actually try binding to the UI InCallService. If the response + // Actually try binding to the UI InCallService. if (mInCallServiceConnection.connect(call) == - InCallServiceConnection.CONNECTION_SUCCEEDED) { + InCallServiceConnection.CONNECTION_SUCCEEDED || call.isSelfManaged()) { // Only connect to the non-ui InCallServices if we actually connected to the main UI - // one. + // one, or if the call is self-managed (in which case we'd still want to keep Wear, BT, + // etc. informed. connectToNonUiInCallServices(call); mBindingFuture = new CompletableFuture().completeOnTimeout(false, mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay( diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java index 6a6b9f341..df1119847 100644 --- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java +++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java @@ -876,6 +876,36 @@ public class InCallControllerTests extends TelecomTestCase { verifyBinding(bindIntentCaptor, 1, APPOP_NONUI_PKG, APPOP_NONUI_CLASS); } + /** + * Ensures that the {@link InCallController} will bind to a non-ui service even if no ui service + * is bound if the call is self managed. + */ + @MediumTest + @Test + public void testBindToService_NonUiSelfManaged() throws Exception { + setupMocks(false /* isExternalCall */, true); + setupMockPackageManager(false /* default */, true/* nonui */, true /* appop_nonui */, + true /* system */, false /* external calls */, false /* self mgd in default */, + false /* self mgd in car*/, true /* self managed in nonui */); + + // we should bind to only the non ui app. + mInCallController.bindToServices(mMockCall); + + // Bind InCallServices + ArgumentCaptor bindIntentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mMockContext, times(1)).bindServiceAsUser( + bindIntentCaptor.capture(), + any(ServiceConnection.class), + eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE + | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), + eq(UserHandle.CURRENT)); + + // Verify bind + assertEquals(1, bindIntentCaptor.getAllValues().size()); + + // Should have bound to the third party non ui app. + verifyBinding(bindIntentCaptor, 0, NONUI_PKG, NONUI_CLASS); + } @MediumTest @Test @@ -1238,7 +1268,7 @@ public class InCallControllerTests extends TelecomTestCase { }}; } - private ResolveInfo getNonUiResolveinfo() { + private ResolveInfo getNonUiResolveinfo(boolean supportsSelfManaged) { return new ResolveInfo() {{ serviceInfo = new ServiceInfo(); serviceInfo.packageName = NONUI_PKG; @@ -1247,6 +1277,11 @@ public class InCallControllerTests extends TelecomTestCase { serviceInfo.applicationInfo.uid = NONUI_UID; serviceInfo.enabled = true; serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE; + serviceInfo.metaData = new Bundle(); + if (supportsSelfManaged) { + serviceInfo.metaData.putBoolean( + TelecomManager.METADATA_INCLUDE_SELF_MANAGED_CALLS, true); + } }}; } @@ -1282,6 +1317,18 @@ public class InCallControllerTests extends TelecomTestCase { final boolean useSystemDialer, final boolean includeExternalCalls, final boolean includeSelfManagedCallsInDefaultDialer, final boolean includeSelfManagedCallsInCarModeDialer) { + setupMockPackageManager(useDefaultDialer, useNonUiInCalls/* nonui */, + useAppOpNonUiInCalls/* appop_nonui */, + useSystemDialer, includeExternalCalls, includeSelfManagedCallsInDefaultDialer, + includeSelfManagedCallsInCarModeDialer, false); + } + + private void setupMockPackageManager(final boolean useDefaultDialer, + final boolean useNonUiInCalls, final boolean useAppOpNonUiInCalls, + final boolean useSystemDialer, final boolean includeExternalCalls, + final boolean includeSelfManagedCallsInDefaultDialer, + final boolean includeSelfManagedCallsInCarModeDialer, + final boolean includeSelfManagedCallsInNonUi) { doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { @@ -1319,7 +1366,7 @@ public class InCallControllerTests extends TelecomTestCase { } else { // InCallController uses a blank package name when querying for non-ui incalls if (useNonUiInCalls) { - resolveInfo.add(getNonUiResolveinfo()); + resolveInfo.add(getNonUiResolveinfo(includeSelfManagedCallsInNonUi)); } // InCallController uses a blank package name when querying for App Op non-ui incalls if (useAppOpNonUiInCalls) {