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

Commit b64ac4c5 authored by Hall Liu's avatar Hall Liu
Browse files

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
Merged-In: Ia80604b7dff8586ff222dbccdbe55e91aab02178
Change-Id: Ia80604b7dff8586ff222dbccdbe55e91aab02178
parent 7f0300f1
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -36691,6 +36691,7 @@ package android.telecom {
    method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
    method public void onParentChanged(android.telecom.Call, android.telecom.Call);
    method public void onPostDialWait(android.telecom.Call, java.lang.String);
    method public void onRttInitiationFailure(android.telecom.Call, int);
    method public void onRttModeChanged(android.telecom.Call, int);
    method public void onRttRequest(android.telecom.Call, int);
    method public void onRttStatusChanged(android.telecom.Call, boolean, android.telecom.Call.RttCall);
@@ -36957,6 +36958,15 @@ package android.telecom {
    field public static final int STATE_RINGING = 2; // 0x2
  }
  public static final class Connection.RttModifyStatus {
    ctor public Connection.RttModifyStatus();
    field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2
    field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3
    field public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5; // 0x5
    field public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1; // 0x1
    field public static final int SESSION_MODIFY_REQUEST_TIMED_OUT = 4; // 0x4
  }
  public static abstract class Connection.VideoProvider {
    ctor public Connection.VideoProvider();
    method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
+10 −0
Original line number Diff line number Diff line
@@ -39665,6 +39665,7 @@ package android.telecom {
    method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
    method public void onParentChanged(android.telecom.Call, android.telecom.Call);
    method public void onPostDialWait(android.telecom.Call, java.lang.String);
    method public void onRttInitiationFailure(android.telecom.Call, int);
    method public void onRttModeChanged(android.telecom.Call, int);
    method public void onRttRequest(android.telecom.Call, int);
    method public void onRttStatusChanged(android.telecom.Call, boolean, android.telecom.Call.RttCall);
@@ -39942,6 +39943,15 @@ package android.telecom {
    field public static final int STATE_RINGING = 2; // 0x2
  }
  public static final class Connection.RttModifyStatus {
    ctor public Connection.RttModifyStatus();
    field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2
    field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3
    field public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5; // 0x5
    field public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1; // 0x1
    field public static final int SESSION_MODIFY_REQUEST_TIMED_OUT = 4; // 0x4
  }
  public static abstract class Connection.VideoProvider {
    ctor public Connection.VideoProvider();
    method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
+10 −0
Original line number Diff line number Diff line
@@ -36773,6 +36773,7 @@ package android.telecom {
    method public void onDetailsChanged(android.telecom.Call, android.telecom.Call.Details);
    method public void onParentChanged(android.telecom.Call, android.telecom.Call);
    method public void onPostDialWait(android.telecom.Call, java.lang.String);
    method public void onRttInitiationFailure(android.telecom.Call, int);
    method public void onRttModeChanged(android.telecom.Call, int);
    method public void onRttRequest(android.telecom.Call, int);
    method public void onRttStatusChanged(android.telecom.Call, boolean, android.telecom.Call.RttCall);
@@ -37039,6 +37040,15 @@ package android.telecom {
    field public static final int STATE_RINGING = 2; // 0x2
  }
  public static final class Connection.RttModifyStatus {
    ctor public Connection.RttModifyStatus();
    field public static final int SESSION_MODIFY_REQUEST_FAIL = 2; // 0x2
    field public static final int SESSION_MODIFY_REQUEST_INVALID = 3; // 0x3
    field public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5; // 0x5
    field public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1; // 0x1
    field public static final int SESSION_MODIFY_REQUEST_TIMED_OUT = 4; // 0x4
  }
  public static abstract class Connection.VideoProvider {
    ctor public Connection.VideoProvider();
    method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
+28 −7
Original line number Diff line number Diff line
@@ -871,6 +871,16 @@ public final class Call {
         * @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 @@ public final class Call {
        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 @@ public final class Call {
         * {@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 @@ public final class Call {
     * {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
     */
    public void sendRttRequest() {
        mInCallAdapter.sendRttRequest();
        mInCallAdapter.sendRttRequest(mTelecomCallId);
    }

    /**
@@ -1224,7 +1236,7 @@ public final class Call {
     * @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 @@ public final class Call {
     * the {@link Callback#onRttStatusChanged(Call, boolean, RttCall)} callback.
     */
    public void stopRtt() {
        mInCallAdapter.stopRtt();
        mInCallAdapter.stopRtt(mTelecomCallId);
    }

    /**
@@ -1637,7 +1649,7 @@ public final class Call {
                    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 @@ public final class Call {
        }
    }

    /** @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;
+122 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import com.android.internal.os.SomeArgs;
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 android.view.Surface;
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 @@ public abstract class Connection extends Conferenceable {
        /** @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 @@ public abstract class Connection extends Conferenceable {
        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 @@ public abstract class Connection extends Conferenceable {
                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;
    }

    /**
@@ -2425,6 +2477,47 @@ public abstract class Connection extends Conferenceable {
        }
    }

    /**
     * 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.
     *
@@ -2595,6 +2688,35 @@ public abstract class Connection extends Conferenceable {
     */
    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) {
Loading