diff options
author | 2020-01-23 13:10:37 -0800 | |
---|---|---|
committer | 2020-01-23 13:10:37 -0800 | |
commit | facfdee12294db3aad7e77b4cf655779f1ab9c32 (patch) | |
tree | 58a0390cbc8b670e4feea24c08d260a8ecfa6fb6 | |
parent | 0ab00030a2ec3ffb848153718360aced093df29c (diff) |
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
-rw-r--r-- | api/current.txt | 4 | ||||
-rw-r--r-- | telecomm/java/android/telecom/Call.java | 33 | ||||
-rw-r--r-- | telecomm/java/android/telecom/Connection.java | 11 | ||||
-rw-r--r-- | telecomm/java/android/telecom/ConnectionService.java | 32 | ||||
-rw-r--r-- | telecomm/java/android/telecom/InCallAdapter.java | 13 | ||||
-rw-r--r-- | telecomm/java/com/android/internal/telecom/IConnectionService.aidl | 2 | ||||
-rw-r--r-- | telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl | 2 | ||||
-rw-r--r-- | telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java | 7 |
8 files changed, 104 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index bba65864ad78..8d78b560dac0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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(); diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index acf51f3856d3..f54f8d1f5832 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -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) @@ -1520,6 +1543,16 @@ public final class Call { } /** + * 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. */ public void disconnect() { diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index c934625f588b..72c66d20548a 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -3037,6 +3037,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. */ diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index 440f044fdcf7..00c2918837ac 100644 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -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; @@ -450,6 +451,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); try { @@ -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(); diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java index 261246818f1d..594c1eb392b3 100644 --- a/telecomm/java/android/telecom/InCallAdapter.java +++ b/telecomm/java/android/telecom/InCallAdapter.java @@ -89,6 +89,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. * * @param callId The identifier of the call to disconnect. diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl index 96f2483f32f9..4249dff151c7 100644 --- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl +++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl @@ -77,6 +77,8 @@ oneway interface IConnectionService { void reject(String callId, in Session.Info sessionInfo); + void rejectWithReason(String callId, int rejectReason, in Session.Info sessionInfo); + void rejectWithMessage(String callId, String message, in Session.Info sessionInfo); void disconnect(String callId, in Session.Info sessionInfo); diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl index 60745e40aa77..eb2d714fe3f4 100644 --- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl @@ -34,6 +34,8 @@ oneway interface IInCallAdapter { void rejectCall(String callId, boolean rejectWithMessage, String textMessage); + void rejectCallWithReason(String callId, int rejectReason); + void disconnectCall(String callId); void holdCall(String callId); diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java index f4367da4a4dc..e8f69ea64a22 100644 --- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java @@ -410,6 +410,13 @@ public class ImsCallSessionImplBase implements AutoCloseable { * Rejects an incoming call or session update. * * @param reason reason code to reject an incoming call, defined in {@link ImsReasonInfo}. + * The {@link android.telecom.InCallService} (dialer app) can use the + * {@link android.telecom.Call#reject(int)} API to reject a call while specifying + * a user-indicated reason for rejecting the call. + * Normal call declines ({@link android.telecom.Call#REJECT_REASON_DECLINED}) will + * map to {@link ImsReasonInfo#CODE_USER_DECLINE}. + * Unwanted calls ({@link android.telecom.Call#REJECT_REASON_UNWANTED}) will map + * to {@link ImsReasonInfo#CODE_SIP_USER_MARKED_UNWANTED}. * {@link ImsCallSession.Listener#callSessionStartFailed} */ public void reject(int reason) { |