Merge "ConnectionService API has only one completed callback (1/3)" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index b8a65fc..ab134f3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28828,12 +28828,10 @@
     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 setConferenceableConnections(java.util.List<android.telecomm.Connection>);
     method public final void setConnectionService(android.telecomm.ConnectionService);
     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();
@@ -28847,10 +28845,8 @@
     method public final void startActivityFromInCall(android.app.PendingIntent);
     method public static java.lang.String stateToString(int);
     field public static final int STATE_ACTIVE = 4; // 0x4
-    field public static final int STATE_CANCELED = 8; // 0x8
     field public static final int STATE_DIALING = 3; // 0x3
     field public static final int STATE_DISCONNECTED = 6; // 0x6
-    field public static final int STATE_FAILED = 7; // 0x7
     field public static final int STATE_HOLDING = 5; // 0x5
     field public static final int STATE_INITIALIZING = 0; // 0x0
     field public static final int STATE_NEW = 1; // 0x1
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 27debde..c1d5715 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -36,6 +36,15 @@
 
 /**
  * Represents a connection to a remote endpoint that carries voice traffic.
+ * <p>
+ * Implementations create a custom subclass of {@code Connection} and return it to the framework
+ * as the return value of
+ * {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
+ * or
+ * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
+ * Implementations are then responsible for updating the state of the {@code Connection}, and
+ * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no
+ * longer used and associated resources may be recovered.
  */
 public abstract class Connection {
 
@@ -53,10 +62,6 @@
 
     public static final int STATE_DISCONNECTED = 6;
 
-    public static final int STATE_FAILED = 7;
-
-    public static final int STATE_CANCELED = 8;
-
     // Flag controlling whether PII is emitted into the logs
     private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
 
@@ -644,10 +649,6 @@
                 return "STATE_HOLDING";
             case STATE_DISCONNECTED:
                 return "DISCONNECTED";
-            case STATE_FAILED:
-                return "STATE_FAILED";
-            case STATE_CANCELED:
-                return "STATE_CANCELED";
             default:
                 Log.wtf(Connection.class, "Unknown state %d", state);
                 return "UNKNOWN";
@@ -694,33 +695,6 @@
     }
 
     /**
-     * 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 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 VideoProfile.VideoState#AUDIO_ONLY},
      * {@link VideoProfile.VideoState#BIDIRECTIONAL},
@@ -1094,9 +1068,8 @@
     }
 
     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));
+        if (mState == STATE_DISCONNECTED && mState != state) {
+            Log.d(this, "Connection already DISCONNECTED; cannot transition out of this state.");
             return;
         }
         if (mState != state) {
@@ -1109,33 +1082,41 @@
         }
     }
 
+    static class FailureSignalingConnection extends Connection {
+        public FailureSignalingConnection(int code, String message) {
+            setDisconnected(code, message);
+        }
+    }
+
     /**
-     * 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.
+     * Return a {@code Connection} which represents a failed connection attempt. The returned
+     * {@code Connection} will have a {@link #getFailureCode()} and {@link #getFailureMessage()}
+     * as specified, a {@link #getState()} of {@link #STATE_DISCONNECTED}.
+     * <p>
+     * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
+     * so users of this method need not maintain a reference to its return value to destroy it.
      *
      * @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.
+     * @return A {@code Connection} which indicates failure.
      */
     public static Connection createFailedConnection(final int code, final String message) {
-        return new Connection() {{
-            setFailed(code, message);
-        }};
+        return new FailureSignalingConnection(code, message);
     }
 
-    private static final Connection CANCELED_CONNECTION = new Connection() {{
-        setCanceled();
-    }};
+    private static final Connection CANCELED_CONNECTION =
+            new FailureSignalingConnection(DisconnectCause.OUTGOING_CANCELED, null);
 
     /**
-     * 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 {@code Connection} which represents a canceled connection attempt. The returned
+     * {@code Connection} will have state {@link #STATE_DISCONNECTED}, and cannot be moved out of
+     * that state. This connection should not be used for anything, and no other
+     * {@code Connection}s should be attempted.
+     * <p>
+     * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
+     * so users of this method need not maintain a reference to its return value to destroy it.
      *
-     * @return A {@link Connection} which indicates that the underlying call should be canceled.
+     * @return A {@code Connection} which indicates that the underlying call should be canceled.
      */
     public static Connection createCanceledConnection() {
         return CANCELED_CONNECTION;
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 97a3102..03b6c7b 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -500,81 +500,26 @@
             boolean isIncoming) {
         Log.d(this, "call %s", request);
 
-        final Connection createdConnection;
-        if (isIncoming) {
-            createdConnection = onCreateIncomingConnection(callManagerAccount, request);
-        } else {
-            createdConnection = onCreateOutgoingConnection(callManagerAccount, request);
-        }
+        Connection createdConnection = isIncoming
+                ? onCreateIncomingConnection(callManagerAccount, request)
+                : onCreateOutgoingConnection(callManagerAccount, request);
 
-        if (createdConnection != null) {
-            Log.d(this, "adapter handleCreateConnectionSuccessful %s", callId);
-            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());
-                                Log.d(this, "adapter handleCreateConnectionFailed %s",
-                                        callId);
-                                mAdapter.handleCreateConnectionFailed(
-                                        callId,
-                                        request,
-                                        c.getFailureCode(),
-                                        c.getFailureMessage());
-                                break;
-                            case Connection.STATE_CANCELED:
-                                Log.d(this, "adapter handleCreateConnectionCanceled %s",
-                                        callId);
-                                mAdapter.handleCreateConnectionCancelled(callId, request);
-                                break;
-                            case Connection.STATE_INITIALIZING:
-                                Log.d(this, "State changed to STATE_INITIALIZING; ignoring");
-                                return; // Don't want to stop listening on this state transition.
-                        }
-                        c.removeConnectionListener(this);
-                    }
-
-                    @Override
-                    public void onDestroyed(Connection c) {
-                        // Listen to onDestroy in case the connection is destroyed before
-                        // transitioning to another state.
-                        c.removeConnectionListener(this);
-                    }
-                });
-                Log.d(this, "Connection created in state INITIALIZING");
-                connectionCreated(callId, request, createdConnection);
-            } else if (createdConnection.getState() == Connection.STATE_CANCELED) {
-                // Tell telecomm not to attempt any more services.
-                mAdapter.handleCreateConnectionCancelled(callId, request);
-            } else if (createdConnection.getState() == Connection.STATE_FAILED) {
-                mAdapter.handleCreateConnectionFailed(
-                        callId,
-                        request,
-                        createdConnection.getFailureCode(),
-                        createdConnection.getFailureMessage());
-            } else {
-                connectionCreated(callId, request, createdConnection);
-            }
-        } else {
+        if (createdConnection == null) {
+            Log.d(this, "adapter handleCreateConnectionComplete CANCELED %s", callId);
             // Tell telecomm to try a different service.
-            Log.d(this, "adapter handleCreateConnectionFailed %s", callId);
-            mAdapter.handleCreateConnectionFailed(
-                    callId,
-                    request,
-                    DisconnectCause.ERROR_UNSPECIFIED,
-                    null);
+            createdConnection = Connection.createCanceledConnection();
         }
+        connectionCreated(callId, request, createdConnection);
     }
 
     private void connectionCreated(
             String callId,
             ConnectionRequest request,
             Connection connection) {
-        addConnection(callId, connection);
+        if (!(connection instanceof Connection.FailureSignalingConnection)) {
+            addConnection(callId, connection);
+        }
+
         Uri handle = connection.getHandle();
         String number = handle == null ? "null" : handle.getSchemeSpecificPart();
         Log.v(this, "connectionCreated, parcelableconnection: %s, %d, %s",
@@ -583,7 +528,7 @@
                 PhoneCapabilities.toString(connection.getCallCapabilities()));
 
         Log.d(this, "adapter handleCreateConnectionSuccessful %s", callId);
-        mAdapter.handleCreateConnectionSuccessful(
+        mAdapter.handleCreateConnectionComplete(
                 callId,
                 request,
                 new ParcelableConnection(
@@ -599,7 +544,9 @@
                         connection.getVideoState(),
                         connection.isRequestingRingback(),
                         connection.getAudioModeIsVoip(),
-                        connection.getStatusHints()));
+                        connection.getStatusHints(),
+                        connection.getFailureCode(),
+                        connection.getFailureMessage()));
     }
 
     private void abort(String callId) {
@@ -699,7 +646,8 @@
                     final List<ComponentName> componentNames,
                     final List<IBinder> services) {
                 mHandler.post(new Runnable() {
-                    @Override public void run() {
+                    @Override
+                    public void run() {
                         for (int i = 0; i < componentNames.size() && i < services.size(); i++) {
                             mRemoteConnectionManager.addConnectionService(
                                     componentNames.get(i),
@@ -714,7 +662,8 @@
             @Override
             public void onError() {
                 mHandler.post(new Runnable() {
-                    @Override public void run() {
+                    @Override
+                    public void run() {
                         mAreAccountsInitialized = true;
                     }
                 });
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
index 0188e62..41c6360 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
@@ -76,37 +76,13 @@
         }
     }
 
-    void handleCreateConnectionSuccessful(
+    void handleCreateConnectionComplete(
             String id,
             ConnectionRequest request,
             ParcelableConnection connection) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.handleCreateConnectionSuccessful(id, request, connection);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    void handleCreateConnectionFailed(
-            String id,
-            ConnectionRequest request,
-            int errorCode,
-            String errorMsg) {
-        for (IConnectionServiceAdapter adapter : mAdapters) {
-            try {
-                adapter.handleCreateConnectionFailed(id, request, errorCode, errorMsg);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    void handleCreateConnectionCancelled(
-            String id,
-            ConnectionRequest request) {
-        for (IConnectionServiceAdapter adapter : mAdapters) {
-            try {
-                adapter.handleCreateConnectionCancelled(id, request);
+                adapter.handleCreateConnectionComplete(id, request, connection);
             } catch (RemoteException e) {
             }
         }
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
index 2654ace..0e1c516 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
@@ -38,29 +38,27 @@
  * @hide
  */
 final class ConnectionServiceAdapterServant {
-    private static final int MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL = 1;
-    private static final int MSG_HANDLE_CREATE_CONNECTION_FAILED = 2;
-    private static final int MSG_HANDLE_CREATE_CONNECTION_CANCELLED = 3;
-    private static final int MSG_SET_ACTIVE = 4;
-    private static final int MSG_SET_RINGING = 5;
-    private static final int MSG_SET_DIALING = 6;
-    private static final int MSG_SET_DISCONNECTED = 7;
-    private static final int MSG_SET_ON_HOLD = 8;
-    private static final int MSG_SET_REQUESTING_RINGBACK = 9;
-    private static final int MSG_SET_CALL_CAPABILITIES = 10;
-    private static final int MSG_SET_IS_CONFERENCED = 11;
-    private static final int MSG_ADD_CONFERENCE_CALL = 12;
-    private static final int MSG_REMOVE_CALL = 13;
-    private static final int MSG_ON_POST_DIAL_WAIT = 14;
-    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 15;
-    private static final int MSG_SET_VIDEO_STATE = 16;
-    private static final int MSG_SET_VIDEO_CALL_PROVIDER = 17;
-    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 18;
-    private static final int MSG_SET_STATUS_HINTS = 19;
-    private static final int MSG_SET_HANDLE = 20;
-    private static final int MSG_SET_CALLER_DISPLAY_NAME = 21;
-    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 22;
-    private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 23;
+    private static final int MSG_HANDLE_CREATE_CONNECTION_COMPLETE = 1;
+    private static final int MSG_SET_ACTIVE = 2;
+    private static final int MSG_SET_RINGING = 3;
+    private static final int MSG_SET_DIALING = 4;
+    private static final int MSG_SET_DISCONNECTED = 5;
+    private static final int MSG_SET_ON_HOLD = 6;
+    private static final int MSG_SET_REQUESTING_RINGBACK = 7;
+    private static final int MSG_SET_CALL_CAPABILITIES = 8;
+    private static final int MSG_SET_IS_CONFERENCED = 9;
+    private static final int MSG_ADD_CONFERENCE_CALL = 10;
+    private static final int MSG_REMOVE_CALL = 11;
+    private static final int MSG_ON_POST_DIAL_WAIT = 12;
+    private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 13;
+    private static final int MSG_SET_VIDEO_STATE = 14;
+    private static final int MSG_SET_VIDEO_CALL_PROVIDER = 15;
+    private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 16;
+    private static final int MSG_SET_STATUS_HINTS = 17;
+    private static final int MSG_SET_HANDLE = 18;
+    private static final int MSG_SET_CALLER_DISPLAY_NAME = 19;
+    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 20;
+    private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 21;
 
     private final IConnectionServiceAdapter mDelegate;
 
@@ -76,10 +74,10 @@
         // Internal method defined to centralize handling of RemoteException
         private void internalHandleMessage(Message msg) throws RemoteException {
             switch (msg.what) {
-                case MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL: {
+                case MSG_HANDLE_CREATE_CONNECTION_COMPLETE: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.handleCreateConnectionSuccessful(
+                        mDelegate.handleCreateConnectionComplete(
                                 (String) args.arg1,
                                 (ConnectionRequest) args.arg2,
                                 (ParcelableConnection) args.arg3);
@@ -88,30 +86,6 @@
                     }
                     break;
                 }
-                case MSG_HANDLE_CREATE_CONNECTION_FAILED: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        mDelegate.handleCreateConnectionFailed(
-                                (String) args.arg1,
-                                (ConnectionRequest) args.arg2,
-                                args.argi1,
-                                (String) args.arg3);
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
-                case MSG_HANDLE_CREATE_CONNECTION_CANCELLED: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        mDelegate.handleCreateConnectionCancelled(
-                                (String) args.arg1,
-                                (ConnectionRequest) args.arg2);
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                }
                 case MSG_SET_ACTIVE:
                     mDelegate.setActive((String) msg.obj);
                     break;
@@ -244,7 +218,7 @@
 
     private final IConnectionServiceAdapter mStub = new IConnectionServiceAdapter.Stub() {
         @Override
-        public void handleCreateConnectionSuccessful(
+        public void handleCreateConnectionComplete(
                 String id,
                 ConnectionRequest request,
                 ParcelableConnection connection) {
@@ -252,31 +226,7 @@
             args.arg1 = id;
             args.arg2 = request;
             args.arg3 = connection;
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_SUCCESSFUL, args).sendToTarget();
-        }
-
-        @Override
-        public void handleCreateConnectionFailed(
-                String id,
-                ConnectionRequest request,
-                int errorCode,
-                String errorMessage) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = id;
-            args.arg2 = request;
-            args.argi1 = errorCode;
-            args.arg3 = errorMessage;
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_FAILED, args).sendToTarget();
-        }
-
-        @Override
-        public void handleCreateConnectionCancelled(
-                String id,
-                ConnectionRequest request) {
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = id;
-            args.arg2 = request;
-            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_CANCELLED, args).sendToTarget();
+            mHandler.obtainMessage(MSG_HANDLE_CREATE_CONNECTION_COMPLETE, args).sendToTarget();
         }
 
         @Override
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java
index 7a87b87..30ff5be 100644
--- a/telecomm/java/android/telecomm/ParcelableConnection.java
+++ b/telecomm/java/android/telecomm/ParcelableConnection.java
@@ -41,6 +41,8 @@
     private boolean mRequestingRingback;
     private boolean mAudioModeIsVoip;
     private StatusHints mStatusHints;
+    private int mFailureCode;
+    private String mFailureMessage;
 
     /** @hide */
     public ParcelableConnection(
@@ -55,7 +57,9 @@
             int videoState,
             boolean requestingRingback,
             boolean audioModeIsVoip,
-            StatusHints statusHints) {
+            StatusHints statusHints,
+            int failureCode,
+            String failureMessage) {
         mPhoneAccount = phoneAccount;
         mState = state;
         mCapabilities = capabilities;
@@ -68,6 +72,8 @@
         mRequestingRingback = requestingRingback;
         mAudioModeIsVoip = audioModeIsVoip;
         mStatusHints = statusHints;
+        mFailureCode = failureCode;
+        mFailureMessage = failureMessage;
     }
 
     public PhoneAccountHandle getPhoneAccount() {
@@ -119,6 +125,14 @@
         return mStatusHints;
     }
 
+    public final int getFailureCode() {
+        return mFailureCode;
+    }
+
+    public final String getFailureMessage() {
+        return mFailureMessage;
+    }
+
     @Override
     public String toString() {
         return new StringBuilder()
@@ -150,6 +164,8 @@
             boolean requestingRingback = source.readByte() == 1;
             boolean audioModeIsVoip = source.readByte() == 1;
             StatusHints statusHints = source.readParcelable(classLoader);
+            int disconnectCauseCode = source.readInt();
+            String disconnectCauseMessage = source.readString();
 
             return new ParcelableConnection(
                     phoneAccount,
@@ -163,7 +179,9 @@
                     videoState,
                     requestingRingback,
                     audioModeIsVoip,
-                    statusHints);
+                    statusHints,
+                    disconnectCauseCode,
+                    disconnectCauseMessage);
         }
 
         @Override
@@ -194,5 +212,7 @@
         destination.writeByte((byte) (mRequestingRingback ? 1 : 0));
         destination.writeByte((byte) (mAudioModeIsVoip ? 1 : 0));
         destination.writeParcelable(mStatusHints, 0);
+        destination.writeInt(mFailureCode);
+        destination.writeString(mFailureMessage);
     }
 }
diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java
index f1cee10..30cfdde 100644
--- a/telecomm/java/android/telecomm/RemoteConnection.java
+++ b/telecomm/java/android/telecomm/RemoteConnection.java
@@ -233,9 +233,9 @@
     RemoteConnection(int failureCode, String failureMessage) {
         this("NULL", null, null);
         mConnected = false;
-        mState = Connection.STATE_FAILED;
-        mFailureCode = failureCode;
-        mFailureMessage = failureMessage;
+        mState = Connection.STATE_DISCONNECTED;
+        mFailureCode = DisconnectCause.OUTGOING_FAILURE;
+        mFailureMessage = failureMessage + " original code = " + failureCode;
     }
 
     /**
@@ -675,8 +675,9 @@
     }
 
     /**
-     * Create a RemoteConnection which is in the {@link Connection#STATE_FAILED} state. Attempting
-     * to use it for anything will almost certainly result in bad things happening. Do not do this.
+     * Create a RemoteConnection represents a failure, and which will be in
+     * {@link Connection#STATE_DISCONNECTED}. Attempting to use it for anything will almost
+     * certainly result in bad things happening. Do not do this.
      *
      * @return a failed {@link RemoteConnection}
      *
diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java
index dedb10e..541df4e 100644
--- a/telecomm/java/android/telecomm/RemoteConnectionService.java
+++ b/telecomm/java/android/telecomm/RemoteConnectionService.java
@@ -48,7 +48,7 @@
 
     private final IConnectionServiceAdapter mServantDelegate = new IConnectionServiceAdapter() {
         @Override
-        public void handleCreateConnectionSuccessful(
+        public void handleCreateConnectionComplete(
                 String id,
                 ConnectionRequest request,
                 ParcelableConnection parcel) {
@@ -56,6 +56,7 @@
                     findConnectionForAction(id, "handleCreateConnectionSuccessful");
             if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
                 mPendingConnections.remove(connection);
+                // Unconditionally initialize the connection ...
                 connection.setState(parcel.getState());
                 connection.setCallCapabilities(parcel.getCapabilities());
                 connection.setHandle(
@@ -64,29 +65,15 @@
                         parcel.getCallerDisplayName(),
                         parcel.getCallerDisplayNamePresentation());
                 // TODO: Do we need to support video providers for remote connections?
+                if (connection.getState() == Connection.STATE_DISCONNECTED) {
+                    // ... then, if it was created in a disconnected state, that indicates
+                    // failure on the providing end, so immediately mark it destroyed
+                    connection.setDestroyed();
+                }
             }
         }
 
         @Override
-        public void handleCreateConnectionFailed(
-                String id,
-                ConnectionRequest request,
-                int errorCode,
-                String errorMessage) {
-            // TODO: How do we propagate the failure codes?
-            findConnectionForAction(id, "handleCreateConnectionFailed")
-                    .setDestroyed();
-        }
-
-        @Override
-        public void handleCreateConnectionCancelled(
-                String id,
-                ConnectionRequest request) {
-            findConnectionForAction(id, "handleCreateConnectionCancelled")
-                    .setDestroyed();
-        }
-
-        @Override
         public void setActive(String callId) {
             findConnectionForAction(callId, "setActive")
                     .setState(Connection.STATE_ACTIVE);
diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
index e6ebae5..ef1769f 100644
--- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
@@ -34,20 +34,11 @@
  * {@hide}
  */
 oneway interface IConnectionServiceAdapter {
-    void handleCreateConnectionSuccessful(
+    void handleCreateConnectionComplete(
             String callId,
             in ConnectionRequest request,
             in ParcelableConnection connection);
 
-    void handleCreateConnectionFailed(
-            String callId,
-            in ConnectionRequest request,
-            int errorCode, String errorMessage);
-
-    void handleCreateConnectionCancelled(
-            String callId,
-            in ConnectionRequest request);
-
     void setActive(String callId);
 
     void setRinging(String callId);