Add further Connection-side APIs for RTT (part 2)
Add methods and callbacks to facilitate local and remote RTT initiation
and termination in the middle of a call. Adds @hide Connection-side APIs
to communicate with the ConnectionService, as well as plumbing for
RemoteConnections.
Test: manual, through telecom testapps
Change-Id: Ia80604b7dff8586ff222dbccdbe55e91aab02178
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 3f7c908..785fbfb 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -871,6 +871,16 @@
* @param id The ID of the request.
*/
public void onRttRequest(Call call, int id) {}
+
+ /**
+ * Invoked when the RTT session failed to initiate for some reason, including rejection
+ * by the remote party.
+ * @param call The call which the RTT initiation failure occurred on.
+ * @param reason One of the status codes defined in
+ * {@link android.telecom.Connection.RttModifyStatus}, with the exception of
+ * {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
+ */
+ public void onRttInitiationFailure(Call call, int reason) {}
}
/**
@@ -913,13 +923,15 @@
private OutputStreamWriter mTransmitStream;
private int mRttMode;
private final InCallAdapter mInCallAdapter;
+ private final String mTelecomCallId;
private char[] mReadBuffer = new char[READ_BUFFER_SIZE];
/**
* @hide
*/
- public RttCall(InputStreamReader receiveStream, OutputStreamWriter transmitStream,
- int mode, InCallAdapter inCallAdapter) {
+ public RttCall(String telecomCallId, InputStreamReader receiveStream,
+ OutputStreamWriter transmitStream, int mode, InCallAdapter inCallAdapter) {
+ mTelecomCallId = telecomCallId;
mReceiveStream = receiveStream;
mTransmitStream = transmitStream;
mRttMode = mode;
@@ -942,7 +954,7 @@
* {@link #RTT_MODE_VCO}, or {@link #RTT_MODE_HCO}.
*/
public void setRttMode(@RttAudioMode int mode) {
- mInCallAdapter.setRttMode(mode);
+ mInCallAdapter.setRttMode(mTelecomCallId, mode);
}
/**
@@ -1213,7 +1225,7 @@
* {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
*/
public void sendRttRequest() {
- mInCallAdapter.sendRttRequest();
+ mInCallAdapter.sendRttRequest(mTelecomCallId);
}
/**
@@ -1224,7 +1236,7 @@
* @param accept {@code true} if the RTT request should be accepted, {@code false} otherwise.
*/
public void respondToRttRequest(int id, boolean accept) {
- mInCallAdapter.respondToRttRequest(id, accept);
+ mInCallAdapter.respondToRttRequest(mTelecomCallId, id, accept);
}
/**
@@ -1232,7 +1244,7 @@
* the {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
*/
public void stopRtt() {
- mInCallAdapter.stopRtt();
+ mInCallAdapter.stopRtt(mTelecomCallId);
}
/**
@@ -1637,7 +1649,7 @@
new ParcelFileDescriptor.AutoCloseOutputStream(
parcelableRttCall.getTransmitStream()),
StandardCharsets.UTF_8);
- RttCall newRttCall = new Call.RttCall(
+ RttCall newRttCall = new Call.RttCall(mTelecomCallId,
receiveStream, transmitStream, parcelableRttCall.getRttMode(), mInCallAdapter);
if (mRttCall == null) {
isRttChanged = true;
@@ -1717,6 +1729,15 @@
}
}
+ /** @hide */
+ final void internalOnRttInitiationFailure(int reason) {
+ for (CallbackRecord<Callback> record : mCallbackRecords) {
+ final Call call = this;
+ final Callback callback = record.getCallback();
+ record.getHandler().post(() -> callback.onRttInitiationFailure(call, reason));
+ }
+ }
+
private void fireStateChanged(final int newState) {
for (CallbackRecord<Callback> record : mCallbackRecords) {
final Call call = this;
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 3e690b9..c2824f4 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -20,6 +20,7 @@
import com.android.internal.telecom.IVideoCallback;
import com.android.internal.telecom.IVideoProvider;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -39,6 +40,8 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -764,6 +767,10 @@
/** @hide */
public void onConferenceSupportedChanged(Connection c, boolean isConferenceSupported) {}
public void onAudioRouteChanged(Connection c, int audioRoute) {}
+ public void onRttInitiationSuccess(Connection c) {}
+ public void onRttInitiationFailure(Connection c, int reason) {}
+ public void onRttSessionRemotelyTerminated(Connection c) {}
+ public void onRemoteRttRequest(Connection c) {}
}
/**
@@ -774,12 +781,16 @@
private static final int READ_BUFFER_SIZE = 1000;
private final InputStreamReader mPipeFromInCall;
private final OutputStreamWriter mPipeToInCall;
+ private final ParcelFileDescriptor mFdFromInCall;
+ private final ParcelFileDescriptor mFdToInCall;
private char[] mReadBuffer = new char[READ_BUFFER_SIZE];
/**
* @hide
*/
public RttTextStream(ParcelFileDescriptor toInCall, ParcelFileDescriptor fromInCall) {
+ mFdFromInCall = fromInCall;
+ mFdToInCall = toInCall;
mPipeFromInCall = new InputStreamReader(
new ParcelFileDescriptor.AutoCloseInputStream(fromInCall));
mPipeToInCall = new OutputStreamWriter(
@@ -823,6 +834,47 @@
return null;
}
}
+
+ /** @hide */
+ public ParcelFileDescriptor getFdFromInCall() {
+ return mFdFromInCall;
+ }
+
+ /** @hide */
+ public ParcelFileDescriptor getFdToInCall() {
+ return mFdToInCall;
+ }
+ }
+
+ /**
+ * Provides constants to represent the results of responses to session modify requests sent via
+ * {@link Call#sendRttRequest()}
+ */
+ public static final class RttModifyStatus {
+ /**
+ * Session modify request was successful.
+ */
+ public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1;
+
+ /**
+ * Session modify request failed.
+ */
+ public static final int SESSION_MODIFY_REQUEST_FAIL = 2;
+
+ /**
+ * Session modify request ignored due to invalid parameters.
+ */
+ public static final int SESSION_MODIFY_REQUEST_INVALID = 3;
+
+ /**
+ * Session modify request timed out.
+ */
+ public static final int SESSION_MODIFY_REQUEST_TIMED_OUT = 4;
+
+ /**
+ * Session modify request rejected by remote user.
+ */
+ public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5;
}
/**
@@ -2426,6 +2478,47 @@
}
/**
+ * Informs listeners that a previously requested RTT session via
+ * {@link ConnectionRequest#isRequestingRtt()} or
+ * {@link #onStartRtt(ParcelFileDescriptor, ParcelFileDescriptor)} has succeeded.
+ * @hide
+ */
+ public final void sendRttInitiationSuccess() {
+ mListeners.forEach((l) -> l.onRttInitiationSuccess(Connection.this));
+ }
+
+ /**
+ * Informs listeners that a previously requested RTT session via
+ * {@link ConnectionRequest#isRequestingRtt()} or
+ * {@link #onStartRtt(ParcelFileDescriptor, ParcelFileDescriptor)}
+ * has failed.
+ * @param reason One of the reason codes defined in {@link RttModifyStatus}, with the
+ * exception of {@link RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
+ * @hide
+ */
+ public final void sendRttInitiationFailure(int reason) {
+ mListeners.forEach((l) -> l.onRttInitiationFailure(Connection.this, reason));
+ }
+
+ /**
+ * Informs listeners that a currently active RTT session has been terminated by the remote
+ * side of the coll.
+ * @hide
+ */
+ public final void sendRttSessionRemotelyTerminated() {
+ mListeners.forEach((l) -> l.onRttSessionRemotelyTerminated(Connection.this));
+ }
+
+ /**
+ * Informs listeners that the remote side of the call has requested an upgrade to include an
+ * RTT session in the call.
+ * @hide
+ */
+ public final void sendRemoteRttRequest() {
+ mListeners.forEach((l) -> l.onRemoteRttRequest(Connection.this));
+ }
+
+ /**
* Notifies this Connection that the {@link #getAudioState()} property has a new value.
*
* @param state The new connection audio state.
@@ -2595,6 +2688,35 @@
*/
public void onShowIncomingCallUi() {}
+ /**
+ * Notifies this {@link Connection} that the user has requested an RTT session.
+ * The connection service should call {@link #sendRttInitiationSuccess} or
+ * {@link #sendRttInitiationFailure} to inform Telecom of the success or failure of the
+ * request, respectively.
+ * @param rttTextStream The object that should be used to send text to or receive text from
+ * the in-call app.
+ * @hide
+ */
+ public void onStartRtt(@NonNull RttTextStream rttTextStream) {}
+
+ /**
+ * Notifies this {@link Connection} that it should terminate any existing RTT communication
+ * channel. No response to Telecom is needed for this method.
+ * @hide
+ */
+ public void onStopRtt() {}
+
+ /**
+ * Notifies this connection of a response to a previous remotely-initiated RTT upgrade
+ * request sent via {@link #sendRemoteRttRequest}. Acceptance of the request is
+ * indicated by the supplied {@link RttTextStream} being non-null, and rejection is
+ * indicated by {@code rttTextStream} being {@code null}
+ * @hide
+ * @param rttTextStream The object that should be used to send text to or receive text from
+ * the in-call app.
+ */
+ public void handleRttUpgradeResponse(@Nullable RttTextStream rttTextStream) {}
+
static String toLogSafePhoneNumber(String number) {
// For unknown number, log empty string.
if (number == null) {
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 6e10029..9bc77b8 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -26,6 +26,8 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
import android.telecom.Logging.Session;
import com.android.internal.os.SomeArgs;
@@ -119,6 +121,9 @@
private static final String SESSION_PULL_EXTERNAL_CALL = "CS.pEC";
private static final String SESSION_SEND_CALL_EVENT = "CS.sCE";
private static final String SESSION_EXTRAS_CHANGED = "CS.oEC";
+ private static final String SESSION_START_RTT = "CS.+RTT";
+ private static final String SESSION_STOP_RTT = "CS.-RTT";
+ private static final String SESSION_RTT_UPGRADE_RESPONSE = "CS.rTRUR";
private static final int MSG_ADD_CONNECTION_SERVICE_ADAPTER = 1;
private static final int MSG_CREATE_CONNECTION = 2;
@@ -144,6 +149,9 @@
private static final int MSG_SEND_CALL_EVENT = 23;
private static final int MSG_ON_EXTRAS_CHANGED = 24;
private static final int MSG_CREATE_CONNECTION_FAILED = 25;
+ private static final int MSG_ON_START_RTT = 26;
+ private static final int MSG_ON_STOP_RTT = 27;
+ private static final int MSG_RTT_UPGRADE_RESPONSE = 28;
private static Connection sNullConnection;
@@ -501,6 +509,53 @@
Log.endSession();
}
}
+
+ @Override
+ public void startRtt(String callId, ParcelFileDescriptor fromInCall,
+ ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
+ Log.startSession(sessionInfo, SESSION_START_RTT);
+ try {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
+ args.arg3 = Log.createSubsession();
+ mHandler.obtainMessage(MSG_ON_START_RTT, args).sendToTarget();
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void stopRtt(String callId, Session.Info sessionInfo) throws RemoteException {
+ Log.startSession(sessionInfo, SESSION_STOP_RTT);
+ try {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = Log.createSubsession();
+ mHandler.obtainMessage(MSG_ON_STOP_RTT, args).sendToTarget();
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void respondToRttUpgradeRequest(String callId, ParcelFileDescriptor fromInCall,
+ ParcelFileDescriptor toInCall, Session.Info sessionInfo) throws RemoteException {
+ Log.startSession(sessionInfo, SESSION_RTT_UPGRADE_RESPONSE);
+ try {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ if (toInCall == null || fromInCall == null) {
+ args.arg2 = null;
+ } else {
+ args.arg2 = new Connection.RttTextStream(toInCall, fromInCall);
+ }
+ args.arg3 = Log.createSubsession();
+ mHandler.obtainMessage(MSG_RTT_UPGRADE_RESPONSE, args).sendToTarget();
+ } finally {
+ Log.endSession();
+ }
+ }
};
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -848,6 +903,49 @@
}
break;
}
+ case MSG_ON_START_RTT: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ Log.continueSession((Session) args.arg3,
+ SESSION_HANDLER + SESSION_START_RTT);
+ String callId = (String) args.arg1;
+ Connection.RttTextStream rttTextStream =
+ (Connection.RttTextStream) args.arg2;
+ startRtt(callId, rttTextStream);
+ } finally {
+ args.recycle();
+ Log.endSession();
+ }
+ break;
+ }
+ case MSG_ON_STOP_RTT: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ Log.continueSession((Session) args.arg2,
+ SESSION_HANDLER + SESSION_STOP_RTT);
+ String callId = (String) args.arg1;
+ stopRtt(callId);
+ } finally {
+ args.recycle();
+ Log.endSession();
+ }
+ break;
+ }
+ case MSG_RTT_UPGRADE_RESPONSE: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ Log.continueSession((Session) args.arg3,
+ SESSION_HANDLER + SESSION_RTT_UPGRADE_RESPONSE);
+ String callId = (String) args.arg1;
+ Connection.RttTextStream rttTextStream =
+ (Connection.RttTextStream) args.arg2;
+ handleRttUpgradeResponse(callId, rttTextStream);
+ } finally {
+ args.recycle();
+ Log.endSession();
+ }
+ break;
+ }
default:
break;
}
@@ -1136,6 +1234,38 @@
mAdapter.setAudioRoute(id, audioRoute);
}
}
+
+ @Override
+ public void onRttInitiationSuccess(Connection c) {
+ String id = mIdByConnection.get(c);
+ if (id != null) {
+ mAdapter.onRttInitiationSuccess(id);
+ }
+ }
+
+ @Override
+ public void onRttInitiationFailure(Connection c, int reason) {
+ String id = mIdByConnection.get(c);
+ if (id != null) {
+ mAdapter.onRttInitiationFailure(id, reason);
+ }
+ }
+
+ @Override
+ public void onRttSessionRemotelyTerminated(Connection c) {
+ String id = mIdByConnection.get(c);
+ if (id != null) {
+ mAdapter.onRttSessionRemotelyTerminated(id);
+ }
+ }
+
+ @Override
+ public void onRemoteRttRequest(Connection c) {
+ String id = mIdByConnection.get(c);
+ if (id != null) {
+ mAdapter.onRemoteRttRequest(id);
+ }
+ }
};
/** {@inheritDoc} */
@@ -1430,7 +1560,6 @@
if (connection != null) {
connection.onCallEvent(event, extras);
}
-
}
/**
@@ -1454,6 +1583,34 @@
}
}
+ private void startRtt(String callId, Connection.RttTextStream rttTextStream) {
+ Log.d(this, "startRtt(%s)", callId);
+ if (mConnectionById.containsKey(callId)) {
+ findConnectionForAction(callId, "startRtt").onStartRtt(rttTextStream);
+ } else if (mConferenceById.containsKey(callId)) {
+ Log.w(this, "startRtt called on a conference.");
+ }
+ }
+
+ private void stopRtt(String callId) {
+ Log.d(this, "stopRtt(%s)", callId);
+ if (mConnectionById.containsKey(callId)) {
+ findConnectionForAction(callId, "stopRtt").onStopRtt();
+ } else if (mConferenceById.containsKey(callId)) {
+ Log.w(this, "stopRtt called on a conference.");
+ }
+ }
+
+ private void handleRttUpgradeResponse(String callId, Connection.RttTextStream rttTextStream) {
+ Log.d(this, "handleRttUpgradeResponse(%s, %s)", callId, rttTextStream == null);
+ if (mConnectionById.containsKey(callId)) {
+ findConnectionForAction(callId, "handleRttUpgradeResponse")
+ .handleRttUpgradeResponse(rttTextStream);
+ } else if (mConferenceById.containsKey(callId)) {
+ Log.w(this, "handleRttUpgradeResponse called on a conference.");
+ }
+ }
+
private void onPostDialContinue(String callId, boolean proceed) {
Log.d(this, "onPostDialContinue(%s)", callId);
findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index 9542b73..63bdf74 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -547,4 +547,66 @@
}
}
}
+
+ /**
+ * Notifies Telecom that an RTT session was successfully established.
+ *
+ * @param callId The unique ID of the call.
+ */
+ void onRttInitiationSuccess(String callId) {
+ Log.v(this, "onRttInitiationSuccess: %s", callId);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.onRttInitiationSuccess(callId, Log.getExternalSession());
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ /**
+ * Notifies Telecom that a requested RTT session failed to be established.
+ *
+ * @param callId The unique ID of the call.
+ */
+ void onRttInitiationFailure(String callId, int reason) {
+ Log.v(this, "onRttInitiationFailure: %s", callId);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.onRttInitiationFailure(callId, reason, Log.getExternalSession());
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ /**
+ * Notifies Telecom that an established RTT session was terminated by the remote user on
+ * the call.
+ *
+ * @param callId The unique ID of the call.
+ */
+ void onRttSessionRemotelyTerminated(String callId) {
+ Log.v(this, "onRttSessionRemotelyTerminated: %s", callId);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.onRttSessionRemotelyTerminated(callId, Log.getExternalSession());
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ /**
+ * Notifies Telecom that the remote user on the call has requested an upgrade to an RTT
+ * session for this call.
+ *
+ * @param callId The unique ID of the call.
+ */
+ void onRemoteRttRequest(String callId) {
+ Log.v(this, "onRemoteRttRequest: %s", callId);
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.onRemoteRttRequest(callId, Log.getExternalSession());
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
}
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index cc437f9..80e3c33 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -68,6 +68,10 @@
private static final int MSG_SET_CONNECTION_PROPERTIES = 27;
private static final int MSG_SET_PULLING = 28;
private static final int MSG_SET_AUDIO_ROUTE = 29;
+ private static final int MSG_ON_RTT_INITIATION_SUCCESS = 30;
+ private static final int MSG_ON_RTT_INITIATION_FAILURE = 31;
+ private static final int MSG_ON_RTT_REMOTELY_TERMINATED = 32;
+ private static final int MSG_ON_RTT_UPGRADE_REQUEST = 33;
private final IConnectionServiceAdapter mDelegate;
@@ -300,6 +304,20 @@
}
break;
}
+ case MSG_ON_RTT_INITIATION_SUCCESS:
+ mDelegate.onRttInitiationSuccess((String) msg.obj, null /*Session.Info*/);
+ break;
+ case MSG_ON_RTT_INITIATION_FAILURE:
+ mDelegate.onRttInitiationFailure((String) msg.obj, msg.arg1,
+ null /*Session.Info*/);
+ break;
+ case MSG_ON_RTT_REMOTELY_TERMINATED:
+ mDelegate.onRttSessionRemotelyTerminated((String) msg.obj,
+ null /*Session.Info*/);
+ break;
+ case MSG_ON_RTT_UPGRADE_REQUEST:
+ mDelegate.onRemoteRttRequest((String) msg.obj, null /*Session.Info*/);
+ break;
}
}
};
@@ -537,6 +555,32 @@
args.arg3 = extras;
mHandler.obtainMessage(MSG_ON_CONNECTION_EVENT, args).sendToTarget();
}
+
+ @Override
+ public void onRttInitiationSuccess(String connectionId, Session.Info sessionInfo)
+ throws RemoteException {
+ mHandler.obtainMessage(MSG_ON_RTT_INITIATION_SUCCESS, connectionId).sendToTarget();
+ }
+
+ @Override
+ public void onRttInitiationFailure(String connectionId, int reason,
+ Session.Info sessionInfo)
+ throws RemoteException {
+ mHandler.obtainMessage(MSG_ON_RTT_INITIATION_FAILURE, reason, 0, connectionId)
+ .sendToTarget();
+ }
+
+ @Override
+ public void onRttSessionRemotelyTerminated(String connectionId, Session.Info sessionInfo)
+ throws RemoteException {
+ mHandler.obtainMessage(MSG_ON_RTT_REMOTELY_TERMINATED, connectionId).sendToTarget();
+ }
+
+ @Override
+ public void onRemoteRttRequest(String connectionId, Session.Info sessionInfo)
+ throws RemoteException {
+ mHandler.obtainMessage(MSG_ON_RTT_UPGRADE_REQUEST, connectionId).sendToTarget();
+ }
};
public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) {
diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java
index d640b1d..9559a28 100644
--- a/telecomm/java/android/telecom/InCallAdapter.java
+++ b/telecomm/java/android/telecom/InCallAdapter.java
@@ -379,9 +379,9 @@
/**
* Sends an RTT upgrade request to the remote end of the connection.
*/
- public void sendRttRequest() {
+ public void sendRttRequest(String callId) {
try {
- mAdapter.sendRttRequest();
+ mAdapter.sendRttRequest(callId);
} catch (RemoteException ignored) {
}
}
@@ -392,9 +392,9 @@
* @param id the ID of the request as specified by Telecom
* @param accept Whether the request should be accepted.
*/
- public void respondToRttRequest(int id, boolean accept) {
+ public void respondToRttRequest(String callId, int id, boolean accept) {
try {
- mAdapter.respondToRttRequest(id, accept);
+ mAdapter.respondToRttRequest(callId, id, accept);
} catch (RemoteException ignored) {
}
}
@@ -402,9 +402,9 @@
/**
* Instructs Telecom to shut down the RTT communication channel.
*/
- public void stopRtt() {
+ public void stopRtt(String callId) {
try {
- mAdapter.stopRtt();
+ mAdapter.stopRtt(callId);
} catch (RemoteException ignored) {
}
}
@@ -413,9 +413,9 @@
* Sets the RTT audio mode.
* @param mode the desired RTT audio mode
*/
- public void setRttMode(int mode) {
+ public void setRttMode(String callId, int mode) {
try {
- mAdapter.setRttMode(mode);
+ mAdapter.setRttMode(callId, mode);
} catch (RemoteException ignored) {
}
}
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 4bc64c0..5d8f9f6 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -77,6 +77,7 @@
private static final int MSG_SILENCE_RINGER = 8;
private static final int MSG_ON_CONNECTION_EVENT = 9;
private static final int MSG_ON_RTT_UPGRADE_REQUEST = 10;
+ private static final int MSG_ON_RTT_INITIATION_FAILURE = 11;
/** Default Handler used to consolidate binder method calls onto a single thread. */
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -140,6 +141,12 @@
mPhone.internalOnRttUpgradeRequest(callId, requestId);
break;
}
+ case MSG_ON_RTT_INITIATION_FAILURE: {
+ String callId = (String) msg.obj;
+ int reason = msg.arg1;
+ mPhone.internalOnRttInitiationFailure(callId, reason);
+ break;
+ }
default:
break;
}
@@ -210,6 +217,11 @@
public void onRttUpgradeRequest(String callId, int id) {
mHandler.obtainMessage(MSG_ON_RTT_UPGRADE_REQUEST, id, 0, callId).sendToTarget();
}
+
+ @Override
+ public void onRttInitiationFailure(String callId, int reason) {
+ mHandler.obtainMessage(MSG_ON_RTT_INITIATION_FAILURE, reason, 0, callId).sendToTarget();
+ }
}
private Phone.Listener mPhoneListener = new Phone.Listener() {
diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java
index ebd04c7..db2abf3 100644
--- a/telecomm/java/android/telecom/Phone.java
+++ b/telecomm/java/android/telecom/Phone.java
@@ -208,6 +208,13 @@
}
}
+ final void internalOnRttInitiationFailure(String callId, int reason) {
+ Call call = mCallByTelecomCallId.get(callId);
+ if (call != null) {
+ call.internalOnRttInitiationFailure(reason);
+ }
+ }
+
/**
* Called to destroy the phone and cleanup any lingering calls.
*/
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 77e0e54..1ca54c8 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -20,6 +20,7 @@
import com.android.internal.telecom.IVideoCallback;
import com.android.internal.telecom.IVideoProvider;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.hardware.camera2.CameraManager;
@@ -231,6 +232,41 @@
* @param extras Extras associated with the event.
*/
public void onConnectionEvent(RemoteConnection connection, String event, Bundle extras) {}
+
+ /**
+ * Indicates that a RTT session was successfully established on this
+ * {@link RemoteConnection}. See {@link Connection#sendRttInitiationSuccess()}.
+ * @hide
+ * @param connection The {@code RemoteConnection} invoking this method.
+ */
+ public void onRttInitiationSuccess(RemoteConnection connection) {}
+
+ /**
+ * Indicates that a RTT session failed to be established on this
+ * {@link RemoteConnection}. See {@link Connection#sendRttInitiationFailure()}.
+ * @hide
+ * @param connection The {@code RemoteConnection} invoking this method.
+ * @param reason One of the reason codes defined in {@link Connection.RttModifyStatus},
+ * with the exception of
+ * {@link Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
+ */
+ public void onRttInitiationFailure(RemoteConnection connection, int reason) {}
+
+ /**
+ * Indicates that an established RTT session was terminated remotely on this
+ * {@link RemoteConnection}. See {@link Connection#sendRttSessionRemotelyTerminated()}
+ * @hide
+ * @param connection The {@code RemoteConnection} invoking this method.
+ */
+ public void onRttSessionRemotelyTerminated(RemoteConnection connection) {}
+
+ /**
+ * Indicates that the remote user on this {@link RemoteConnection} has requested an upgrade
+ * to an RTT session. See {@link Connection#sendRemoteRttRequest()}
+ * @hide
+ * @param connection The {@code RemoteConnection} invoking this method.
+ */
+ public void onRemoteRttRequest(RemoteConnection connection) {}
}
/**
@@ -1046,6 +1082,61 @@
}
/**
+ * Notifies this {@link RemoteConnection} that the user has requested an RTT session.
+ * @param rttTextStream The object that should be used to send text to or receive text from
+ * the in-call app.
+ * @hide
+ */
+ public void startRtt(@NonNull Connection.RttTextStream rttTextStream) {
+ try {
+ if (mConnected) {
+ mConnectionService.startRtt(mConnectionId, rttTextStream.getFdFromInCall(),
+ rttTextStream.getFdToInCall(), null /*Session.Info*/);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
+ * Notifies this {@link RemoteConnection} that it should terminate any existing RTT
+ * session. No response to Telecom is needed for this method.
+ * @hide
+ */
+ public void stopRtt() {
+ try {
+ if (mConnected) {
+ mConnectionService.stopRtt(mConnectionId, null /*Session.Info*/);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
+ * Notifies this {@link RemoteConnection} of a response to a previous remotely-initiated RTT
+ * upgrade request sent via {@link Connection#sendRemoteRttRequest}.
+ * Acceptance of the request is indicated by the supplied {@link RttTextStream} being non-null,
+ * and rejection is indicated by {@code rttTextStream} being {@code null}
+ * @hide
+ * @param rttTextStream The object that should be used to send text to or receive text from
+ * the in-call app.
+ */
+ public void sendRttUpgradeResponse(@Nullable Connection.RttTextStream rttTextStream) {
+ try {
+ if (mConnected) {
+ if (rttTextStream == null) {
+ mConnectionService.respondToRttUpgradeRequest(mConnectionId,
+ null, null, null /*Session.Info*/);
+ } else {
+ mConnectionService.respondToRttUpgradeRequest(mConnectionId,
+ rttTextStream.getFdFromInCall(), rttTextStream.getFdToInCall(),
+ null /*Session.Info*/);
+ }
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
* Obtain the {@code RemoteConnection}s with which this {@code RemoteConnection} may be
* successfully asked to create a conference with.
*
@@ -1411,6 +1502,47 @@
}
}
+ /** @hide */
+ void onRttInitiationSuccess() {
+ for (CallbackRecord record : mCallbackRecords) {
+ final RemoteConnection connection = this;
+ final Callback callback = record.getCallback();
+ record.getHandler().post(
+ () -> callback.onRttInitiationSuccess(connection));
+ }
+ }
+
+ /** @hide */
+ void onRttInitiationFailure(int reason) {
+ for (CallbackRecord record : mCallbackRecords) {
+ final RemoteConnection connection = this;
+ final Callback callback = record.getCallback();
+ record.getHandler().post(
+ () -> callback.onRttInitiationFailure(connection, reason));
+ }
+ }
+
+ /** @hide */
+ void onRttSessionRemotelyTerminated() {
+ for (CallbackRecord record : mCallbackRecords) {
+ final RemoteConnection connection = this;
+ final Callback callback = record.getCallback();
+ record.getHandler().post(
+ () -> callback.onRttSessionRemotelyTerminated(connection));
+ }
+ }
+
+ /** @hide */
+ void onRemoteRttRequest() {
+ for (CallbackRecord record : mCallbackRecords) {
+ final RemoteConnection connection = this;
+ final Callback callback = record.getCallback();
+ record.getHandler().post(
+ () -> callback.onRemoteRttRequest(connection));
+ }
+ }
+
+ /**
/**
* Create a RemoteConnection represents a failure, and which will be in
* {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 60a40f5..ffba93a 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -405,6 +405,50 @@
extras);
}
}
+
+ @Override
+ public void onRttInitiationSuccess(String callId, Session.Info sessionInfo)
+ throws RemoteException {
+ if (hasConnection(callId)) {
+ findConnectionForAction(callId, "onRttInitiationSuccess")
+ .onRttInitiationSuccess();
+ } else {
+ Log.w(this, "onRttInitiationSuccess called on a remote conference");
+ }
+ }
+
+ @Override
+ public void onRttInitiationFailure(String callId, int reason, Session.Info sessionInfo)
+ throws RemoteException {
+ if (hasConnection(callId)) {
+ findConnectionForAction(callId, "onRttInitiationFailure")
+ .onRttInitiationFailure(reason);
+ } else {
+ Log.w(this, "onRttInitiationFailure called on a remote conference");
+ }
+ }
+
+ @Override
+ public void onRttSessionRemotelyTerminated(String callId, Session.Info sessionInfo)
+ throws RemoteException {
+ if (hasConnection(callId)) {
+ findConnectionForAction(callId, "onRttSessionRemotelyTerminated")
+ .onRttSessionRemotelyTerminated();
+ } else {
+ Log.w(this, "onRttSessionRemotelyTerminated called on a remote conference");
+ }
+ }
+
+ @Override
+ public void onRemoteRttRequest(String callId, Session.Info sessionInfo)
+ throws RemoteException {
+ if (hasConnection(callId)) {
+ findConnectionForAction(callId, "onRemoteRttRequest")
+ .onRemoteRttRequest();
+ } else {
+ Log.w(this, "onRemoteRttRequest called on a remote conference");
+ }
+ }
};
private final ConnectionServiceAdapterServant mServant =