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

Commit f5650326 authored by Pranav Madapurmath's avatar Pranav Madapurmath
Browse files

Fix secondary user unable to access in-call screen

We bind to the InCallService for the user placing the call (this is
derived from the phone account). This was changed from binding to
UserHandle.CURRENT to support the incoming work profile changes
that were added into U. Falling back on binding the service on
UserHandle.CURRENT in scenarios where the user placing the call is not
running under a managed profile (i.e. work) and is not the same as
UserHandle.CURRENT will resolve this issue.

From manual testing, I can see that work calls are still binding to the
work profile dialer. For the secondary user, I can see the call screen
pop up while the call is dialing and we can click into the notification.
The calls made on the personal profile are still working as intended.

Fixes: 276611583
Test: Manual (tested calls on admin/work/secondary user)
Change-Id: Ic4e071b1831c89d26811d66081ac2ae2aaa96d72
parent 6225289f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -336,6 +336,10 @@ public class InCallController extends CallsManagerListenerBase implements
            mIsConnected = true;
            mInCallServiceInfo.setBindingStartTime(mClockProxy.elapsedRealtime());
            UserHandle userToBind = getUserFromCall(call);
            boolean isManagedProfile = UserUtil.isManagedProfile(mContext, userToBind);
            // Note that UserHandle.CURRENT fails to capture the work profile, so we need to handle
            // it separately to ensure that the ICS is bound to the appropriate user.
            userToBind = isManagedProfile ? userToBind : UserHandle.CURRENT;
            if (!mContext.bindServiceAsUser(intent, mServiceConnection,
                    Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
                        | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
+27 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.compat.testing.PlatformCompatChangeRule;
import android.os.Binder;
@@ -152,6 +153,7 @@ public class InCallControllerTests extends TelecomTestCase {
    @Mock InCallController.InCallServiceInfo mInCallServiceInfo;
    @Mock private AnomalyReporterAdapter mAnomalyReporterAdapter;
    @Mock UserManager mMockUserManager;
    @Mock UserInfo mMockUserInfo;

    @Rule
    public TestRule compatChangeRule = new PlatformCompatChangeRule();
@@ -284,6 +286,11 @@ public class InCallControllerTests extends TelecomTestCase {
                .thenReturn(PackageManager.PERMISSION_DENIED);

        when(mMockCallsManager.getAudioState()).thenReturn(new CallAudioState(false, 0, 0));

        when(mMockContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mMockUserManager);
        // Mock user info to allow binding on user stored in the phone account (mUserHandle).
        when(mMockUserManager.getUserInfo(anyInt())).thenReturn(mMockUserInfo);
        when(mMockUserInfo.isManagedProfile()).thenReturn(true);
    }

    @Override
@@ -1464,6 +1471,26 @@ public class InCallControllerTests extends TelecomTestCase {
                android.telecom.Call.EXTRA_IS_SUPPRESSED_BY_DO_NOT_DISTURB));
    }

    @Test
    public void testSecondaryUserCallBindToCurrentUser() throws Exception {
        setupMocks(true /* isExternalCall */);
        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
        // Force the difference between the phone account user and current user. This is supposed to
        // simulate a secondary user placing a call over an unassociated sim.
        assertFalse(mUserHandle.equals(UserHandle.USER_CURRENT));
        when(mMockUserInfo.isManagedProfile()).thenReturn(false);

        mInCallController.bindToServices(mMockCall);

        // Bind InCallService on UserHandle.CURRENT and not the user from the call (mUserHandle)
        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mMockContext, times(1)).bindServiceAsUser(
                bindIntentCaptor.capture(),
                any(ServiceConnection.class),
                eq(serviceBindingFlags),
                eq(UserHandle.CURRENT));
    }

    private void setupMocks(boolean isExternalCall) {
        setupMocks(isExternalCall, false /* isSelfManagedCall */);
    }