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

Commit 6ff642d5 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. Allow users with across user permission to access phone accounts from other users.

Bug: 255343995
Bug: 257953390
Test: Manual, atest TelecomUnitTests, atest CtsTelecomTestCases
Change-Id: Ifb647f540899dc1f81ef89fcbf249759165fe2e9
parent ffe9e304
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