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

Commit facfdee1 authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Add support for rejecting Telecom call with a specified reason.

Adding a new Call API which supports passing a user-specified call
rejection reason down to the lower layers for reporting to the network.
Part of the VERSTAT spec involves support for this type of signaling, so
it makes sense to also support it here as well.
There are two potential types of reject reason:
declined - user declined the call because they want it to go to voicemail
or don't want to talk to the caller right now.
unwanted - this is a nuisance call and the user never wanted to receive it.

Bug: 135929421
Test: Added new CTS test to validate API pathways.
Test: Ran existing telecom and telephony unit tests.
Test: Modified test dialer app to use the new reject API and verified that
the reject reason signals down to the modem and translates to the correct
reject cause.

Change-Id: I6f25fafa2b2620e2839e5d3a9fb986f1130fa165
parent 0ab00030
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -43500,6 +43500,7 @@ package android.telecom {
    method public void registerCallback(android.telecom.Call.Callback);
    method public void registerCallback(android.telecom.Call.Callback, android.os.Handler);
    method public void reject(boolean, String);
    method public void reject(int);
    method public void removeExtras(java.util.List<java.lang.String>);
    method public void removeExtras(java.lang.String...);
    method public void respondToRttRequest(int, boolean);
@@ -43515,6 +43516,8 @@ package android.telecom {
    field public static final String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS = "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
    field public static final String EXTRA_SILENT_RINGING_REQUESTED = "android.telecom.extra.SILENT_RINGING_REQUESTED";
    field public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS = "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS";
    field public static final int REJECT_REASON_DECLINED = 1; // 0x1
    field public static final int REJECT_REASON_UNWANTED = 2; // 0x2
    field public static final int STATE_ACTIVE = 4; // 0x4
    field public static final int STATE_AUDIO_PROCESSING = 12; // 0xc
    field public static final int STATE_CONNECTING = 9; // 0x9
@@ -43782,6 +43785,7 @@ package android.telecom {
    method public void onPostDialContinue(boolean);
    method public void onPullExternalCall();
    method public void onReject();
    method public void onReject(int);
    method public void onReject(String);
    method public void onSeparate();
    method public void onShowIncomingCallUi();
+33 −0
Original line number Diff line number Diff line
@@ -265,6 +265,29 @@ public final class Call {
    public static final String EVENT_HANDOVER_FAILED =
            "android.telecom.event.HANDOVER_FAILED";


    /**
     * Reject reason used with {@link #reject(int)} to indicate that the user is rejecting this
     * call because they have declined to answer it.  This typically means that they are unable
     * to answer the call at this time and would prefer it be sent to voicemail.
     */
    public static final int REJECT_REASON_DECLINED = 1;

    /**
     * Reject reason used with {@link #reject(int)} to indicate that the user is rejecting this
     * call because it is an unwanted call.  This allows the user to indicate that they are
     * rejecting a call because it is likely a nuisance call.
     */
    public static final int REJECT_REASON_UNWANTED = 2;

    /**
     * @hide
     */
    @IntDef(prefix = { "REJECT_REASON_" },
            value = {REJECT_REASON_DECLINED, REJECT_REASON_UNWANTED})
    @Retention(RetentionPolicy.SOURCE)
    public @interface RejectReason {};

    public static class Details {
        /** @hide */
        @Retention(RetentionPolicy.SOURCE)
@@ -1519,6 +1542,16 @@ public final class Call {
        mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
    }

    /**
     * Instructs the {@link ConnectionService} providing this {@link #STATE_RINGING} call that the
     * user has chosen to reject the call and has indicated a reason why the call is being rejected.
     *
     * @param rejectReason the reason the call is being rejected.
     */
    public void reject(@RejectReason int rejectReason) {
        mInCallAdapter.rejectCall(mTelecomCallId, rejectReason);
    }

    /**
     * Instructs this {@code Call} to disconnect.
     */
+11 −0
Original line number Diff line number Diff line
@@ -3036,6 +3036,17 @@ public abstract class Connection extends Conferenceable {
     */
    public void onReject() {}

    /**
     * Notifies this Connection, which is in {@link #STATE_RINGING}, of a request to reject.
     * <p>
     * For managed {@link ConnectionService}s, this will be called when the user rejects a call via
     * the default dialer's {@link InCallService} using {@link Call#reject(int)}.
     * @param rejectReason the reason the user provided for rejecting the call.
     */
    public void onReject(@android.telecom.Call.RejectReason int rejectReason) {
        // to be implemented by ConnectionService.
    }

    /**
     * Notifies this Connection, which is in {@link #STATE_RINGING}, of
     * a request to reject with a message.
+32 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ public abstract class ConnectionService extends Service {
    private static final int MSG_CREATE_CONFERENCE = 35;
    private static final int MSG_CREATE_CONFERENCE_COMPLETE = 36;
    private static final int MSG_CREATE_CONFERENCE_FAILED = 37;
    private static final int MSG_REJECT_WITH_REASON = 38;

    private static Connection sNullConnection;

@@ -449,6 +450,21 @@ public abstract class ConnectionService extends Service {
            }
        }

        @Override
        public void rejectWithReason(String callId,
                @android.telecom.Call.RejectReason int rejectReason, Session.Info sessionInfo) {
            Log.startSession(sessionInfo, SESSION_REJECT);
            try {
                SomeArgs args = SomeArgs.obtain();
                args.arg1 = callId;
                args.argi1 = rejectReason;
                args.arg2 = Log.createSubsession();
                mHandler.obtainMessage(MSG_REJECT_WITH_REASON, args).sendToTarget();
            } finally {
                Log.endSession();
            }
        }

        @Override
        public void rejectWithMessage(String callId, String message, Session.Info sessionInfo) {
            Log.startSession(sessionInfo, SESSION_REJECT_MESSAGE);
@@ -1053,6 +1069,17 @@ public abstract class ConnectionService extends Service {
                    }
                    break;
                }
                case MSG_REJECT_WITH_REASON: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT);
                    try {
                        reject((String) args.arg1, args.argi1);
                    } finally {
                        args.recycle();
                        Log.endSession();
                    }
                    break;
                }
                case MSG_REJECT_WITH_MESSAGE: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    Log.continueSession((Session) args.arg3,
@@ -1981,6 +2008,11 @@ public abstract class ConnectionService extends Service {
        findConnectionForAction(callId, "reject").onReject(rejectWithMessage);
    }

    private void reject(String callId, @android.telecom.Call.RejectReason int rejectReason) {
        Log.d(this, "reject %s with reason %d", callId, rejectReason);
        findConnectionForAction(callId, "reject").onReject(rejectReason);
    }

    private void silence(String callId) {
        Log.d(this, "silence %s", callId);
        findConnectionForAction(callId, "silence").onSilence();
+13 −0
Original line number Diff line number Diff line
@@ -88,6 +88,19 @@ public final class InCallAdapter {
        }
    }

    /**
     * Instructs Telecom to reject the specified call.
     *
     * @param callId The identifier of the call to reject.
     * @param rejectReason The reason the call was rejected.
     */
    public void rejectCall(String callId, @Call.RejectReason int rejectReason) {
        try {
            mAdapter.rejectCallWithReason(callId, rejectReason);
        } catch (RemoteException e) {
        }
    }

    /**
     * Instructs Telecom to disconnect the specified call.
     *
Loading