Creating connections for conference event package participants.

- Add "addExistingCall" method to Connection service wrapper to handle
the creation of new calls for connections which already exist in telephony.
- Fixed but in setIsConference message where an isValidCallId check made
outside of the handler would result in a newly added call NOT being
marked as conferenced due to a race condition.  The MSG_SET_IS_CONFERENCED
handler already checks if the call exists before performing its operation.

Bug: 18057361
Change-Id: I2348c8e6985cd831f2cae56b37dfcb33bae014a8
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 86d9f01..300f4fa 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -28,6 +28,7 @@
 import android.telecom.DisconnectCause;
 import android.telecom.GatewayInfo;
 import android.telecom.ParcelableConference;
+import android.telecom.ParcelableConnection;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.PhoneCapabilities;
@@ -1225,6 +1226,36 @@
     }
 
     /**
+     * Creates a new call for an existing connection.
+     *
+     * @param callId The id of the new call.
+     * @param connection The connection information.
+     * @return The new call.
+     */
+    Call createCallForExistingConnection(String callId, ParcelableConnection connection) {
+        Call call = new Call(
+                mContext,
+                mConnectionServiceRepository,
+                connection.getHandle() /* handle */,
+                null /* gatewayInfo */,
+                null /* connectionManagerPhoneAccount */,
+                connection.getPhoneAccount(), /* targetPhoneAccountHandle */
+                false /* isIncoming */,
+                false /* isConference */);
+
+        setCallState(call, Call.getStateFromConnectionState(connection.getState()));
+        call.setConnectTimeMillis(System.currentTimeMillis());
+        call.setCallCapabilities(connection.getCapabilities());
+        call.setCallerDisplayName(connection.getCallerDisplayName(),
+                connection.getCallerDisplayNamePresentation());
+
+        call.addListener(this);
+        addCall(call);
+
+        return call;
+    }
+
+    /**
      * Dumps the state of the {@link CallsManager}.
      *
      * @param pw The {@code IndentingPrintWriter} to write the state to.
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 32c6107..cb7a1fe 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -80,6 +80,7 @@
     private static final int MSG_SET_CALLER_DISPLAY_NAME = 18;
     private static final int MSG_SET_VIDEO_STATE = 19;
     private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20;
+    private static final int MSG_ADD_EXISTING_CONNECTION = 21;
 
     private final Handler mHandler = new Handler() {
         @Override
@@ -350,6 +351,19 @@
                     }
                     break;
                 }
+                case MSG_ADD_EXISTING_CONNECTION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        String callId = (String)args.arg1;
+                        ParcelableConnection connection = (ParcelableConnection)args.arg2;
+                        Call existingCall = mCallsManager.createCallForExistingConnection(callId,
+                                connection);
+                        mCallIdMapper.addCall(existingCall, callId);
+                        existingCall.setConnectionService(ConnectionServiceWrapper.this);
+                    } finally {
+                        args.recycle();
+                    }
+                }
             }
         }
     };
@@ -458,12 +472,10 @@
         @Override
         public void setIsConferenced(String callId, String conferenceCallId) {
             logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
-            if (mCallIdMapper.isValidCallId(callId)) {
-                SomeArgs args = SomeArgs.obtain();
-                args.arg1 = callId;
-                args.arg2 = conferenceCallId;
-                mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
-            }
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = conferenceCallId;
+            mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
         }
 
         @Override
@@ -558,6 +570,15 @@
                 mHandler.obtainMessage(MSG_SET_CONFERENCEABLE_CONNECTIONS, args).sendToTarget();
             }
         }
+
+        @Override
+        public void addExistingConnection(String callId, ParcelableConnection connection) {
+            logIncoming("addExistingConnection  %s %s", callId, connection);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = connection;
+            mHandler.obtainMessage(MSG_ADD_EXISTING_CONNECTION, args).sendToTarget();
+        }
     }
 
     private final Adapter mAdapter = new Adapter();