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

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

Update InCallController to support work profiles.

Allow work profiles to place/receive calls using the associated dialer
app. The existing code will use the primary profile to query the
potential apps to connect to. Instead, we can get the right user from
the phone account that is stored in the call. Also, we need to allow
users with the across users permission to access phone accounts from
other users (getAllPhoneAccountHandles/getCallCapablePhoneAccounts).

A regression was introduced in the initial commit where emergency calls
were unable to be placed from the lock screen so I added a test in
InCallControllerTests to verify that the method behaves properly when
there is not any InCallServices bound.

Bug: 255343995
Bug: 257953390
Bug: 262487224
Test: Manual, atest TelecomUnitTests, atest CtsTelecomTestCases
Change-Id: I3a6977940b989c802eecb5a4ff9077080fae26c3
parent 660551bb
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -1617,6 +1617,26 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
        checkIfRttCapable();
    }

    public UserHandle getUserHandleFromTargetPhoneAccount() {
        return mTargetPhoneAccountHandle == null
                ? mCallsManager.getCurrentUserHandle() :
                mTargetPhoneAccountHandle.getUserHandle();
    }

    public PhoneAccount getPhoneAccountFromHandle() {
        if (getTargetPhoneAccount() == null) {
            return null;
        }
        PhoneAccount phoneAccount = mCallsManager.getPhoneAccountRegistrar()
                .getPhoneAccountUnchecked(getTargetPhoneAccount());

        if (phoneAccount == null) {
            return null;
        }

        return phoneAccount;
    }

    public CharSequence getTargetPhoneAccountLabel() {
        if (getTargetPhoneAccount() == null) {
            return null;
+24 −3
Original line number Diff line number Diff line
@@ -17,10 +17,13 @@
package com.android.server.telecom;

import android.annotation.NonNull;
import android.content.Context;
import android.media.IAudioService;
import android.media.ToneGenerator;
import android.os.UserHandle;
import android.telecom.CallAudioState;
import android.telecom.Log;
import android.telecom.PhoneAccount;
import android.telecom.VideoProfile;
import android.util.SparseArray;

@@ -450,16 +453,34 @@ public class CallAudioManager extends CallsManagerListenerBase {
                CallAudioRouteStateMachine.INCLUDE_BLUETOOTH_IN_BASELINE);
    }

    void silenceRingers() {
    Set<UserHandle> silenceRingers(Context context, UserHandle callingUser) {
        // Store all users from calls that were silenced so that we can silence the
        // InCallServices which are associated with those users.
        Set<UserHandle> userHandles = new HashSet<>();
        boolean allCallSilenced = true;
        synchronized (mCallsManager.getLock()) {
            for (Call call : mRingingCalls) {
                PhoneAccount targetPhoneAccount = call.getPhoneAccountFromHandle();
                UserHandle userFromCall = call.getUserHandleFromTargetPhoneAccount();
                // Do not try to silence calls when calling user is different from the phone account
                // user and the account does not have CAPABILITY_MULTI_USER enabled.
                if (!callingUser.equals(userFromCall) && !targetPhoneAccount.
                        hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
                    allCallSilenced = false;
                    continue;
                }
                userHandles.add(userFromCall);
                call.silence();
            }

            // If all the calls were silenced, we can stop the ringer.
            if (allCallSilenced) {
                mRinger.stopRinging();
                mRinger.stopCallWaiting();
            }
        }
        return userHandles;
    }

    public boolean isRingtonePlaying() {
        return mRinger.isRinging();
+3 −2
Original line number Diff line number Diff line
@@ -2458,7 +2458,7 @@ public class CallsManager extends Call.ListenerBase
            }
        } else if (mPhoneAccountRegistrar.getCallCapablePhoneAccounts(
                requireCallCapableAccountByHandle ? callHandleScheme : null, false,
                call.getInitiatingUser()).isEmpty()) {
                call.getInitiatingUser(), false).isEmpty()) {
            // If there are no call capable accounts, disconnect the call.
            markCallAsDisconnected(call, new DisconnectCause(DisconnectCause.CANCELED,
                    "No registered PhoneAccounts"));
@@ -2924,7 +2924,8 @@ public class CallsManager extends Call.ListenerBase
        List<PhoneAccountHandle> allAccounts =
                mPhoneAccountRegistrar.getCallCapablePhoneAccounts(handle.getScheme(), false, user,
                        capabilities,
                        isEmergency ? 0 : PhoneAccount.CAPABILITY_EMERGENCY_CALLS_ONLY);
                        isEmergency ? 0 : PhoneAccount.CAPABILITY_EMERGENCY_CALLS_ONLY,
                        isEmergency);
        if (mMaxNumberOfSimultaneouslyActiveSims < 0) {
            mMaxNumberOfSimultaneouslyActiveSims =
                    getTelephonyManager().getMaxNumberOfSimultaneouslyActiveSims();
+1 −1
Original line number Diff line number Diff line
@@ -887,7 +887,7 @@ public class ConnectionServiceWrapper extends ServiceBinder implements
                    // an emergency call.
                            mPhoneAccountRegistrar.getCallCapablePhoneAccounts(null /*uriScheme*/,
                            false /*includeDisabledAccounts*/, userHandle, 0 /*capabilities*/,
                            0 /*excludedCapabilities*/);
                            0 /*excludedCapabilities*/, false);
                    PhoneAccountHandle phoneAccountHandle = null;
                    for (PhoneAccountHandle accountHandle : accountHandles) {
                        if(accountHandle.equals(callingPhoneAccountHandle)) {
+14 −1
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.server.telecom;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.telecom.DisconnectCause;
import android.telecom.Log;
import android.telecom.ParcelableConference;
@@ -389,12 +391,23 @@ public class CreateConnectionProcessor implements CreateConnectionResponse {
            // current user.
            // ONLY include phone accounts which are NOT self-managed; we will never consider a self
            // managed phone account for placing an emergency call.
            UserHandle userFromCall = mCall.getUserHandleFromTargetPhoneAccount();
            List<PhoneAccount> allAccounts = mPhoneAccountRegistrar
                    .getAllPhoneAccountsOfCurrentUser()
                    .getAllPhoneAccounts(userFromCall, false)
                    .stream()
                    .filter(act -> !act.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED))
                    .collect(Collectors.toList());

            if (allAccounts.isEmpty()) {
                // Try using phone accounts from other users to place the call (i.e. using an
                // available work sim) given that the current user has the INTERACT_ACROSS_USERS
                // permission.
                allAccounts = mPhoneAccountRegistrar.getAllPhoneAccounts(userFromCall, true)
                        .stream()
                        .filter(act -> !act.hasCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED))
                        .collect(Collectors.toList());
            }

            if (allAccounts.isEmpty() && mContext.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_TELEPHONY)) {
                // If the list of phone accounts is empty at this point, it means Telephony hasn't
Loading