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

Commit c95c0b4c authored by Hall Liu's avatar Hall Liu
Browse files

Don't start a call until after it's been evaluated

Telecom grants the system dialer location permissions if a 3pty dialer attempts
to make an emergency call. However, if a 3pty dialer tries to make an emergency
call, we launch the system dialer's dial activity and terminate the call that
was already started. After termination, we'll revoke the location permission,
thereby killing the system dialer that we just launched.

To fix this, reorder things in CallIntentProcessor so that
evaluateCall() in NewOutgoingCallIntentBroadcaster gets called before we
kick things off in CallsManager, and so that we can quit before we start
binding/setting up stuff related to the call.

Fixes: 152348036
Test: manual, existing unit tests
Change-Id: I0851b730e3d415fbf995a47cf8df60df27add85c
parent 0cd4c9b4
Loading
Loading
Loading
Loading
+13 −26
Original line number Diff line number Diff line
@@ -165,6 +165,17 @@ public class CallIntentProcessor {
        boolean isPrivilegedDialer = defaultDialerCache.isDefaultOrSystemDialer(callingPackage,
                initiatingUser.getIdentifier());

        NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster(
                context, callsManager, intent, callsManager.getPhoneNumberUtilsAdapter(),
                isPrivilegedDialer, defaultDialerCache);

        // If the broadcaster comes back with an immediate error, disconnect and show a dialog.
        NewOutgoingCallIntentBroadcaster.CallDisposition disposition = broadcaster.evaluateCall();
        if (disposition.disconnectCause != DisconnectCause.NOT_DISCONNECTED) {
            showErrorDialog(context, disposition.disconnectCause);
            return;
        }

        // Send to CallsManager to ensure the InCallUI gets kicked off before the broadcast returns
        CompletableFuture<Call> callFuture = callsManager
                .startOutgoingCall(handle, phoneAccountHandle, clientExtras, initiatingUser,
@@ -175,8 +186,7 @@ public class CallIntentProcessor {
            if (call != null) {
                Log.continueSession(logSubsession, "CIP.sNOCI");
                try {
                    sendNewOutgoingCallIntent(context, call, callsManager, intent,
                            isPrivilegedDialer, defaultDialerCache);
                    broadcaster.processCall(call, disposition);
                } finally {
                    Log.endSession();
                }
@@ -184,27 +194,6 @@ public class CallIntentProcessor {
        });
    }

    static void sendNewOutgoingCallIntent(Context context, Call call, CallsManager callsManager,
            Intent intent, boolean isPrivilegedDialer, DefaultDialerCache defaultDialerCache) {
        // Asynchronous calls should not usually be made inside a BroadcastReceiver because once
        // onReceive is complete, the BroadcastReceiver's process runs the risk of getting
        // killed if memory is scarce. However, this is OK here because the entire Telecom
        // process will be running throughout the duration of the phone call and should never
        // be killed.
        NewOutgoingCallIntentBroadcaster broadcaster = new NewOutgoingCallIntentBroadcaster(
                context, callsManager, call, intent, callsManager.getPhoneNumberUtilsAdapter(),
                isPrivilegedDialer, defaultDialerCache);

        // If the broadcaster comes back with an immediate error, disconnect and show a dialog.
        NewOutgoingCallIntentBroadcaster.CallDisposition disposition = broadcaster.evaluateCall();
        if (disposition.disconnectCause != DisconnectCause.NOT_DISCONNECTED) {
            disconnectCallAndShowErrorDialog(context, call, disposition.disconnectCause);
            return;
        }

        broadcaster.processCall(disposition);
    }

    /**
     * If the call is initiated from managed profile but there is no work dialer installed, treat
     * the call is initiated from its parent user.
@@ -276,9 +265,7 @@ public class CallIntentProcessor {
        callsManager.addNewUnknownCall(phoneAccountHandle, intent.getExtras());
    }

    private static void disconnectCallAndShowErrorDialog(
            Context context, Call call, int errorCode) {
        call.disconnect();
    private static void showErrorDialog(Context context, int errorCode) {
        final Intent errorIntent = new Intent(context, ErrorDialogActivity.class);
        int errorMessageId = -1;
        switch (errorCode) {
+4 −4
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public class NewOutgoingCallIntentBroadcaster {
    public static final String EXTRA_GATEWAY_URI = "com.android.phone.extra.GATEWAY_URI";

    private final CallsManager mCallsManager;
    private final Call mCall;
    private Call mCall;
    private final Intent mIntent;
    private final Context mContext;
    private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter;
@@ -99,12 +99,11 @@ public class NewOutgoingCallIntentBroadcaster {
    }

    @VisibleForTesting
    public NewOutgoingCallIntentBroadcaster(Context context, CallsManager callsManager, Call call,
    public NewOutgoingCallIntentBroadcaster(Context context, CallsManager callsManager,
            Intent intent, PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
            boolean isDefaultPhoneApp, DefaultDialerCache defaultDialerCache) {
        mContext = context;
        mCallsManager = callsManager;
        mCall = call;
        mIntent = intent;
        mPhoneNumberUtilsAdapter = phoneNumberUtilsAdapter;
        mIsDefaultOrSystemPhoneApp = isDefaultPhoneApp;
@@ -330,7 +329,8 @@ public class NewOutgoingCallIntentBroadcaster {
        return number;
    }

    public void processCall(CallDisposition disposition) {
    public void processCall(Call call, CallDisposition disposition) {
        mCall = call;
        if (disposition.callImmediately) {
            boolean speakerphoneOn = mIntent.getBooleanExtra(
                    TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false);
+2 −2
Original line number Diff line number Diff line
@@ -474,11 +474,11 @@ public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
    private NewOutgoingCallIntentBroadcaster.CallDisposition processIntent(Intent intent,
            boolean isDefaultPhoneApp) {
        NewOutgoingCallIntentBroadcaster b = new NewOutgoingCallIntentBroadcaster(
                mContext, mCallsManager, mCall, intent, mPhoneNumberUtilsAdapter,
                mContext, mCallsManager, intent, mPhoneNumberUtilsAdapter,
                isDefaultPhoneApp, mDefaultDialerCache);
        NewOutgoingCallIntentBroadcaster.CallDisposition cd = b.evaluateCall();
        if (cd.disconnectCause == DisconnectCause.NOT_DISCONNECTED) {
            b.processCall(cd);
            b.processCall(mCall, cd);
        }
        return cd;
    }