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

Commit 9250e5fa authored by Yorke Lee's avatar Yorke Lee
Browse files

Add ability to add sim-initiated MO call to UI (3/4)

Pipe an unknown call through CallsManager via various new APIs like
onSuccessfulUnknownCall, onFailedUnknownCall, etc. These are the unknown call's
equivalent of onSuccessfulOutgoingCall and onFailedOutgoingCall.

Only the TelephonyConnectionService is allowed to call this hidden new API
in Telecom.

Also add the ability for TestConnectionService to test this API (although the
check for TelephonyConnectionService must be disabled at build time first).

Bug: 16852844
Change-Id: I5dfdfc1bd4675f6b300a4a55a3098582f9d715a2
parent 72d271c4
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ final class Call implements CreateConnectionResponse {
        void onFailedOutgoingCall(Call call, DisconnectCause disconnectCause);
        void onSuccessfulIncomingCall(Call call);
        void onFailedIncomingCall(Call call);
        void onSuccessfulUnknownCall(Call call, int callState);
        void onFailedUnknownCall(Call call);
        void onRingbackRequested(Call call, boolean ringbackRequested);
        void onPostDialWait(Call call, String remaining);
        void onCallCapabilitiesChanged(Call call);
@@ -99,6 +101,10 @@ final class Call implements CreateConnectionResponse {
        @Override
        public void onFailedIncomingCall(Call call) {}
        @Override
        public void onSuccessfulUnknownCall(Call call, int callState) {}
        @Override
        public void onFailedUnknownCall(Call call) {}
        @Override
        public void onRingbackRequested(Call call, boolean ringbackRequested) {}
        @Override
        public void onPostDialWait(Call call, String remaining) {}
@@ -167,6 +173,11 @@ final class Call implements CreateConnectionResponse {
    /** True if this is an incoming call. */
    private final boolean mIsIncoming;

    /** True if this is a currently unknown call that was not previously tracked by CallsManager,
     *  and did not originate via the regular incoming/outgoing call code paths.
     */
    private boolean mIsUnknown;

    /**
     * The time this call was created. Beyond logging and such, may also be used for bookkeeping
     * and specifically for marking certain call attempts as failed attempts.
@@ -660,7 +671,11 @@ final class Call implements CreateConnectionResponse {
            mConferenceableCalls.add(idMapper.getCall(id));
        }

        if (mIsIncoming) {
        if (mIsUnknown) {
            for (Listener l : mListeners) {
                l.onSuccessfulUnknownCall(this, getStateFromConnectionState(connection.getState()));
            }
        } else if (mIsIncoming) {
            // We do not handle incoming calls immediately when they are verified by the connection
            // service. We allow the caller-info-query code to execute first so that we can read the
            // direct-to-voicemail property before deciding if we want to show the incoming call to
@@ -686,7 +701,11 @@ final class Call implements CreateConnectionResponse {
        setDisconnectCause(disconnectCause);
        CallsManager.getInstance().markCallAsDisconnected(this, disconnectCause);

        if (mIsIncoming) {
        if (mIsUnknown) {
            for (Listener listener : mListeners) {
                listener.onFailedUnknownCall(this);
            }
        } else if (mIsIncoming) {
            for (Listener listener : mListeners) {
                listener.onFailedIncomingCall(this);
            }
@@ -1255,6 +1274,14 @@ final class Call implements CreateConnectionResponse {
        }
    }

    public boolean isUnknown() {
        return mIsUnknown;
    }

    public void setIsUnknown(boolean isUnknown) {
        mIsUnknown = isUnknown;
    }

    static int getStateFromConnectionState(int state) {
        switch (state) {
            case Connection.STATE_INITIALIZING:
+23 −2
Original line number Diff line number Diff line
@@ -21,16 +21,21 @@ import android.telephony.PhoneNumberUtils;
public class CallReceiver extends BroadcastReceiver {
    private static final String TAG = CallReceiver.class.getName();

    static final String KEY_IS_UNKNOWN_CALL = "is_unknown_call";
    static final String KEY_IS_INCOMING_CALL = "is_incoming_call";
    static final String KEY_IS_DEFAULT_DIALER =
            "is_default_dialer";

    @Override
    public void onReceive(Context context, Intent intent) {
        final boolean isUnknownCall = intent.getBooleanExtra(KEY_IS_UNKNOWN_CALL, false);
        final boolean isIncomingCall = intent.getBooleanExtra(KEY_IS_INCOMING_CALL, false);
        Log.i(TAG, "onReceive - isIncomingCall: %s", isIncomingCall);
        Log.i(this, "onReceive - isIncomingCall: %s isUnknownCall: %s", isIncomingCall,
                isUnknownCall);

        if (isIncomingCall) {
        if (isUnknownCall) {
            processUnknownCallIntent(intent);
        } else if (isIncomingCall) {
            processIncomingCallIntent(intent);
        } else {
            processOutgoingCallIntent(context, intent);
@@ -111,6 +116,22 @@ public class CallReceiver extends BroadcastReceiver {
        getCallsManager().processIncomingCallIntent(phoneAccountHandle, clientExtras);
    }

    private void processUnknownCallIntent(Intent intent) {
        PhoneAccountHandle phoneAccountHandle = intent.getParcelableExtra(
                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE);

        if (phoneAccountHandle == null) {
            Log.w(this, "Rejecting unknown call due to null phone account");
            return;
        }
        if (phoneAccountHandle.getComponentName() == null) {
            Log.w(this, "Rejecting unknown call due to null component name");
            return;
        }

        getCallsManager().addNewUnknownCall(phoneAccountHandle, intent.getExtras());
    }

    static CallsManager getCallsManager() {
        return CallsManager.getInstance();
    }
+36 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;

import com.android.internal.util.IndentingPrintWriter;

import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;

@@ -225,6 +226,20 @@ public final class CallsManager extends Call.ListenerBase {
        call.removeListener(this);
    }

    @Override
    public void onSuccessfulUnknownCall(Call call, int callState) {
        setCallState(call, callState);
        Log.i(this, "onSuccessfulUnknownCall for call %s", call);
        addCall(call);
    }

    @Override
    public void onFailedUnknownCall(Call call) {
        Log.i(this, "onFailedUnknownCall for call %s", call);
        setCallState(call, CallState.DISCONNECTED);
        call.removeListener(this);
    }

    @Override
    public void onRingbackRequested(Call call, boolean ringback) {
        for (CallsManagerListener listener : mListeners) {
@@ -336,6 +351,27 @@ public final class CallsManager extends Call.ListenerBase {
        call.startCreateConnection(mPhoneAccountRegistrar);
    }

    void addNewUnknownCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
        Uri handle = extras.getParcelable(TelecomManager.EXTRA_UNKNOWN_CALL_HANDLE);
        Log.i(this, "addNewUnknownCall with handle: %s", Log.pii(handle));
        Call call = new Call(
                mContext,
                mConnectionServiceRepository,
                handle,
                null /* gatewayInfo */,
                null /* connectionManagerPhoneAccount */,
                phoneAccountHandle,
                // Use onCreateIncomingConnection in TelephonyConnectionService, so that we attach
                // to the existing connection instead of trying to create a new one.
                true /* isIncoming */,
                false /* isConference */);
        call.setConnectTimeMillis(System.currentTimeMillis());
        call.setIsUnknown(true);
        call.setExtras(extras);
        call.addListener(this);
        call.startCreateConnection(mPhoneAccountRegistrar);
    }

    /**
     * Kicks off the first steps to creating an outgoing call so that InCallUI can launch.
     *
+2 −1
Original line number Diff line number Diff line
@@ -643,7 +643,8 @@ final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
                                    call.getHandle(),
                                    extras,
                                    call.getVideoState()),
                            call.isIncoming());
                            call.isIncoming(),
                            call.isUnknown());
                } catch (RemoteException e) {
                    Log.e(this, e, "Failure to createConnection -- %s", getComponentName());
                    mPendingResponses.remove(callId).handleCreateConnectionFailure(
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ import java.util.List;
import java.util.Objects;

/**
 * This class creates connections to place new outgoing calls to attached to an existing incoming
 * This class creates connections to place new outgoing calls or to attach to an existing incoming
 * call. In either case, this class cycles through a set of connection services until:
 *   - a connection service returns a newly created connection in which case the call is displayed
 *     to the user
Loading