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/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) {