Add setConferenceable() API from ConnectionService to incall. (2/4)

Change-Id: I64fdca08d35f893d755e3b154543a261b1418343
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index d6373a1..b72f383 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -22,10 +22,12 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.telecomm.CallCapabilities;
 import android.telecomm.CallPropertyPresentation;
 import android.telecomm.CallState;
 import android.telecomm.Connection;
 import android.telecomm.ConnectionRequest;
+import android.telecomm.ConnectionService.VideoCallProvider;
 import android.telecomm.GatewayInfo;
 import android.telecomm.ParcelableConnection;
 import android.telecomm.PhoneAccount;
@@ -44,6 +46,7 @@
 import com.android.telecomm.ContactsAsyncHelper.OnImageLoadCompleteListener;
 import com.google.common.base.Preconditions;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -85,6 +88,8 @@
         void onStartActivityFromInCall(Call call, PendingIntent intent);
         void onTargetPhoneAccountChanged(Call call);
         void onConnectionManagerPhoneAccountChanged(Call call);
+        void onPhoneAccountChanged(Call call);
+        void onConferenceableCallsChanged(Call call);
     }
 
     abstract static class ListenerBase implements Listener {
@@ -134,6 +139,10 @@
         public void onTargetPhoneAccountChanged(Call call) {}
         @Override
         public void onConnectionManagerPhoneAccountChanged(Call call) {}
+        @Override
+        public void onPhoneAccountChanged(Call call) {}
+        @Override
+        public void onConferenceableCallsChanged(Call call) {}
     }
 
     private static final OnQueryCompleteListener sCallerInfoQueryListener =
@@ -187,6 +196,10 @@
 
     private final Handler mHandler = new Handler();
 
+    private final List<Call> mConferenceableCalls = new ArrayList<>();
+
+    private PhoneAccountHandle mPhoneAccountHandle;
+
     private long mConnectTimeMillis;
 
     /** The state of the call. */
@@ -312,7 +325,8 @@
     }
 
     /** {@inheritDoc} */
-    @Override public String toString() {
+    @Override
+    public String toString() {
         String component = null;
         if (mConnectionService != null && mConnectionService.getComponentName() != null) {
             component = mConnectionService.getComponentName().flattenToShortString();
@@ -513,8 +527,9 @@
     }
 
     void setCallCapabilities(int callCapabilities) {
+        Log.v(this, "setCallCapabilities: %s", CallCapabilities.toString(callCapabilities));
         if (mCallCapabilities != callCapabilities) {
-            mCallCapabilities = callCapabilities;
+           mCallCapabilities = callCapabilities;
             for (Listener l : mListeners) {
                 l.onCallCapabilitiesChanged(this);
             }
@@ -597,6 +612,7 @@
     @Override
     public void handleCreateConnectionSuccessful(
             ConnectionRequest request, ParcelableConnection connection) {
+        Log.v(this, "handleCreateConnectionSuccessful %s", connection);
         mCreateConnectionProcessor = null;
         setState(getStateFromConnectionState(connection.getState()));
         setTargetPhoneAccount(connection.getPhoneAccount());
@@ -869,6 +885,15 @@
         }
     }
 
+    void setConferenceableCalls(List<Call> conferenceableCalls) {
+        mConferenceableCalls.clear();
+        mConferenceableCalls.addAll(conferenceableCalls);
+    }
+
+    List<Call> getConferenceableCalls() {
+        return mConferenceableCalls;
+    }
+
     private void addChildCall(Call call) {
         if (!mChildCalls.contains(call)) {
             mChildCalls.add(call);
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 5ce9fe8..de7fbc4 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -357,9 +357,10 @@
     /**
      * Attempts to start a conference call for the specified call.
      *
-     * @param call The call to conference with.
+     * @param call The call to conference.
+     * @param otherCall The other call to conference with.
      */
-    void conference(Call call) {
+    void conference(Call call, Call otherCall) {
         Call conferenceCall = new Call(
                 mConnectionServiceRepository,
                 null /* handle */,
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index 82381bd..4a45902 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -79,7 +79,8 @@
     private static final int MSG_SET_HANDLE = 19;
     private static final int MSG_SET_CALLER_DISPLAY_NAME = 20;
     private static final int MSG_SET_VIDEO_STATE = 21;
-    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 22;
+    private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 22;
+    private static final int MSG_START_ACTIVITY_FROM_IN_CALL = 23;
 
     private final Handler mHandler = new Handler() {
         @Override
@@ -314,6 +315,28 @@
                     }
                     break;
                 }
+                case MSG_SET_CONFERENCEABLE_CONNECTIONS: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        if (call != null ){
+                            @SuppressWarnings("unchecked")
+                            List<String> conferenceableIds = (List<String>) args.arg2;
+                            List<Call> conferenceableCalls =
+                                    new ArrayList<>(conferenceableIds.size());
+                            for (String otherId : (List<String>) args.arg2) {
+                                Call otherCall = mCallIdMapper.getCall(otherId);
+                                if (otherCall != null && otherCall != call) {
+                                    conferenceableCalls.add(otherCall);
+                                }
+                            }
+                            call.setConferenceableCalls(conferenceableCalls);
+                        }
+                    } finally {
+                        args.recycle();
+                    }
+                    break;
+                }
                 case MSG_START_ACTIVITY_FROM_IN_CALL: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
@@ -513,6 +536,17 @@
         }
 
         @Override
+        public void setConferenceableConnections(
+                String callId, List<String> conferenceableCallIds) {
+            logIncoming("setConferenceableConnections %s %s", callId, conferenceableCallIds);
+            mCallIdMapper.checkValidCallId(callId);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = callId;
+            args.arg2 = conferenceableCallIds;
+            mHandler.obtainMessage(MSG_SET_CONFERENCEABLE_CONNECTIONS, args).sendToTarget();
+        }
+
+        @Override
         public void startActivityFromInCall(String callId, PendingIntent intent) {
             logIncoming("startActivityFromInCall %s %s", callId, intent);
             mCallIdMapper.checkValidCallId(callId);
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index 0acb3f5..0e6c9df 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -161,14 +161,21 @@
                 case MSG_SET_AUDIO_ROUTE:
                     mCallsManager.setAudioRoute(msg.arg1);
                     break;
-                case MSG_CONFERENCE:
-                    call = mCallIdMapper.getCall(msg.obj);
-                    if (call != null) {
-                        mCallsManager.conference(call);
-                    } else {
-                        Log.w(this, "conference, unknown call id: %s", msg.obj);
+                case MSG_CONFERENCE: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    try {
+                        call = mCallIdMapper.getCall(args.arg1);
+                        Call otherCall = mCallIdMapper.getCall(args.arg2);
+                        if (call != null && otherCall != null) {
+                            mCallsManager.conference(call, otherCall);
+                        } else {
+                            Log.w(this, "conference, unknown call id: %s", msg.obj);
+                        }
+                    } finally {
+                        args.recycle();
                     }
                     break;
+                }
                 case MSG_SPLIT_FROM_CONFERENCE:
                     call = mCallIdMapper.getCall(msg.obj);
                     if (call != null) {
@@ -293,8 +300,11 @@
     }
 
     @Override
-    public void conference(String callId) {
-        mHandler.obtainMessage(MSG_CONFERENCE, callId).sendToTarget();
+    public void conference(String callId, String otherCallId) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = callId;
+        args.arg2 = otherCallId;
+        mHandler.obtainMessage(MSG_CONFERENCE, args).sendToTarget();
     }
 
     @Override
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index e12372d..6b4b424 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -112,6 +112,11 @@
         public void onTargetPhoneAccountChanged(Call call) {
             updateCall(call);
         }
+
+        @Override
+        public void onConferenceableCallsChanged(Call call) {
+            updateCall(call);
+        }
     };
 
     /** Maintains a binding connection to the in-call app. */
@@ -336,6 +341,15 @@
         String callerDisplayName = call.getCallerDisplayNamePresentation() ==
                 CallPropertyPresentation.ALLOWED ?  call.getCallerDisplayName() : null;
 
+        List<Call> conferenceableCalls = call.getConferenceableCalls();
+        List<String> conferenceableCallIds = new ArrayList<String>(conferenceableCalls.size());
+        for (Call otherCall : conferenceableCalls) {
+            String otherId = mCallIdMapper.getCallId(otherCall);
+            if (otherId != null) {
+                conferenceableCallIds.add(otherId);
+            }
+        }
+
         return new ParcelableCall(
                 callId,
                 state,
@@ -354,6 +368,7 @@
                 parentCallId,
                 childCallIds,
                 call.getStatusHints(),
-                call.getVideoState());
+                call.getVideoState(),
+                conferenceableCallIds);
     }
 }