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

Commit bbfd9831 authored by Brad Ebinger's avatar Brad Ebinger Committed by Android (Google) Code Review
Browse files

Merge "Integrate Calling Restrictions into the outgoing call flow" into main

parents f5094557 55a97f9c
Loading
Loading
Loading
Loading
+88 −5
Original line number Diff line number Diff line
@@ -82,7 +82,6 @@ import android.provider.BlockedNumberContract;
import android.provider.BlockedNumberContract.BlockedNumbers;
import android.provider.CallLog.Calls;
import android.provider.Settings;
import android.sysprop.TelephonyProperties;
import android.telecom.CallAttributes;
import android.telecom.CallAudioState;
import android.telecom.CallEndpoint;
@@ -165,7 +164,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -491,6 +489,7 @@ public class CallsManager extends Call.ListenerBase
    private final UserManager mUserManager;
    private final CallStreamingNotification mCallStreamingNotification;
    private final FeatureFlags mFeatureFlags;
    private final com.android.internal.telephony.flags.FeatureFlags mTelephonyFeatureFlags;

    private final IncomingCallFilterGraphProvider mIncomingCallFilterGraphProvider;

@@ -610,6 +609,7 @@ public class CallsManager extends Call.ListenerBase
            CallStreamingNotification callStreamingNotification,
            BluetoothDeviceManager bluetoothDeviceManager,
            FeatureFlags featureFlags,
            com.android.internal.telephony.flags.FeatureFlags telephonyFlags,
            IncomingCallFilterGraphProvider incomingCallFilterGraphProvider) {

        mContext = context;
@@ -717,6 +717,7 @@ public class CallsManager extends Call.ListenerBase
        mCallStreamingController = new CallStreamingController(mContext, mLock);
        mCallStreamingNotification = callStreamingNotification;
        mFeatureFlags = featureFlags;
        mTelephonyFeatureFlags = telephonyFlags;

        if (mFeatureFlags.useImprovedListenerOrder()) {
            mListeners.add(mInCallController);
@@ -3428,8 +3429,14 @@ public class CallsManager extends Call.ListenerBase
    // then include only that SIM based PhoneAccount and any non-SIM PhoneAccounts, such as SIP.
    @VisibleForTesting
    public List<PhoneAccountHandle> constructPossiblePhoneAccounts(Uri handle, UserHandle user,
            boolean isVideo, boolean isEmergency) {
        return constructPossiblePhoneAccounts(handle, user, isVideo, isEmergency, false);
            boolean isVideo, boolean isEmergency,  boolean isConference) {
        if (mTelephonyFeatureFlags.simultaneousCallingIndications()) {
            return constructPossiblePhoneAccountsNew(handle, user, isVideo, isEmergency,
                    isConference);
        } else {
            return constructPossiblePhoneAccountsOld(handle, user, isVideo, isEmergency,
                    isConference);
        }
    }

    // Returns whether the device is capable of 2 simultaneous active voice calls on different subs.
@@ -3444,7 +3451,7 @@ public class CallsManager extends Call.ListenerBase
        }
    }

    public List<PhoneAccountHandle> constructPossiblePhoneAccounts(Uri handle, UserHandle user,
    private List<PhoneAccountHandle> constructPossiblePhoneAccountsOld(Uri handle, UserHandle user,
            boolean isVideo, boolean isEmergency, boolean isConference) {

        if (handle == null) {
@@ -3485,6 +3492,82 @@ public class CallsManager extends Call.ListenerBase
        return allAccounts;
    }

    /**
     * Filters the list of all PhoneAccounts that match the outgoing call Handle's schema against
     * the outgoing call request criteria and the state of the already ongoing calls on the
     * device and their potential simultaneous calling restrictions.
     * @return The filtered List
     */
    private List<PhoneAccountHandle> constructPossiblePhoneAccountsNew(Uri handle, UserHandle user,
            boolean isVideo, boolean isEmergency, boolean isConference) {
        if (handle == null) {
            return Collections.emptyList();
        }
        // If we're specifically looking for video capable accounts, then include that capability,
        // otherwise specify no additional capability constraints. When handling the emergency call,
        // it also needs to find the phone accounts excluded by CAPABILITY_EMERGENCY_CALLS_ONLY.
        int capabilities = isVideo ? PhoneAccount.CAPABILITY_VIDEO_CALLING : 0;
        capabilities |= isConference ? PhoneAccount.CAPABILITY_ADHOC_CONFERENCE_CALLING : 0;
        List<PhoneAccountHandle> allAccounts =
                mPhoneAccountRegistrar.getCallCapablePhoneAccounts(handle.getScheme(), false, user,
                        capabilities,
                        isEmergency ? 0 : PhoneAccount.CAPABILITY_EMERGENCY_CALLS_ONLY,
                        isEmergency);
        Log.v(this, "constructPossiblePhoneAccountsNew: allAccounts=" + allAccounts);
        Set<PhoneAccountHandle> activeCallAccounts = mCalls.stream()
                .filter(c -> !c.isDisconnected() && !c.isNew()).map(Call::getTargetPhoneAccount)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        Log.v(this, "constructPossiblePhoneAccountsNew: activeCallAccounts="
                + activeCallAccounts);
        // No Active calls - all accounts are valid
        if (activeCallAccounts.isEmpty()) return allAccounts;
        // The emergency call should be attempted only over the same SIM PhoneAccounts where there
        // are already ongoing calls - filter out inactive SIM PhoneAccounts in this case.
        if (isEmergency) {
            Set<PhoneAccountHandle> simAccounts =
                    new HashSet<>(mPhoneAccountRegistrar.getSimPhoneAccountsOfCurrentUser());
            if (activeCallAccounts.stream().anyMatch(simAccounts::contains)) {
                allAccounts.removeIf(h -> {
                    boolean isRemoved = simAccounts.contains(h) && !activeCallAccounts.contains(h);
                    if (isRemoved) {
                        Log.i(this, "constructPossiblePhoneAccountsNew: removing candidate PAH ["
                                + h + "] because another SIM account is active with an emergency "
                                + "call");
                    }
                    return isRemoved;
                });
            }
        }
        // Apply restrictions to which PhoneAccounts can be used to place a call by looking at
        // active calls and removing candidate PhoneAccounts if they are from the same source
        // as the active call and the candidate PhoneAccount is not part of the restriction.
        for (PhoneAccountHandle callHandle : activeCallAccounts) {
            allAccounts.removeIf(candidateHandle -> {
                PhoneAccount callAcct = mPhoneAccountRegistrar.getPhoneAccount(callHandle,
                        user);
                if (callAcct == null) {
                    Log.w(this, "constructPossiblePhoneAccountsNew: unexpected"
                            + "null PA for PAH, removing : " + candidateHandle);
                    return true;
                }
                boolean isRemoved = !Objects.equals(candidateHandle, callHandle)
                        && Objects.equals(candidateHandle.getComponentName(),
                                callHandle.getComponentName())
                        && callAcct.hasSimultaneousCallingRestriction()
                        && !callAcct.getSimultaneousCallingRestriction().contains(candidateHandle);
                if (isRemoved) {
                    Log.i(this, "constructPossiblePhoneAccountsNew: removing candidate"
                            + " PAH [" + candidateHandle + "] because it is not part of the"
                            + " restriction set by [" + callHandle + "], restriction="
                            + callAcct.getSimultaneousCallingRestriction());
                }
                return isRemoved;
            });
        }
        return allAccounts;
    }

    private TelephonyManager getTelephonyManager() {
        return mContext.getSystemService(TelephonyManager.class);
    }
+3 −1
Original line number Diff line number Diff line
@@ -230,7 +230,8 @@ public class TelecomSystem {
            Executor asyncTaskExecutor,
            Executor asyncCallAudioTaskExecutor,
            BlockedNumbersAdapter blockedNumbersAdapter,
            FeatureFlags featureFlags) {
            FeatureFlags featureFlags,
            com.android.internal.telephony.flags.FeatureFlags telephonyFlags) {
        mContext = context.getApplicationContext();
        mFeatureFlags = featureFlags;
        LogUtils.initLogging(mContext);
@@ -427,6 +428,7 @@ public class TelecomSystem {
                    callStreamingNotification,
                    bluetoothDeviceManager,
                    featureFlags,
                    telephonyFlags,
                    IncomingCallFilterGraph::new);

            mIncomingCallNotifier = incomingCallNotifier;
+2 −1
Original line number Diff line number Diff line
@@ -234,7 +234,8 @@ public class TelecomService extends Service implements TelecomSystem.Component {
                                            showNotification);
                                }
                            },
                            new FeatureFlagsImpl()));
                            new FeatureFlagsImpl(),
                            new com.android.internal.telephony.flags.FeatureFlagsImpl()));
        }
    }

+297 −9

File changed.

Preview size limit exceeded, changes collapsed.

+4 −1
Original line number Diff line number Diff line
@@ -221,6 +221,8 @@ public class TelecomSystemTest extends TelecomTestCase{
    CallAudioCommunicationDeviceTracker mCommunicationDeviceTracker;
    @Mock
    FeatureFlags mFeatureFlags;
    @Mock
    com.android.internal.telephony.flags.FeatureFlags mTelephonyFlags;

    final ComponentName mInCallServiceComponentNameX =
            new ComponentName(
@@ -581,7 +583,8 @@ public class TelecomSystemTest extends TelecomTestCase{
                Runnable::run,
                Runnable::run,
                mBlockedNumbersAdapter,
                mFeatureFlags);
                mFeatureFlags,
                mTelephonyFlags);

        mComponentContextFixture.setTelecomManager(new TelecomManager(
                mComponentContextFixture.getTestDouble(),