Handle Call disconnect before connection

Make Call behave cleanly if it receives a request to disconnect
before a connection has been established.

Bug: 13936734

Change-Id: Id5e6bc289d36cba028f1ff101beef5ac33d3138f
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 2db5b4e..d0697ad 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -373,7 +373,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/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() {