From d34698def53665d99498e8adc609df24653e0f8f Mon Sep 17 00:00:00 2001 From: Pooja Jain Date: Thu, 28 Dec 2017 14:15:31 +0530 Subject: [PATCH] IMS: Add support in frameworks for call deflection feature Call deflection feature is useful to deflect MT call to another number. Test: Manual Bug: 62170348 Change-Id: Idfbcc175a856aa0bb9476f8c73d7a614a3af0700 --- api/current.txt | 4 +++ api/system-current.txt | 1 + telecomm/java/android/telecom/Call.java | 17 +++++++++- telecomm/java/android/telecom/Connection.java | 14 +++++++- .../android/telecom/ConnectionService.java | 32 +++++++++++++++++++ .../java/android/telecom/InCallAdapter.java | 14 ++++++++ .../internal/telecom/IConnectionService.aidl | 3 ++ .../internal/telecom/IInCallAdapter.aidl | 3 ++ .../telephony/CarrierConfigManager.java | 7 ++++ .../android/telephony/ims/ImsCallSession.java | 16 ++++++++++ .../compat/stub/ImsCallSessionImplBase.java | 9 ++++++ .../ims/stub/ImsCallSessionImplBase.java | 13 ++++++++ .../android/ims/internal/IImsCallSession.aidl | 7 ++++ 13 files changed, 138 insertions(+), 2 deletions(-) diff --git a/api/current.txt b/api/current.txt index 14f44ecf7e83d..2c950638e8a63 100644 --- a/api/current.txt +++ b/api/current.txt @@ -39129,6 +39129,7 @@ package android.telecom { public final class Call { method public void answer(int); method public void conference(android.telecom.Call); + method public void deflect(android.net.Uri); method public void disconnect(); method public java.util.List getCannedTextResponses(); method public java.util.List getChildren(); @@ -39239,6 +39240,7 @@ package android.telecom { field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL = 3072; // 0xc00 field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 1024; // 0x400 field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800 + field public static final int CAPABILITY_SUPPORT_DEFLECT = 16777216; // 0x1000000 field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2 field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8 field public static final int PROPERTY_CONFERENCE = 1; // 0x1 @@ -39384,6 +39386,7 @@ package android.telecom { method public void onAnswer(); method public void onCallAudioStateChanged(android.telecom.CallAudioState); method public void onCallEvent(java.lang.String, android.os.Bundle); + method public void onDeflect(android.net.Uri); method public void onDisconnect(); method public void onExtrasChanged(android.os.Bundle); method public void onHandoverComplete(); @@ -39446,6 +39449,7 @@ package android.telecom { field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL = 3072; // 0xc00 field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_RX = 1024; // 0x400 field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800 + field public static final int CAPABILITY_SUPPORT_DEFLECT = 33554432; // 0x2000000 field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2 field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8 field public static final java.lang.String EVENT_CALL_MERGE_FAILED = "android.telecom.event.CALL_MERGE_FAILED"; diff --git a/api/system-current.txt b/api/system-current.txt index d8a84a94e7025..bd00ecafe8551 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4863,6 +4863,7 @@ package android.telephony.ims.stub { ctor public ImsCallSessionImplBase(); method public void accept(int, android.telephony.ims.ImsStreamMediaProfile); method public void close(); + method public void deflect(java.lang.String); method public void extendToConference(java.lang.String[]); method public java.lang.String getCallId(); method public android.telephony.ims.ImsCallProfile getCallProfile(); diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 8a4b046516ece..2341f03d2ec54 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -352,8 +352,11 @@ public final class Call { */ public static final int CAPABILITY_CAN_PULL_CALL = 0x00800000; + /** Call supports the deflect feature. */ + public static final int CAPABILITY_SUPPORT_DEFLECT = 0x01000000; + //****************************************************************************************** - // Next CAPABILITY value: 0x01000000 + // Next CAPABILITY value: 0x02000000 //****************************************************************************************** /** @@ -529,6 +532,9 @@ public final class Call { if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) { builder.append(" CAPABILITY_CAN_PULL_CALL"); } + if (can(capabilities, CAPABILITY_SUPPORT_DEFLECT)) { + builder.append(" CAPABILITY_SUPPORT_DEFLECT"); + } builder.append("]"); return builder.toString(); } @@ -1235,6 +1241,15 @@ public final class Call { mInCallAdapter.answerCall(mTelecomCallId, videoState); } + /** + * Instructs this {@link #STATE_RINGING} {@code Call} to deflect. + * + * @param address The address to which the call will be deflected. + */ + public void deflect(Uri address) { + mInCallAdapter.deflectCall(mTelecomCallId, address); + } + /** * Instructs this {@link #STATE_RINGING} {@code Call} to reject. * diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 8150efa725712..c0f6dfe90a571 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -328,8 +328,11 @@ public abstract class Connection extends Conferenceable { */ public static final int CAPABILITY_CAN_PULL_CALL = 0x01000000; + /** Call supports the deflect feature. */ + public static final int CAPABILITY_SUPPORT_DEFLECT = 0x02000000; + //********************************************************************************************** - // Next CAPABILITY value: 0x02000000 + // Next CAPABILITY value: 0x04000000 //********************************************************************************************** /** @@ -729,6 +732,9 @@ public abstract class Connection extends Conferenceable { if (can(capabilities, CAPABILITY_CAN_PULL_CALL)) { builder.append(isLong ? " CAPABILITY_CAN_PULL_CALL" : " pull"); } + if (can(capabilities, CAPABILITY_SUPPORT_DEFLECT)) { + builder.append(isLong ? " CAPABILITY_SUPPORT_DEFLECT" : " sup_def"); + } builder.append("]"); return builder.toString(); @@ -2744,6 +2750,12 @@ public abstract class Connection extends Conferenceable { onAnswer(VideoProfile.STATE_AUDIO_ONLY); } + /** + * Notifies this Connection, which is in {@link #STATE_RINGING}, of + * a request to deflect. + */ + public void onDeflect(Uri address) {} + /** * Notifies this Connection, which is in {@link #STATE_RINGING}, of * a request to reject. diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index 990b0b4eefee8..2ea7e65eeec7e 100644 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -124,6 +124,7 @@ public abstract class ConnectionService extends Service { private static final String SESSION_ABORT = "CS.ab"; private static final String SESSION_ANSWER = "CS.an"; private static final String SESSION_ANSWER_VIDEO = "CS.anV"; + private static final String SESSION_DEFLECT = "CS.def"; private static final String SESSION_REJECT = "CS.r"; private static final String SESSION_REJECT_MESSAGE = "CS.rWM"; private static final String SESSION_SILENCE = "CS.s"; @@ -181,6 +182,7 @@ public abstract class ConnectionService extends Service { private static final int MSG_CONNECTION_SERVICE_FOCUS_GAINED = 31; private static final int MSG_HANDOVER_FAILED = 32; private static final int MSG_HANDOVER_COMPLETE = 33; + private static final int MSG_DEFLECT = 34; private static Connection sNullConnection; @@ -352,6 +354,20 @@ public abstract class ConnectionService extends Service { } } + @Override + public void deflect(String callId, Uri address, Session.Info sessionInfo) { + Log.startSession(sessionInfo, SESSION_DEFLECT); + try { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = callId; + args.arg2 = address; + args.arg3 = Log.createSubsession(); + mHandler.obtainMessage(MSG_DEFLECT, args).sendToTarget(); + } finally { + Log.endSession(); + } + } + @Override public void reject(String callId, Session.Info sessionInfo) { Log.startSession(sessionInfo, SESSION_REJECT); @@ -847,6 +863,17 @@ public abstract class ConnectionService extends Service { } break; } + case MSG_DEFLECT: { + SomeArgs args = (SomeArgs) msg.obj; + Log.continueSession((Session) args.arg3, SESSION_HANDLER + SESSION_DEFLECT); + try { + deflect((String) args.arg1, (Uri) args.arg2); + } finally { + args.recycle(); + Log.endSession(); + } + break; + } case MSG_REJECT: { SomeArgs args = (SomeArgs) msg.obj; Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_REJECT); @@ -1605,6 +1632,11 @@ public abstract class ConnectionService extends Service { findConnectionForAction(callId, "answer").onAnswer(); } + private void deflect(String callId, Uri address) { + Log.d(this, "deflect %s", callId); + findConnectionForAction(callId, "deflect").onDeflect(address); + } + private void reject(String callId) { Log.d(this, "reject %s", callId); findConnectionForAction(callId, "reject").onReject(); diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java index 658685fe29074..8678e33f68b6b 100644 --- a/telecomm/java/android/telecom/InCallAdapter.java +++ b/telecomm/java/android/telecom/InCallAdapter.java @@ -16,6 +16,7 @@ package android.telecom; +import android.net.Uri; import android.bluetooth.BluetoothDevice; import android.os.Bundle; import android.os.RemoteException; @@ -60,6 +61,19 @@ public final class InCallAdapter { } } + /** + * Instructs Telecom to deflect the specified call. + * + * @param callId The identifier of the call to deflect. + * @param address The address to deflect. + */ + public void deflectCall(String callId, Uri address) { + try { + mAdapter.deflectCall(callId, address); + } catch (RemoteException e) { + } + } + /** * Instructs Telecom to reject the specified call. * diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl index 3dbc8ddc340ff..04f057d96ef2d 100644 --- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl +++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl @@ -16,6 +16,7 @@ package com.android.internal.telecom; +import android.net.Uri; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.telecom.CallAudioState; @@ -58,6 +59,8 @@ oneway interface IConnectionService { void answer(String callId, in Session.Info sessionInfo); + void deflect(String callId, in Uri address, in Session.Info sessionInfo); + void reject(String callId, in Session.Info sessionInfo); void rejectWithMessage(String callId, String message, 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 87ccd3ed43694..57df5c1e548e5 100644 --- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl @@ -16,6 +16,7 @@ package com.android.internal.telecom; +import android.net.Uri; import android.os.Bundle; import android.telecom.PhoneAccountHandle; @@ -29,6 +30,8 @@ import android.telecom.PhoneAccountHandle; oneway interface IInCallAdapter { void answerCall(String callId, int videoState); + void deflectCall(String callId, in Uri address); + void rejectCall(String callId, boolean rejectWithMessage, String textMessage); void disconnectCall(String callId); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 046b8be90a778..f360680913c45 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1370,6 +1370,12 @@ public class CarrierConfigManager { */ public static final String KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL = "allow_hold_in_ims_call"; + /** + * Flag indicating whether the carrier supports call deflection for an incoming IMS call. + * @hide + */ + public static final String KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL = + "carrier_allow_deflect_ims_call_bool"; /** * Flag indicating whether the carrier always wants to play an "on-hold" tone when a call has @@ -1822,6 +1828,7 @@ public class CarrierConfigManager { static { sDefaults = new PersistableBundle(); sDefaults.putBoolean(KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL, true); + sDefaults.putBoolean(KEY_CARRIER_ALLOW_DEFLECT_IMS_CALL_BOOL, false); sDefaults.putBoolean(KEY_ALWAYS_PLAY_REMOTE_HOLD_TONE_BOOL, false); sDefaults.putBoolean(KEY_ADDITIONAL_CALL_SETTING_BOOL, true); sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL, false); diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java index 207965d5a2f6e..da322114d9932 100644 --- a/telephony/java/android/telephony/ims/ImsCallSession.java +++ b/telephony/java/android/telephony/ims/ImsCallSession.java @@ -752,6 +752,22 @@ public class ImsCallSession { } } + /** + * Deflects an incoming call. + * + * @param number number to be deflected to + */ + public void deflect(String number) { + if (mClosed) { + return; + } + + try { + miSession.deflect(number); + } catch (RemoteException e) { + } + } + /** * Rejects an incoming call or session update. * diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java index 00cb1e25f66d5..e5ed825728730 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java @@ -181,6 +181,15 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { public void accept(int callType, ImsStreamMediaProfile profile) { } + /** + * Deflects an incoming call. + * + * @param deflectNumber number to deflect the call + */ + @Override + public void deflect(String deflectNumber) { + } + /** * Rejects an incoming call or session update. * diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java index c6ca6fdb0fd8a..7b9fe2b144ab0 100644 --- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java @@ -173,6 +173,11 @@ public class ImsCallSessionImplBase implements AutoCloseable { ImsCallSessionImplBase.this.accept(callType, profile); } + @Override + public void deflect(String deflectNumber) { + ImsCallSessionImplBase.this.deflect(deflectNumber); + } + @Override public void reject(int reason) { ImsCallSessionImplBase.this.reject(reason); @@ -394,6 +399,14 @@ public class ImsCallSessionImplBase implements AutoCloseable { public void accept(int callType, ImsStreamMediaProfile profile) { } + /** + * Deflects an incoming call. + * + * @param deflectNumber number to deflect the call + */ + public void deflect(String deflectNumber) { + } + /** * Rejects an incoming call or session update. * diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl index 203e6cf9c577a..15234e5c0e92a 100644 --- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl +++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl @@ -135,6 +135,13 @@ interface IImsCallSession { */ void accept(int callType, in ImsStreamMediaProfile profile); + /** + * Deflects an incoming call. + * + * @param deflectNumber number to deflect the call + */ + void deflect(String deflectNumber); + /** * Rejects an incoming call or session update. *