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

Commit 8e6825d0 authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Remove is_new_outgoing_call_broadcast_unblocking flag.

This flag was launched in 24Q3.  Removing the flag aconfig and uses in
the code.

Test: Run unit tests.
Flag: NONE this is a flag cleanup task.
Bug: 224550864
Change-Id: Ib06b2f8aa5e8d5addc3b508b2908d90e094d8f24
parent 0d5aa724
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
package: "com.android.server.telecom.flags"
container: "system"

# OWNER=tgunn TARGET=24Q3
flag {
  name: "is_new_outgoing_call_broadcast_unblocking"
  namespace: "telecom"
  description: "When set, the ACTION_NEW_OUTGOING_CALL broadcast is unblocking."
  bug: "224550864"
}
 No newline at end of file
# This file intentionally left blank to avoid compilation errors due to removed flag.
+12 −169
Original line number Diff line number Diff line
@@ -115,88 +115,6 @@ public class NewOutgoingCallIntentBroadcaster {
        mFeatureFlags = featureFlags;
    }

    /**
     * Processes the result of the outgoing call broadcast intent, and performs callbacks to
     * the OutgoingCallIntentBroadcasterListener as necessary.
     */
    public class NewOutgoingCallBroadcastIntentReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                Log.startSession("NOCBIR.oR");
                synchronized (mLock) {
                    Log.v(this, "onReceive: %s", intent);

                    // Once the NEW_OUTGOING_CALL broadcast is finished, the resultData is
                    // used as the actual number to call. (If null, no call will be placed.)
                    String resultNumber = getResultData();
                    Log.i(NewOutgoingCallIntentBroadcaster.this,
                            "Received new-outgoing-call-broadcast for %s with data %s", mCall,
                            Log.pii(resultNumber));

                    boolean endEarly = false;
                    long disconnectTimeout =
                            Timeouts.getNewOutgoingCallCancelMillis(mContext, mFeatureFlags);
                    if (resultNumber == null) {
                        Log.v(this, "Call cancelled (null number), returning...");
                        disconnectTimeout = getDisconnectTimeoutFromApp(
                                getResultExtras(false), disconnectTimeout);
                        endEarly = true;
                    } else if (isEmergencyNumber(resultNumber)) {
                        Log.w(this, "Cannot modify outgoing call to emergency number %s.",
                                resultNumber);
                        disconnectTimeout = 0;
                        endEarly = true;
                    }

                    if (endEarly) {
                        if (mCall != null) {
                            mCall.disconnect(disconnectTimeout);
                        }
                        return;
                    }

                    // If this call is already disconnected then we have nothing more to do.
                    if (mCall.isDisconnected()) {
                        Log.w(this, "Call has already been disconnected," +
                                        " ignore the broadcast Call %s", mCall);
                        return;
                    }

                    // TODO: Remove the assumption that phone numbers are either SIP or TEL.
                    // This does not impact self-managed ConnectionServices as they do not use the
                    // NewOutgoingCallIntentBroadcaster.
                    Uri resultHandleUri = Uri.fromParts(
                            mPhoneNumberUtilsAdapter.isUriNumber(resultNumber) ?
                                    PhoneAccount.SCHEME_SIP : PhoneAccount.SCHEME_TEL,
                            resultNumber, null);

                    Uri originalUri = mIntent.getData();

                    if (originalUri.getSchemeSpecificPart().equals(resultNumber)) {
                        Log.v(this, "Call number unmodified after" +
                                " new outgoing call intent broadcast.");
                    } else {
                        Log.v(this, "Retrieved modified handle after outgoing call intent" +
                                " broadcast: Original: %s, Modified: %s",
                                Log.pii(originalUri),
                                Log.pii(resultHandleUri));
                    }

                    GatewayInfo gatewayInfo = getGateWayInfoFromIntent(intent, resultHandleUri);
                    placeOutgoingCallImmediately(mCall, resultHandleUri, gatewayInfo,
                            mIntent.getBooleanExtra(
                                    TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false),
                            mIntent.getIntExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
                                    VideoProfile.STATE_AUDIO_ONLY));
                }
            } finally {
                Log.endSession();
            }
        }
    }

    /**
     * Processes the supplied intent and starts the outgoing call broadcast process relevant to the
     * intent.
@@ -355,13 +273,6 @@ public class NewOutgoingCallIntentBroadcaster {

    public void processCall(Call call, CallDisposition disposition) {
        mCall = call;

        // If the new outgoing call broadast doesn't block, trigger the legacy process call
        // behavior and exit out here.
        if (!mFeatureFlags.isNewOutgoingCallBroadcastUnblocking()) {
            legacyProcessCall(disposition);
            return;
        }
        boolean callRedirectionWithService = false;
        // Only try to do redirection if it was requested and we're not calling immediately.
        // We can expect callImmediately to be true for emergency calls and voip calls.
@@ -398,50 +309,6 @@ public class NewOutgoingCallIntentBroadcaster {
        }
    }

    /**
     * The legacy non-flagged version of processing a call.  Although there is some code duplication
     * if makes the new flow cleaner to read.
     * @param disposition
     */
    private void legacyProcessCall(CallDisposition disposition) {
        if (disposition.callImmediately) {
            callImmediately(disposition);

            // Don't return but instead continue and send the ACTION_NEW_OUTGOING_CALL broadcast
            // so that third parties can still inspect (but not intercept) the outgoing call. When
            // the broadcast finally reaches the OutgoingCallBroadcastReceiver, we'll know not to
            // initiate the call again because of the presence of the EXTRA_ALREADY_CALLED extra.
        }

        boolean callRedirectionWithService = false;
        if (disposition.requestRedirection) {
            CallRedirectionProcessor callRedirectionProcessor = new CallRedirectionProcessor(
                    mContext, mCallsManager, mCall, disposition.callingAddress,
                    mCallsManager.getPhoneAccountRegistrar(),
                    getGateWayInfoFromIntent(mIntent, mIntent.getData()),
                    mIntent.getBooleanExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE,
                            false),
                    mIntent.getIntExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
                            VideoProfile.STATE_AUDIO_ONLY), mFeatureFlags);
            /**
             * If there is an available {@link android.telecom.CallRedirectionService}, use the
             * {@link CallRedirectionProcessor} to perform call redirection instead of using
             * broadcasting.
             */
            callRedirectionWithService = callRedirectionProcessor
                    .canMakeCallRedirectionWithServiceAsUser(mCall.getAssociatedUser());
            if (callRedirectionWithService) {
                callRedirectionProcessor.performCallRedirection(mCall.getAssociatedUser());
            }
        }

        if (disposition.sendBroadcast) {
            UserHandle targetUser = mCall.getAssociatedUser();
            broadcastIntent(mIntent, disposition.number,
                    !disposition.callImmediately && !callRedirectionWithService, targetUser);
        }
    }

    /**
     * Place a call immediately.
     * @param disposition The disposition; used for retrieving the address of the call.
@@ -479,8 +346,7 @@ public class NewOutgoingCallIntentBroadcaster {

        checkAndCopyProviderExtras(originalCallIntent, broadcastIntent);

        if (mFeatureFlags.isNewOutgoingCallBroadcastUnblocking()) {
            // Where the new outgoing call broadcast is unblocking, do not give receiver FG priority
        // The new outgoing call broadcast is unblocking, do not give receiver FG priority
        // and do not allow background activity starts.
        broadcastIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        Log.i(this, "broadcastIntent: Sending non-blocking for %s to %s", mCall.getId(),
@@ -497,29 +363,6 @@ public class NewOutgoingCallIntentBroadcaster {
                    android.Manifest.permission.PROCESS_OUTGOING_CALLS,
                    AppOpsManager.OP_PROCESS_OUTGOING_CALLS);  // initialExtras
        }
        } else {
            Log.i(this, "broadcastIntent: Sending ordered for %s to %s, waitForResult=%b",
                    mCall.getId(), targetUser, receiverRequired);
            final BroadcastOptions options = BroadcastOptions.makeBasic();
            options.setBackgroundActivityStartsAllowed(true);
            // Force receivers of this broadcast intent to run at foreground priority because we
            // want to finish processing the broadcast intent as soon as possible.
            broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);

            mContext.sendOrderedBroadcastAsUser(
                    broadcastIntent,
                    targetUser,
                    android.Manifest.permission.PROCESS_OUTGOING_CALLS,
                    AppOpsManager.OP_PROCESS_OUTGOING_CALLS,
                    options.toBundle(),
                    receiverRequired ? new NewOutgoingCallBroadcastIntentReceiver() : null,
                    null,  // scheduler
                    Activity.RESULT_OK,  // initialCode
                    number,  // initialData: initial value for the result data (number to be
                             // modified)
                    null);  // initialExtras
        }
    }

    /**
+18 −208
Original line number Diff line number Diff line
@@ -78,16 +78,6 @@ import org.mockito.Mock;
public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
    private static final Uri TEST_URI = Uri.parse("tel:16505551212");

    private static class ReceiverIntentPair {
        public BroadcastReceiver receiver;
        public Intent intent;

        public ReceiverIntentPair(BroadcastReceiver receiver, Intent intent) {
            this.receiver = receiver;
            this.intent = intent;
        }
    }

    @Mock private CallsManager mCallsManager;
    @Mock private Call mCall;
    @Mock private SystemStateHelper mSystemStateHelper;
@@ -117,7 +107,6 @@ public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
            any(PhoneAccountHandle.class))).thenReturn(mPhoneAccount);
        when(mPhoneAccount.isSelfManaged()).thenReturn(true);
        when(mSystemStateHelper.isCarModeOrProjectionActive()).thenReturn(false);
        when(mFeatureFlags.isNewOutgoingCallBroadcastUnblocking()).thenReturn(false);
    }

    @Override
@@ -193,21 +182,6 @@ public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
        verifyNoCallPlaced();
    }

    @SmallTest
    @Test
    public void testAlreadyDisconnectedCall() {
        Uri handle = Uri.parse("tel:6505551234");
        doReturn(true).when(mCall).isDisconnected();
        Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null);
        ReceiverIntentPair result = regularCallTestHelper(callIntent, null);

        result.receiver.setResultData(
                result.intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));

        result.receiver.onReceive(mContext, result.intent);
        verifyNoCallPlaced();
    }

    @SmallTest
    @Test
    public void testNoNumberSupplied() {
@@ -392,170 +366,15 @@ public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
        if (expectedAdditionalExtras != null) {
            expectedExtras.putAll(expectedAdditionalExtras);
        }
        BroadcastReceiver receiver = verifyBroadcastSent(handle.getSchemeSpecificPart(),
                expectedExtras).receiver;
        assertNull(receiver);
    }

    @SmallTest
    @Test
    public void testUnmodifiedRegularCall() {
        Uri handle = Uri.parse("tel:6505551234");
        Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null);
        ReceiverIntentPair result = regularCallTestHelper(callIntent, null);

        result.receiver.setResultData(
                result.intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));

        result.receiver.onReceive(mContext, result.intent);

        verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(handle), isNull(),
                eq(true), eq(VideoProfile.STATE_BIDIRECTIONAL));
    }

    @SmallTest
    @Test
    public void testUnmodifiedSipCall() {
        Uri handle = Uri.parse("sip:test@test.com");
        Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null);
        ReceiverIntentPair result = regularCallTestHelper(callIntent, null);

        result.receiver.setResultData(
                result.intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));

        result.receiver.onReceive(mContext, result.intent);

        Uri encHandle = Uri.fromParts(handle.getScheme(),
                handle.getSchemeSpecificPart(), null);
        verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(encHandle), isNull(),
                eq(true), eq(VideoProfile.STATE_BIDIRECTIONAL));
    }

    @SmallTest
    @Test
    public void testCallWithGatewayInfo() {
        Uri handle = Uri.parse("tel:6505551234");
        Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null);

        callIntent.putExtra(NewOutgoingCallIntentBroadcaster
                        .EXTRA_GATEWAY_PROVIDER_PACKAGE, "sample1");
        callIntent.putExtra(NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_URI, "sample2");
        ReceiverIntentPair result = regularCallTestHelper(callIntent, callIntent.getExtras());

        result.receiver.setResultData(
                result.intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));

        result.receiver.onReceive(mContext, result.intent);

        verify(mCallsManager).placeOutgoingCall(eq(mCall), eq(handle),
                isNotNull(), eq(true), eq(VideoProfile.STATE_BIDIRECTIONAL));
    }

    @SmallTest
    @Test
    public void testCallNumberModifiedToNull() {
        Uri handle = Uri.parse("tel:6505551234");
        Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null);
        ReceiverIntentPair result = regularCallTestHelper(callIntent, null);

        result.receiver.setResultData(null);

        result.receiver.onReceive(mContext, result.intent);
        verifyNoCallPlaced();
        ArgumentCaptor<Long> timeoutCaptor = ArgumentCaptor.forClass(Long.class);
        verify(mCall).disconnect(timeoutCaptor.capture());
        assertTrue(timeoutCaptor.getValue() > 0);
    }

    @SmallTest
    @Test
    public void testCallNumberModifiedToNullWithLongCustomTimeout() {
        Uri handle = Uri.parse("tel:6505551234");
        Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null);
        ReceiverIntentPair result = regularCallTestHelper(callIntent, null);

        long customTimeout = 100000000;
        Bundle bundle = new Bundle();
        bundle.putLong(TelecomManager.EXTRA_NEW_OUTGOING_CALL_CANCEL_TIMEOUT, customTimeout);
        result.receiver.setResultData(null);
        result.receiver.setResultExtras(bundle);

        result.receiver.onReceive(mContext, result.intent);
        verifyNoCallPlaced();
        ArgumentCaptor<Long> timeoutCaptor = ArgumentCaptor.forClass(Long.class);
        verify(mCall).disconnect(timeoutCaptor.capture());
        assertTrue(timeoutCaptor.getValue() < customTimeout);
    }

    @SmallTest
    @Test
    public void testCallModifiedToEmergency() {
        Uri handle = Uri.parse("tel:6505551234");
        Intent callIntent = buildIntent(handle, Intent.ACTION_CALL, null);
        ReceiverIntentPair result = regularCallTestHelper(callIntent, null);

        String newEmergencyNumber = "1234567890";
        result.receiver.setResultData(newEmergencyNumber);

        doReturn(true).when(mComponentContextFixture.getTelephonyManager())
                .isEmergencyNumber(eq(newEmergencyNumber));
        result.receiver.onReceive(mContext, result.intent);
        verify(mCall).disconnect(eq(0L));
    }

    /**
     * Ensure if {@link TelephonyManager#isPotentialEmergencyNumber(String)} throws an exception of
     * any sort that we don't crash Telecom.
     */
    @SmallTest
    @Test
    public void testThrowOnIsPotentialEmergencyNumber() {
        doThrow(new IllegalStateException()).when(mComponentContextFixture.getTelephonyManager())
                .isPotentialEmergencyNumber(anyString());
        testUnmodifiedRegularCall();
    }

    /**
     * Where the flag `isNewOutgoingCallBroadcastUnblocking` is off, verify that we sent an ordered
     * broadcast and did not try to start the call immediately (legacy behavior).
     */
    @SmallTest
    @Test
    public void testSendBroadcastBlocking() {
        when(mFeatureFlags.isNewOutgoingCallBroadcastUnblocking()).thenReturn(false);
        Intent intent = new Intent(Intent.ACTION_CALL, TEST_URI);
        NewOutgoingCallIntentBroadcaster nocib = new NewOutgoingCallIntentBroadcaster(
                mContext, mCallsManager, intent, mPhoneNumberUtilsAdapter,
                true /* isDefaultPhoneApp */, mDefaultDialerCache, mMmiUtils, mFeatureFlags);

        NewOutgoingCallIntentBroadcaster.CallDisposition disposition = nocib.evaluateCall();
        nocib.processCall(mCall, disposition);

        // We should not have not short-circuited to place the outgoing call directly.
        verify(mCall, never()).setNewOutgoingCallIntentBroadcastIsDone();
        verify(mCallsManager, never()).placeOutgoingCall(any(Call.class), any(Uri.class),
                any(GatewayInfo.class), anyBoolean(), anyInt());

        // Ensure we did send the broadcast ordered
        verifyBroadcastSent(TEST_URI.getSchemeSpecificPart(),
                createNumberExtras(TEST_URI.getSchemeSpecificPart()));

        // Ensure we did not try to directly send the broadcast unordered.
        verify(mContext, never()).sendBroadcastAsUser(
                any(Intent.class),
                eq(UserHandle.CURRENT),
                eq(android.Manifest.permission.PROCESS_OUTGOING_CALLS));
        verifyBroadcastSent(handle.getSchemeSpecificPart(), expectedExtras);
    }

    /**
     * Where the flag `isNewOutgoingCallBroadcastUnblocking` is off, verify that we sent an ordered
     * broadcast and did not try to start the call immediately.  Also ensure that the broadcast
     * flags are correct.
     * Verify that the new outgoing call broadcast is not ordered.
     */
    @SmallTest
    @Test
    public void testSendBroadcastNonBlocking() {
        when(mFeatureFlags.isNewOutgoingCallBroadcastUnblocking()).thenReturn(true);
        Intent intent = new Intent(Intent.ACTION_CALL, TEST_URI);
        NewOutgoingCallIntentBroadcaster nocib = new NewOutgoingCallIntentBroadcaster(
                mContext, mCallsManager, intent, mPhoneNumberUtilsAdapter,
@@ -593,7 +412,7 @@ public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
        assertEquals(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, capturedIntent.getFlags());
    }

    private ReceiverIntentPair regularCallTestHelper(Intent intent,
    private void regularCallTestHelper(Intent intent,
            Bundle expectedAdditionalExtras) {
        Uri handle = intent.getData();
        int videoState = VideoProfile.STATE_BIDIRECTIONAL;
@@ -610,7 +429,7 @@ public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
        if (expectedAdditionalExtras != null) {
            expectedExtras.putAll(expectedAdditionalExtras);
        }
        return verifyBroadcastSent(handle.getSchemeSpecificPart(), expectedExtras);
        verifyBroadcastSent(handle.getSchemeSpecificPart(), expectedExtras);
    }

    private Intent buildIntent(Uri handle, String action, Bundle extras) {
@@ -633,36 +452,27 @@ public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
        return cd;
    }

    private ReceiverIntentPair verifyBroadcastSent(String number, Bundle expectedExtras) {
    private void verifyBroadcastSent(String number, Bundle expectedExtras) {
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        ArgumentCaptor<BroadcastReceiver> receiverCaptor =
                ArgumentCaptor.forClass(BroadcastReceiver.class);

        verify(mContext).sendOrderedBroadcastAsUser(
        if (mFeatureFlags.telecomResolveHiddenDependencies()) {
            verify(mContext).sendBroadcastAsUser(
                    intentCaptor.capture(),
                    eq(UserHandle.CURRENT),
                    eq(Manifest.permission.PROCESS_OUTGOING_CALLS));
        } else {
            verify(mContext).sendBroadcastAsUser(
                    intentCaptor.capture(),
                    eq(UserHandle.CURRENT),
                    eq(Manifest.permission.PROCESS_OUTGOING_CALLS),
                eq(AppOpsManager.OP_PROCESS_OUTGOING_CALLS),
                any(Bundle.class),
                receiverCaptor.capture(),
                isNull(),
                eq(Activity.RESULT_OK),
                eq(number),
                isNull());
                    anyInt());
        }

        Intent capturedIntent = intentCaptor.getValue();
        assertEquals(Intent.ACTION_NEW_OUTGOING_CALL, capturedIntent.getAction());
        assertEquals(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
        assertEquals(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
                capturedIntent.getFlags());
        assertTrue(areBundlesEqual(expectedExtras, capturedIntent.getExtras()));

        BroadcastReceiver receiver = receiverCaptor.getValue();
        if (receiver != null) {
            receiver.setPendingResult(
                    new BroadcastReceiver.PendingResult(0, "", null, 0, true, false, null, 0, 0));
        }

        return new ReceiverIntentPair(receiver, capturedIntent);
    }

    private Bundle createNumberExtras(String number) {
+20 −27

File changed.

Preview size limit exceeded, changes collapsed.