Add additional call state PRE_DIAL_WAIT for selection of account

If an account default is not set, the incall ui will display a dialog to
allow the user to select an account for that particular call.

Bug: 16243703

Change-Id: If1beaf60a92b4446adaaace2a72c3e0f70e61f21
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index b830499..5dfba52 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -431,6 +431,10 @@
         return mPhoneAccount;
     }
 
+    void setPhoneAccount(PhoneAccount account) {
+        mPhoneAccount = account;
+    }
+
     boolean isIncoming() {
         return mIsIncoming;
     }
@@ -641,7 +645,7 @@
      * Attempts to disconnect the call through the connection service.
      */
     void disconnect() {
-        if (mState == CallState.NEW) {
+        if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT) {
             Log.v(this, "Aborting call %s", this);
             abort();
         } else if (mState != CallState.ABORTED && mState != CallState.DISCONNECTED) {
@@ -658,6 +662,8 @@
     void abort() {
         if (mCreateConnectionProcessor != null) {
             mCreateConnectionProcessor.abort();
+        } else if (mState == CallState.PRE_DIAL_WAIT) {
+            handleCreateConnectionFailed(DisconnectCause.LOCAL, null);
         }
     }
 
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 36f8cea..8265b20 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -62,6 +62,9 @@
 
     private static final CallsManager INSTANCE = new CallsManager();
 
+    /** Temporary flag for disabling account selection menu */
+    public static final boolean ENABLE_ACCOUNT_SELECT = true;
+
     /**
      * The main call repository. Keeps an instance of all live calls. New incoming and outgoing
      * calls are added to the map and removed when the calls move to the disconnected state.
@@ -280,9 +283,8 @@
      * Attempts to issue/connect the specified call.
      *
      * @param handle Handle to connect the call with.
-     * @param contactInfo Information about the entity being called.
      * @param gatewayInfo Optional gateway information that can be used to route the call to the
-     *         actual dialed handle via a gateway provider. May be null.
+     *        actual dialed handle via a gateway provider. May be null.
      * @param speakerphoneOn Whether or not to turn the speakerphone on once the call connects.
      * @param videoState The desired video state for the outgoing call.
      */
@@ -311,6 +313,13 @@
         // TODO(santoscordon): Move this to be a part of addCall()
         call.addListener(this);
         addCall(call);
+
+        // TODO: check for default account
+        if (account == null && ENABLE_ACCOUNT_SELECT) {
+            call.setState(CallState.PRE_DIAL_WAIT);
+            return;
+        }
+
         call.startCreateConnection();
     }
 
@@ -480,6 +489,15 @@
         }
     }
 
+    void phoneAccountSelected(Call call, PhoneAccount account) {
+        if (!mCalls.contains(call)) {
+            Log.i(this, "Attemped to add account to unknown call %s", call);
+        } else {
+            call.setPhoneAccount(account);
+            call.startCreateConnection();
+        }
+    }
+
     /** Called when the audio state changes. */
     void onAudioStateChanged(CallAudioState oldAudioState, CallAudioState newAudioState) {
         Log.v(this, "onAudioStateChanged, audioState: %s -> %s", oldAudioState, newAudioState);
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index 7db9325..161d4a4 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -18,6 +18,7 @@
 
 import android.os.Handler;
 import android.os.Message;
+import android.telecomm.PhoneAccount;
 
 import com.android.internal.os.SomeArgs;
 import com.android.internal.telecomm.IInCallAdapter;
@@ -42,6 +43,7 @@
     private static final int MSG_CONFERENCE = 11;
     private static final int MSG_SPLIT_FROM_CONFERENCE = 12;
     private static final int MSG_SWAP_WITH_BACKGROUND_CALL = 13;
+    private static final int MSG_PHONE_ACCOUNT_SELECTED = 14;
 
     private final class InCallAdapterHandler extends Handler {
         @Override
@@ -56,7 +58,7 @@
                         Log.w(this, "answerCall, unknown call id: %s", msg.obj);
                     }
                     break;
-                case MSG_REJECT_CALL:
+                case MSG_REJECT_CALL: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
                         call = mCallIdMapper.getCall(args.arg1);
@@ -71,6 +73,7 @@
                         args.recycle();
                     }
                     break;
+                }
                 case MSG_PLAY_DTMF_TONE:
                     call = mCallIdMapper.getCall(msg.obj);
                     if (call != null) {
@@ -129,6 +132,20 @@
                         Log.w(this, "phoneAccountClicked, unknown call id: %s", msg.obj);
                     }
                     break;
+                case MSG_PHONE_ACCOUNT_SELECTED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null) {
+                            mCallsManager.phoneAccountSelected(call, (PhoneAccount) args.arg2);
+                        } else {
+                            Log.w(this, "phoneAccountSelected, unknown call id: %s", args.arg1);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
                 case MSG_MUTE:
                     mCallsManager.mute(msg.arg1 == 1);
                     break;
@@ -142,7 +159,6 @@
                     } else {
                         Log.w(this, "conference, unknown call id: %s", msg.obj);
                     }
-
                     break;
                 case MSG_SPLIT_FROM_CONFERENCE:
                     call = mCallIdMapper.getCall(msg.obj);
@@ -240,6 +256,15 @@
     }
 
     @Override
+    public void phoneAccountSelected(String callId, PhoneAccount account) {
+        mCallIdMapper.checkValidCallId(callId);
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = callId;
+        args.arg2 = account;
+        mHandler.obtainMessage(MSG_PHONE_ACCOUNT_SELECTED, args).sendToTarget();
+    }
+
+    @Override
     public void mute(boolean shouldMute) {
         mHandler.obtainMessage(MSG_MUTE, shouldMute ? 1 : 0, 0).sendToTarget();
     }