Merge "Use ComponentName.flattenToShortString" into master-nova
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index b33f862..024d7d4 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -375,7 +375,9 @@
      */
     void disconnect() {
         if (mCallService == null) {
-            Log.w(this, "disconnect() request on a call without a call service.");
+            Log.d(this, "disconnect() request on a call without a call service.");
+            // In case this call is ringing, ensure we abort and clean up right away.
+            CallsManager.getInstance().abortCall(this);
         } else {
             Log.i(this, "Send disconnect to call service for call: %s", this);
             // The call isn't officially disconnected until the call service confirms that the call
diff --git a/src/com/android/telecomm/CallServiceSelectorAdapter.java b/src/com/android/telecomm/CallServiceSelectorAdapter.java
index 5c805c5..3fa3b10 100644
--- a/src/com/android/telecomm/CallServiceSelectorAdapter.java
+++ b/src/com/android/telecomm/CallServiceSelectorAdapter.java
@@ -32,9 +32,10 @@
  */
 public final class CallServiceSelectorAdapter extends ICallServiceSelectorAdapter.Stub {
     private static final int MSG_SET_SELECTED_CALL_SERVICES = 0;
-    private static final int MSG_SET_HANDOFF_INFO = 1;
+    private static final int MSG_CANCEL_OUTGOING_CALL = 1;
+    private static final int MSG_SET_HANDOFF_INFO = 2;
 
-    private final class CallServiceSelectorAdapaterHandler extends Handler {
+    private final class CallServiceSelectorAdapterHandler extends Handler {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -47,13 +48,23 @@
                         if (call != null) {
                             mOutgoingCallsManager.processSelectedCallServices(call, descriptors);
                         } else {
-                            Log.w(this, "Unknown call: %s, id: %s", call, args.arg1);
+                            Log.w(this, "setSelectedCallServices: unknown call: %s, id: %s",
+                                    call, args.arg1);
                         }
                     } finally {
                         args.recycle();
                     }
                     break;
                 }
+                case MSG_CANCEL_OUTGOING_CALL: {
+                    Call call = mCallIdMapper.getCall(msg.obj);
+                    if (call != null) {
+                        mOutgoingCallsManager.abort(call);
+                    } else {
+                        Log.w(this, "cancelOutgoingCall: unknown call: %s, id: %s", call, msg.obj);
+                    }
+                    break;
+                }
                 case MSG_SET_HANDOFF_INFO: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
@@ -63,7 +74,8 @@
                         if (call != null) {
                             mCallsManager.setHandoffInfo(call, handle, extras);
                         } else {
-                            Log.w(this, "Unknown call: %s, id: %s", call, args.arg1);
+                            Log.w(this, "setHandoffInfo: unknown call: %s, id: %s",
+                                    call, args.arg1);
                         }
                     } finally {
                         args.recycle();
@@ -74,7 +86,7 @@
         }
     }
 
-    private final Handler mHandler = new CallServiceSelectorAdapaterHandler();
+    private final Handler mHandler = new CallServiceSelectorAdapterHandler();
     private final CallsManager mCallsManager;
     private final OutgoingCallsManager mOutgoingCallsManager;
     private final CallIdMapper mCallIdMapper;
@@ -90,7 +102,7 @@
     }
 
     /**
-     * @see CallServiceSelectorAdapater#setSelectedCallServices(String,List<CallServiceDescriptor>)
+     * @see CallServiceSelectorAdapter#setSelectedCallServices(String,List<CallServiceDescriptor>)
      */
     @Override
     public void setSelectedCallServices(String callId, List<CallServiceDescriptor> descriptors) {
@@ -101,7 +113,14 @@
         mHandler.obtainMessage(MSG_SET_SELECTED_CALL_SERVICES, args).sendToTarget();
     }
 
-    /** @see CallServiceSelectorAdapater#setHandoffInfo(String,Uri,Bundle) */
+    /** @see CallServiceSelectorAdapter#cancelOutgoingCall(String) */
+    @Override
+    public void cancelOutgoingCall(String callId) {
+        mCallIdMapper.checkValidCallId(callId);
+        mHandler.obtainMessage(MSG_CANCEL_OUTGOING_CALL, callId).sendToTarget();
+    }
+
+    /** @see CallServiceSelectorAdapter#setHandoffInfo(String,Uri,Bundle) */
     @Override
     public void setHandoffInfo(String callId, Uri handle, Bundle extras) {
         mCallIdMapper.checkValidCallId(callId);
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 93316ed..81243a9 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -394,6 +394,18 @@
         }
     }
 
+    /**
+     * Instructs Telecomm to abort any outgoing state of the specified call.
+     */
+    void abortCall(Call call) {
+        if (!mCalls.contains(call)) {
+            Log.w(this, "Unknown call (%s) asked to be aborted", call);
+        } else {
+            Log.d(this, "Aborting call: (%s)", call);
+            mSwitchboard.abortCall(call);
+        }
+    }
+
     /** Called by the in-call UI to change the mute state. */
     void mute(boolean shouldMute) {
         mCallAudioManager.mute(shouldMute);
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index bd6b449..fdc271e 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -252,6 +252,16 @@
     }
 
     /**
+     * Ensures any state regarding a call is cleaned up.
+     *
+     * @param call The call.
+     */
+    void abortCall(Call call) {
+        Log.d(this, "abortCall");
+        mOutgoingCallsManager.abort(call);
+    }
+
+    /**
      * @return True if ticking should continue (or be resumed) and false otherwise.
      */
     private boolean isTicking() {