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

Commit 17a3814a authored by Evan Charlton's avatar Evan Charlton Committed by Android (Google) Code Review
Browse files

Merge "Make creating the Connection synchronous" into lmp-dev

parents eb527ef7 bf11f98d
Loading
Loading
Loading
Loading
+37 −24
Original line number Diff line number Diff line
@@ -28593,7 +28593,11 @@ package android.telecomm {
    method public final int getCallCapabilities();
    method public final java.lang.String getCallerDisplayName();
    method public final int getCallerDisplayNamePresentation();
    method public static android.telecomm.Connection getCanceledConnection();
    method public final java.util.List<android.telecomm.Connection> getChildConnections();
    method public static android.telecomm.Connection getFailedConnection(int, java.lang.String);
    method public final int getFailureCode();
    method public final java.lang.String getFailureMessage();
    method public final android.net.Uri getHandle();
    method public final int getHandlePresentation();
    method public final android.telecomm.Connection getParentConnection();
@@ -28622,9 +28626,13 @@ package android.telecomm {
    method public final void setAudioModeIsVoip(boolean);
    method public final void setCallCapabilities(int);
    method public final void setCallerDisplayName(java.lang.String, int);
    method public final void setCanceled();
    method public final void setDialing();
    method public final void setDisconnected(int, java.lang.String);
    method public final void setFailed(int, java.lang.String);
    method public final void setHandle(android.net.Uri, int);
    method public final void setInitialized();
    method public final void setInitializing();
    method public final void setOnHold();
    method public final void setParentConnection(android.telecomm.Connection);
    method public final void setPostDialWait(java.lang.String);
@@ -28639,12 +28647,15 @@ package android.telecomm {
  }
  public final class Connection.State {
    field public static final int ACTIVE = 3; // 0x3
    field public static final int DIALING = 2; // 0x2
    field public static final int DISCONNECTED = 5; // 0x5
    field public static final int HOLDING = 4; // 0x4
    field public static final int NEW = 0; // 0x0
    field public static final int RINGING = 1; // 0x1
    field public static final int ACTIVE = 4; // 0x4
    field public static final int CANCELED = 8; // 0x8
    field public static final int DIALING = 3; // 0x3
    field public static final int DISCONNECTED = 6; // 0x6
    field public static final int FAILED = 7; // 0x7
    field public static final int HOLDING = 5; // 0x5
    field public static final int INITIALIZING = 0; // 0x0
    field public static final int NEW = 1; // 0x1
    field public static final int RINGING = 2; // 0x2
  }
  public final class ConnectionRequest implements android.os.Parcelable {
@@ -28662,17 +28673,16 @@ package android.telecomm {
  public abstract class ConnectionService extends android.app.Service {
    ctor public ConnectionService();
    method public final void createRemoteIncomingConnection(android.telecomm.ConnectionRequest, android.telecomm.ConnectionService.CreateConnectionResponse<android.telecomm.RemoteConnection>);
    method public final void createRemoteOutgoingConnection(android.telecomm.ConnectionRequest, android.telecomm.ConnectionService.CreateConnectionResponse<android.telecomm.RemoteConnection>);
    method public final android.telecomm.RemoteConnection createRemoteIncomingConnection(android.telecomm.ConnectionRequest);
    method public final android.telecomm.RemoteConnection createRemoteOutgoingConnection(android.telecomm.ConnectionRequest);
    method public final java.util.Collection<android.telecomm.Connection> getAllConnections();
    method public final void lookupRemoteAccounts(android.net.Uri, android.telecomm.SimpleResponse<android.net.Uri, java.util.List<android.telecomm.PhoneAccountHandle>>);
    method public final void maybeRespondToAccountLookup();
    method public final android.os.IBinder onBind(android.content.Intent);
    method public void onConnectionAdded(android.telecomm.Connection);
    method public void onConnectionRemoved(android.telecomm.Connection);
    method public void onCreateConferenceConnection(java.lang.String, android.telecomm.Connection, android.telecomm.Response<java.lang.String, android.telecomm.Connection>);
    method public void onCreateIncomingConnection(android.telecomm.ConnectionRequest, android.telecomm.ConnectionService.CreateConnectionResponse<android.telecomm.Connection>);
    method public void onCreateOutgoingConnection(android.telecomm.ConnectionRequest, android.telecomm.ConnectionService.CreateConnectionResponse<android.telecomm.Connection>);
    method public android.telecomm.Connection onCreateIncomingConnection(android.telecomm.ConnectionRequest);
    method public android.telecomm.Connection onCreateOutgoingConnection(android.telecomm.ConnectionRequest);
    field public static final java.lang.String SERVICE_INTERFACE = "android.telecomm.ConnectionService";
  }
@@ -28803,6 +28813,8 @@ package android.telecomm {
    method public int getCallerDisplayNamePresentation();
    method public int getDisconnectCause();
    method public java.lang.String getDisconnectMessage();
    method public int getFailureCode();
    method public java.lang.String getFailureMessage();
    method public android.net.Uri getHandle();
    method public int getHandlePresentation();
    method public int getState();
@@ -28819,19 +28831,20 @@ package android.telecomm {
    method public void unhold();
  }
  public static abstract interface RemoteConnection.Listener {
    method public abstract void onAudioModeIsVoipChanged(android.telecomm.RemoteConnection, boolean);
    method public abstract void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int);
    method public abstract void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int);
    method public abstract void onDestroyed(android.telecomm.RemoteConnection);
    method public abstract void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String);
    method public abstract void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
    method public abstract void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String);
    method public abstract void onRequestingRingback(android.telecomm.RemoteConnection, boolean);
    method public abstract void onStartActivityFromInCall(android.telecomm.RemoteConnection, android.app.PendingIntent);
    method public abstract void onStateChanged(android.telecomm.RemoteConnection, int);
    method public abstract void onStatusHintsChanged(android.telecomm.RemoteConnection, android.telecomm.StatusHints);
    method public abstract void onVideoStateChanged(android.telecomm.RemoteConnection, int);
  public static abstract class RemoteConnection.Listener {
    ctor public RemoteConnection.Listener();
    method public void onAudioModeIsVoipChanged(android.telecomm.RemoteConnection, boolean);
    method public void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int);
    method public void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int);
    method public void onDestroyed(android.telecomm.RemoteConnection);
    method public void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String);
    method public void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
    method public void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String);
    method public void onRequestingRingback(android.telecomm.RemoteConnection, boolean);
    method public void onStartActivityFromInCall(android.telecomm.RemoteConnection, android.app.PendingIntent);
    method public void onStateChanged(android.telecomm.RemoteConnection, int);
    method public void onStatusHintsChanged(android.telecomm.RemoteConnection, android.telecomm.StatusHints);
    method public void onVideoStateChanged(android.telecomm.RemoteConnection, int);
  }
  public abstract interface Response {
+119 −13
Original line number Diff line number Diff line
@@ -48,17 +48,22 @@ public abstract class Connection {
        public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
        public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
        public void onStartActivityFromInCall(Connection c, PendingIntent intent) {}
        public void onFailed(Connection c, int code, String msg) {}
    }

    public final class State {
        private State() {}

        public static final int NEW = 0;
        public static final int RINGING = 1;
        public static final int DIALING = 2;
        public static final int ACTIVE = 3;
        public static final int HOLDING = 4;
        public static final int DISCONNECTED = 5;
        public static final int INITIALIZING = 0;
        public static final int NEW = 1;
        public static final int RINGING = 2;
        public static final int DIALING = 3;
        public static final int ACTIVE = 4;
        public static final int HOLDING = 5;
        public static final int DISCONNECTED = 6;
        public static final int FAILED = 7;
        public static final int CANCELED = 8;

    }

    private final Set<Listener> mListeners = new HashSet<>();
@@ -77,6 +82,9 @@ public abstract class Connection {
    private boolean mAudioModeIsVoip;
    private StatusHints mStatusHints;
    private int mVideoState;
    private int mFailureCode;
    private String mFailureMessage;
    private boolean mIsCanceled;

    /**
     * Create a new Connection.
@@ -196,6 +204,20 @@ public abstract class Connection {
        return this;
    }

    /**
     * @return The failure code ({@see DisconnectCause}) associated with this failed connection.
     */
    public final int getFailureCode() {
        return mFailureCode;
    }

    /**
     * @return The reason for the connection failure. This will not be displayed to the user.
     */
    public final String getFailureMessage() {
        return mFailureMessage;
    }

    /**
     * Inform this Connection that the state of its audio output has been changed externally.
     *
@@ -226,6 +248,10 @@ public abstract class Connection {
                return "HOLDING";
            case State.DISCONNECTED:
                return "DISCONNECTED";
            case State.FAILED:
                return "FAILED";
            case State.CANCELED:
                return "CANCELED";
            default:
                Log.wtf(Connection.class, "Unknown state %d", state);
                return "UNKNOWN";
@@ -299,6 +325,33 @@ public abstract class Connection {
        }
    }

    /**
     * Cancel the {@link Connection}. Once this is called, the {@link Connection} will not be used,
     * and no subsequent {@link Connection}s will be attempted.
     */
    public final void setCanceled() {
        Log.d(this, "setCanceled");
        setState(State.CANCELED);
    }

    /**
     * Move the {@link Connection} to the {@link State#FAILED} state, with the given code
     * ({@see DisconnectCause}) and message. This message is not shown to the user, but is useful
     * for logging and debugging purposes.
     * <p>
     * After calling this, the {@link Connection} will not be used.
     *
     * @param code The {@link android.telephony.DisconnectCause} indicating why the connection
     *             failed.
     * @param message A message explaining why the {@link Connection} failed.
     */
    public final void setFailed(int code, String message) {
        Log.d(this, "setFailed (%d: %s)", code, message);
        mFailureCode = code;
        mFailureMessage = message;
        setState(State.FAILED);
    }

    /**
     * Set the video state for the connection.
     * Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY},
@@ -332,6 +385,20 @@ public abstract class Connection {
        setState(State.RINGING);
    }

    /**
     * Sets state to initializing (this Connection is not yet ready to be used).
     */
    public final void setInitializing() {
        setState(State.INITIALIZING);
    }

    /**
     * Sets state to initialized (the Connection has been set up and is now ready to be used).
     */
    public final void setInitialized() {
        setState(State.NEW);
    }

    /**
     * Sets state to dialing (e.g., dialing an outbound call).
     */
@@ -485,8 +552,8 @@ public abstract class Connection {
    public void onSetAudioState(CallAudioState state) {}

    /**
     * Notifies this Connection of an internal state change. This method is called before the
     * state is actually changed.
     * Notifies this Connection of an internal state change. This method is called after the
     * state is changed.
     *
     * @param state The new state, a {@link Connection.State} member.
     */
@@ -577,11 +644,50 @@ public abstract class Connection {
    }

    private void setState(int state) {
        if (mState == State.FAILED || mState == State.CANCELED) {
            Log.d(this, "Connection already %s; cannot transition out of this state.",
                    stateToString(mState));
            return;
        }
        if (mState != state) {
            Log.d(this, "setState: %s", stateToString(state));
        this.mState = state;
            mState = state;
            for (Listener l : mListeners) {
                l.onStateChanged(this, state);
            }
            onSetState(state);
        }
    }

    /**
     * Return a {@link Connection} which represents a failed connection attempt. The returned
     * {@link Connection} will have {@link #getFailureCode()}, {@link #getFailureMessage()}, and
     * {@link #getState()} set appropriately, but the {@link Connection} itself should not be used
     * for anything.
     *
     * @param code The failure code ({@see DisconnectCause}).
     * @param message A reason for why the connection failed (not intended to be shown to the user).
     * @return A {@link Connection} which indicates failure.
     */
    public static Connection getFailedConnection(final int code, final String message) {
        return new Connection() {{
            setFailed(code, message);
        }};
    }

    private static final Connection CANCELED_CONNECTION = new Connection() {{
        setCanceled();
    }};

    /**
     * Return a {@link Connection} which represents a canceled a connection attempt. The returned
     * {@link Connection} will have state {@link State#CANCELED}, and cannot be moved out of that
     * state. This connection should not be used for anything, and no other {@link Connection}s
     * should be attempted.
     *
     * @return A {@link Connection} which indicates that the underlying call should be canceled.
     */
    public static Connection getCanceledConnection() {
        return CANCELED_CONNECTION;
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ResultReceiver;
import android.telephony.DisconnectCause;

/**
 * Simple data container encapsulating a request to some entity to
@@ -110,6 +112,7 @@ public final class ConnectionRequest implements Parcelable {
        return mVideoState;
    }

    @Override
    public String toString() {
        return String.format("PhoneConnectionRequest %s %s",
                mHandle == null
+77 −61
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;

import android.telephony.DisconnectCause;
import com.android.internal.os.SomeArgs;
import com.android.internal.telecomm.IConnectionService;
import com.android.internal.telecomm.IConnectionServiceAdapter;
@@ -132,7 +132,7 @@ public abstract class ConnectionService extends Service {
        public void answer(String callId, int videoState) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = callId;
            args.arg2 = videoState;
            args.argi1 = videoState;
            mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
        }

@@ -224,7 +224,7 @@ public abstract class ConnectionService extends Service {
                    SomeArgs args = (SomeArgs) msg.obj;
                    try {
                        String callId = (String) args.arg1;
                        int videoState = (int) args.arg2;
                        int videoState = args.argi1;
                        answer(callId, videoState);
                    } finally {
                        args.recycle();
@@ -425,13 +425,60 @@ public abstract class ConnectionService extends Service {
     * incoming call. In either case, telecomm will cycle through a set of services and call
     * createConnection util a connection service cancels the process or completes it successfully.
     */
    private void createConnection(ConnectionRequest originalRequest, boolean isIncoming) {
        Log.d(this, "call %s", originalRequest);
        CreateConnectionResponse response = new CreateConnectionResponse<Connection>() {
            @Override
            public void onSuccess(ConnectionRequest request, Connection connection) {
    private void createConnection(final ConnectionRequest request, boolean isIncoming) {
        Log.d(this, "call %s", request);

        final Connection createdConnection;
        if (isIncoming) {
            createdConnection = onCreateIncomingConnection(request);
        } else {
            createdConnection = onCreateOutgoingConnection(request);
        }

        if (createdConnection != null) {
            Log.d(this, "adapter handleCreateConnectionSuccessful %s",
                    request.getCallId());
            if (createdConnection.getState() == Connection.State.INITIALIZING) {
                // Wait for the connection to become initialized.
                createdConnection.addConnectionListener(new Connection.Listener() {
                    @Override
                    public void onStateChanged(Connection c, int state) {
                        switch (state) {
                            case Connection.State.FAILED:
                                Log.d(this, "Connection (%s) failed (%d: %s)", request,
                                        c.getFailureCode(), c.getFailureMessage());
                                mAdapter.handleCreateConnectionFailed(request, c.getFailureCode(),
                                        c.getFailureMessage());
                                break;
                            case Connection.State.CANCELED:
                                Log.d(this, "Connection (%s) canceled", request);
                                mAdapter.handleCreateConnectionCancelled(request);
                                break;
                            case Connection.State.INITIALIZING:
                                Log.d(this, "State changed to INITIALIZING; ignoring");
                                return; // Don't want to stop listening on this state transition.
                            default:
                                Log.d(this, "Connection created in state %s",
                                        Connection.stateToString(state));
                                connectionCreated(request, createdConnection);
                                break;
                        }
                        c.removeConnectionListener(this);
                    }
                });
            } else if (createdConnection.getState() == Connection.State.CANCELED) {
                // Tell telecomm not to attempt any more services.
                mAdapter.handleCreateConnectionCancelled(request);
            } else {
                connectionCreated(request, createdConnection);
            }
        } else {
            // Tell telecomm to try a different service.
            mAdapter.handleCreateConnectionFailed(request, DisconnectCause.ERROR_UNSPECIFIED, null);
        }
    }

    private void connectionCreated(ConnectionRequest request, Connection connection) {
        addConnection(request.getCallId(), connection);
        mAdapter.handleCreateConnectionSuccessful(
                request,
@@ -448,25 +495,6 @@ public abstract class ConnectionService extends Service {
                        connection.getVideoState()));
    }

            @Override
            public void onFailure(ConnectionRequest request, int code, String msg) {
                // Tell telecomm to try a different service.
                mAdapter.handleCreateConnectionFailed(request, code, msg);
            }

            @Override
            public void onCancel(ConnectionRequest request) {
                // Tell telecomm not to attempt any more services.
                mAdapter.handleCreateConnectionCancelled(request);
            }
        };
        if (isIncoming) {
            onCreateIncomingConnection(originalRequest, response);
        } else {
            onCreateOutgoingConnection(originalRequest, response);
        }
    }

    private void abort(String callId) {
        Log.d(this, "abort %s", callId);
        findConnectionForAction(callId, "abort").onAbort();
@@ -609,13 +637,6 @@ public abstract class ConnectionService extends Service {
        });
    }

    public final void lookupRemoteAccounts(
            Uri handle, SimpleResponse<Uri, List<PhoneAccountHandle>> response) {
        mAccountLookupResponse = response;
        mAccountLookupHandle = handle;
        maybeRespondToAccountLookup();
    }

    public final void maybeRespondToAccountLookup() {
        if (mAreAccountsInitialized && mAccountLookupResponse != null) {
            mAccountLookupResponse.onResult(
@@ -627,16 +648,12 @@ public abstract class ConnectionService extends Service {
        }
    }

    public final void createRemoteIncomingConnection(
            ConnectionRequest request,
            CreateConnectionResponse<RemoteConnection> response) {
        mRemoteConnectionManager.createRemoteConnection(request, response, true);
    public final RemoteConnection createRemoteIncomingConnection(ConnectionRequest request) {
        return mRemoteConnectionManager.createRemoteConnection(request, true);
    }

    public final void createRemoteOutgoingConnection(
            ConnectionRequest request,
            CreateConnectionResponse<RemoteConnection> response) {
        mRemoteConnectionManager.createRemoteConnection(request, response, false);
    public final RemoteConnection createRemoteOutgoingConnection(ConnectionRequest request) {
        return mRemoteConnectionManager.createRemoteConnection(request, false);
    }

    /**
@@ -649,23 +666,22 @@ public abstract class ConnectionService extends Service {
    /**
     * Create a Connection given an incoming request. This is used to attach to existing incoming
     * calls.
     *
     * @param request Details about the incoming call.
     * @param callback A callback for providing the result.
     *
     * @return The {@link Connection} object to satisfy this call, or {@code null} to not handle
     * the call.
     */
    public void onCreateIncomingConnection(
            ConnectionRequest request,
            CreateConnectionResponse<Connection> callback) {}
    public Connection onCreateIncomingConnection(ConnectionRequest request) { return null; }

    /**
     * Create a Connection given an outgoing request. This is used to initiate new outgoing calls.
     *
     *  @param request Details about the outgoing call.
     * @param callback A callback for providing the result.
     *
     * @return The {@link Connection} object to satisfy this request,
     * or null to not handle the call.
     *
     */
    public void onCreateOutgoingConnection(
            ConnectionRequest request,
            CreateConnectionResponse<Connection> callback) {}
    public Connection onCreateOutgoingConnection(ConnectionRequest request) { return null; }

    /**
     * Returns a new or existing conference connection when the the user elects to convert the
+67 −20

File changed.

Preview size limit exceeded, changes collapsed.

Loading