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

Commit 0d88e9fb authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/32808568'] into 25Q2-release.

Change-Id: I070a745173c8fda054999ee07a5c210b6c9162c2
parents 0db24b00 b8f6be8c
Loading
Loading
Loading
Loading
+36 −3
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import static android.telecom.TelecomManager.SHORT_CALL_TIME_MS;
import static android.telecom.TelecomManager.VERY_SHORT_CALL_TIME_MS;

import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -155,6 +156,8 @@ import com.android.server.telecom.callsequencing.voip.VoipCallMonitor;
import com.android.server.telecom.callsequencing.TransactionManager;
import com.android.server.telecom.callsequencing.voip.VoipCallMonitorLegacy;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -189,6 +192,23 @@ import java.util.stream.Stream;
 */
public class CallsManager extends Call.ListenerBase
        implements VideoProviderProxy.Listener, CallFilterResultCallback, CurrentUserProxy {
    /**
     * The origin of the request is not known.
     */
    public static final int REQUEST_ORIGIN_UNKNOWN = -1;

    /**
     * The request originated from a Telecom-provided disambiguation.
     */
    public static final int REQUEST_ORIGIN_TELECOM_DISAMBIGUATION = 1;

    /**
     * @hide
     */
    @IntDef(prefix = { "REQUEST_ORIGIN_" },
            value = {REQUEST_ORIGIN_UNKNOWN, REQUEST_ORIGIN_TELECOM_DISAMBIGUATION})
    @Retention(RetentionPolicy.SOURCE)
    public @interface RequestOrigin {}

    // TODO: Consider renaming this CallsManagerPlugin.
    @VisibleForTesting
@@ -3267,6 +3287,18 @@ public class CallsManager extends Call.ListenerBase
        call.conferenceWith(otherCall);
    }

    /**
     * Similar to {@link #answerCall(Call, int, int)}, instructs Telecom to answer the specified
     * call.  This prototype assumes that the origin of the request is
     * {@link #REQUEST_ORIGIN_UNKNOWN} for the time being.  In most cases this is likely a user
     * request to answer a call, but could be internal to Telecom.
     * @param call The call to answer.
     * @param videoState The video state in which to answer the call.
     */
    public void answerCall(Call call, int videoState) {
        answerCall(call, videoState, REQUEST_ORIGIN_UNKNOWN);
    }

    /**
     * Instructs Telecom to answer the specified call. Intended to be invoked by the in-call
     * app through {@link InCallAdapter} after Telecom notifies it of an incoming call followed by
@@ -3274,13 +3306,14 @@ public class CallsManager extends Call.ListenerBase
     *
     * @param call The call to answer.
     * @param videoState The video state in which to answer the call.
     * @param requestOrigin The origin of the request being made.
     */
    @VisibleForTesting
    public void answerCall(Call call, int videoState) {
    public void answerCall(Call call, int videoState, @RequestOrigin int requestOrigin) {
        if (!mCalls.contains(call)) {
            Log.i(this, "Request to answer a non-existent call %s", call);
        }
        mCallSequencingAdapter.answerCall(call, videoState);
        mCallSequencingAdapter.answerCall(call, videoState, requestOrigin);
    }

    /**
@@ -3293,7 +3326,7 @@ public class CallsManager extends Call.ListenerBase
     * <p>
     * Note: This is only used when {@link FeatureFlags#enableCallSequencing()} is false.
     */
    public void answerCallOld(Call call, int videoState) {
    public void answerCallOld(Call call, int videoState, @RequestOrigin int requestOrigin) {
        if (call.isTransactionalCall()) {
            // InCallAdapter is requesting to answer the given transactioanl call. Must get an ack
            // from the client via a transaction before answering.
+2 −1
Original line number Diff line number Diff line
@@ -184,7 +184,8 @@ public final class TelecomBroadcastIntentProcessor {
                // Answer the current ringing call.
                Call incomingCall = mCallsManager.getIncomingCallNotifier().getIncomingCall();
                if (incomingCall != null) {
                    mCallsManager.answerCall(incomingCall, incomingCall.getVideoState());
                    mCallsManager.answerCall(incomingCall, incomingCall.getVideoState(),
                            CallsManager.REQUEST_ORIGIN_TELECOM_DISAMBIGUATION);
                }
            } finally {
                Log.endSession();
+20 −7
Original line number Diff line number Diff line
@@ -169,11 +169,16 @@ public class CallSequencingController {
     * sequencing provided that the calls that are being manipulated are across phone accounts.
     * @param incomingCall The incoming call to be answered.
     * @param videoState The video state configuration for the provided call.
     * @param requestOrigin The origin of the request to answer the call; this can impact sequencing
     *                      decisions as requests that Telecom makes can override rules we have set
     *                      for actions which originate from outside.
     */
    public void answerCall(Call incomingCall, int videoState) {
    public void answerCall(Call incomingCall, int videoState,
            @CallsManager.RequestOrigin int requestOrigin) {
        Log.i(this, "answerCall: Beginning call sequencing transaction for answering "
                + "incoming call.");
        holdActiveCallForNewCallWithSequencing(incomingCall).thenComposeAsync((result) -> {
        holdActiveCallForNewCallWithSequencing(incomingCall, requestOrigin)
                .thenComposeAsync((result) -> {
                if (result) {
                    mCallsManager.requestFocusActionAnswerCall(incomingCall, videoState);
                } else {
@@ -190,7 +195,8 @@ public class CallSequencingController {
     * @param call The self-managed call that's waiting to go active.
     */
    public void handleSetSelfManagedCallActive(Call call) {
        holdActiveCallForNewCallWithSequencing(call).thenComposeAsync((result) -> {
        holdActiveCallForNewCallWithSequencing(call, CallsManager.REQUEST_ORIGIN_UNKNOWN)
                .thenComposeAsync((result) -> {
                if (result) {
                    Log.i(this, "markCallAsActive: requesting focus for self managed call "
                            + "before setting active.");
@@ -218,7 +224,7 @@ public class CallSequencingController {
     */
    public void transactionHoldPotentialActiveCallForNewCallSequencing(
            Call newCall, OutcomeReceiver<Boolean, CallException> callback) {
        holdActiveCallForNewCallWithSequencing(newCall)
        holdActiveCallForNewCallWithSequencing(newCall, CallsManager.REQUEST_ORIGIN_UNKNOWN)
                .thenComposeAsync((result) -> {
                    if (result) {
                        // Either we were able to hold the active call or the active call was
@@ -245,13 +251,14 @@ public class CallSequencingController {
     * Attempts to hold the active call so that the provided call can go active. This is done via
     * call sequencing and the resulting future is an indication of whether that request
     * has succeeded.
     *
     * @param call The call that's waiting to go active.
     * @return The {@link CompletableFuture} indicating the result of whether the
     * active call was able to be held (if applicable).
     */
    @VisibleForTesting
    public CompletableFuture<Boolean> holdActiveCallForNewCallWithSequencing(
            Call call) {
            Call call, int requestOrigin) {
        Call activeCall = (Call) mCallsManager.getConnectionServiceFocusManager()
                .getCurrentFocusCall();
        Log.i(this, "holdActiveCallForNewCallWithSequencing, newCall: %s, "
@@ -292,8 +299,14 @@ public class CallSequencingController {
                    // and the held call is a carrier call, then disconnect the held call. The
                    // idea is that if we have a held carrier call and the incoming call is a
                    // VOIP call, we don't want to force the carrier call to auto-disconnect).
                    if (isManagedCall(heldCall) && isVoipCall(call)) {
                    // Note: If the origin of this request was from the Telecom call incoming call
                    // disambiguation notification, we will allow the request to continue.
                    if (isManagedCall(heldCall) && isVoipCall(call) && requestOrigin
                            != CallsManager.REQUEST_ORIGIN_TELECOM_DISAMBIGUATION) {
                        // Otherwise, fail the transaction.
                        Log.w(this, "holdActiveCallForNewCallWithSequencing: ignoring request to "
                                + "disconnect carrier call %s for voip call %s.", activeCall,
                                heldCall);
                        return CompletableFuture.completedFuture(false);
                    } else {
                        isSequencingRequiredHeldAndActive = !arePhoneAccountsSame(
+5 −3
Original line number Diff line number Diff line
@@ -70,12 +70,14 @@ public class CallsManagerCallSequencingAdapter {
     * (mIsCallSequencingEnabled) is enabled.
     * @param incomingCall The incoming call that should be answered.
     * @param videoState The video state configuration associated with the call.
     * @param requestOrigin The origin of the request.
     */
    public void answerCall(Call incomingCall, int videoState) {
    public void answerCall(Call incomingCall, int videoState,
            @CallsManager.RequestOrigin int requestOrigin) {
        if (mIsCallSequencingEnabled && !incomingCall.isTransactionalCall()) {
            mSequencingController.answerCall(incomingCall, videoState);
            mSequencingController.answerCall(incomingCall, videoState, requestOrigin);
        } else {
            mCallsManager.answerCallOld(incomingCall, videoState);
            mCallsManager.answerCallOld(incomingCall, videoState, requestOrigin);
        }
    }

+37 −12
Original line number Diff line number Diff line
@@ -194,7 +194,7 @@ public class CallSequencingTests extends TelecomTestCase {
    public void testAnswerCall() {
        // This will allow holdActiveCallForNewCallWithSequencing to immediately return true
        setActiveCallFocus(null);
        mController.answerCall(mNewCall, 0);
        mController.answerCall(mNewCall, 0, CallsManager.REQUEST_ORIGIN_UNKNOWN);
        verify(mCallsManager, timeout(SEQUENCING_TIMEOUT_MS))
                .requestFocusActionAnswerCall(eq(mNewCall), eq(0));
    }
@@ -203,11 +203,26 @@ public class CallSequencingTests extends TelecomTestCase {
    @Test
    public void testAnswerCallFail() {
        setupHoldActiveCallForNewCallFailMocks();
        mController.answerCall(mNewCall, 0);
        mController.answerCall(mNewCall, 0, CallsManager.REQUEST_ORIGIN_UNKNOWN);
        verify(mCallsManager, timeout(SEQUENCING_TIMEOUT_MS).times(0))
                .requestFocusActionAnswerCall(eq(mNewCall), eq(0));
    }

    @SmallTest
    @Test
    public void testAnswerCallAcceptedFromTelecom() {
        setPhoneAccounts(mNewCall, mActiveCall, false);
        setActiveCallFocus(mActiveCall);
        when(mCallsManager.canHold(mActiveCall)).thenReturn(true);
        when(mActiveCall.hold(anyString())).thenReturn(CompletableFuture.completedFuture(true));

        when(mHeldCall.isSelfManaged()).thenReturn(false);
        when(mNewCall.isSelfManaged()).thenReturn(true);
        mController.answerCall(mNewCall, 0, CallsManager.REQUEST_ORIGIN_TELECOM_DISAMBIGUATION);
        verify(mCallsManager, timeout(SEQUENCING_TIMEOUT_MS).times(1))
                .requestFocusActionAnswerCall(eq(mNewCall), eq(0));
    }

    @SmallTest
    @Test
    public void testSetSelfManagedCallActive() {
@@ -270,7 +285,8 @@ public class CallSequencingTests extends TelecomTestCase {
    public void testHoldCallForNewCall_NoActiveCall() {
        setActiveCallFocus(null);
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        assertTrue(waitForFutureResult(resultFuture, false));
    }

@@ -285,13 +301,15 @@ public class CallSequencingTests extends TelecomTestCase {
        // Cross phone account case (sequencing enabled)
        assertFalse(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        assertTrue(waitForFutureResult(resultFuture, false));

        // Same phone account case
        setPhoneAccounts(mNewCall, mActiveCall, true);
        assertTrue(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        resultFuture = mController.holdActiveCallForNewCallWithSequencing(mNewCall);
        resultFuture = mController.holdActiveCallForNewCallWithSequencing(mNewCall,
                CallsManager.REQUEST_ORIGIN_UNKNOWN);
        assertTrue(waitForFutureResult(resultFuture, false));
    }

@@ -312,7 +330,8 @@ public class CallSequencingTests extends TelecomTestCase {
        // disconnect the active (carrier) call.
        assertFalse(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        verify(mHeldCall, timeout(SEQUENCING_TIMEOUT_MS)).disconnect();
        verify(mActiveCall, timeout(SEQUENCING_TIMEOUT_MS)).hold();
        verify(mNewCall).increaseHeldByThisCallCount();
@@ -332,7 +351,8 @@ public class CallSequencingTests extends TelecomTestCase {
        // Cross phone account case (sequencing enabled)
        assertFalse(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        verify(mActiveCall, timeout(SEQUENCING_TIMEOUT_MS)).hold();
        verify(mNewCall).increaseHeldByThisCallCount();
        assertTrue(waitForFutureResult(resultFuture, false));
@@ -352,7 +372,8 @@ public class CallSequencingTests extends TelecomTestCase {

        assertFalse(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        verify(mActiveCall, timeout(SEQUENCING_TIMEOUT_MS)).disconnect(anyString());
        assertTrue(waitForFutureResult(resultFuture, false));
    }
@@ -372,7 +393,8 @@ public class CallSequencingTests extends TelecomTestCase {
        // disconnect the active (carrier) call.
        assertFalse(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        assertFalse(waitForFutureResult(resultFuture, true));
    }

@@ -387,7 +409,8 @@ public class CallSequencingTests extends TelecomTestCase {

        assertTrue(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        assertTrue(waitForFutureResult(resultFuture, true));
    }

@@ -404,7 +427,8 @@ public class CallSequencingTests extends TelecomTestCase {

        assertFalse(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        verify(mNewCall, timeout(SEQUENCING_TIMEOUT_MS)).reject(
                anyBoolean(), anyString(), anyString());
        assertFalse(waitForFutureResult(resultFuture, true));
@@ -423,7 +447,8 @@ public class CallSequencingTests extends TelecomTestCase {

        assertFalse(mController.arePhoneAccountsSame(mNewCall, mActiveCall));
        CompletableFuture<Boolean> resultFuture = mController
                .holdActiveCallForNewCallWithSequencing(mNewCall);
                .holdActiveCallForNewCallWithSequencing(mNewCall,
                        CallsManager.REQUEST_ORIGIN_UNKNOWN);
        assertFalse(waitForFutureResult(resultFuture, true));
    }