Support conference calling. (2/4) [DO NOT MERGE]

Bug: 15006702
Change-Id: I2764ea242f783ba478c9eae86618dd33e9fc792a
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index c3aa950..7be1baa 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -33,6 +33,10 @@
 import com.android.internal.telecomm.IInCallService;
 import com.google.common.collect.ImmutableCollection;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Binds to {@link IInCallService} and provides the service to {@link CallsManager} through which it
  * can send updates to the in-call app. This class is created and owned by CallsManager and retains
@@ -152,6 +156,17 @@
         }
     }
 
+    @Override
+    public void onIsConferenceCapableChanged(Call call, boolean isConferenceCapable) {
+        updateCall(call);
+    }
+
+    @Override
+    public void onIsConferencedChanged(Call call) {
+        Log.v(this, "onIsConferencedChanged %s", call);
+        updateCall(call);
+    }
+
     void bringToForeground(boolean showDialpad) {
         if (mInCallService != null) {
             try {
@@ -241,7 +256,9 @@
     private void updateCall(Call call) {
         if (mInCallService != null) {
             try {
-                mInCallService.updateCall(toInCallCall(call));
+                InCallCall inCallCall = toInCallCall(call);
+                Log.v(this, "updateCall %s ==> %s", call, inCallCall);
+                mInCallService.updateCall(inCallCall);
             } catch (RemoteException ignored) {
             }
         }
@@ -257,6 +274,9 @@
         if (call.getHandoffHandle() != null) {
             capabilities |= CallCapabilities.CONNECTION_HANDOFF;
         }
+        if (call.isConferenceCapable()) {
+            capabilities |= CallCapabilities.MERGE_CALLS;
+        }
         CallState state = call.getState();
         if (state == CallState.ABORTED) {
             state = CallState.DISCONNECTED;
@@ -265,8 +285,26 @@
         if (state == CallState.DISCONNECTED && call.getHandoffCallServiceDescriptor() != null) {
             state = CallState.ACTIVE;
         }
+
+        String parentCallId = null;
+        Call parentCall = call.getParentCall();
+        if (parentCall != null) {
+            parentCallId = mCallIdMapper.getCallId(parentCall);
+        }
+
+        long connectTimeMillis = call.getConnectTimeMillis();
+        List<Call> childCalls = call.getChildCalls();
+        List<String> childCallIds = new ArrayList<>();
+        if (!childCalls.isEmpty()) {
+            connectTimeMillis = Long.MAX_VALUE;
+            for (Call child : childCalls) {
+                connectTimeMillis = Math.min(child.getConnectTimeMillis(), connectTimeMillis);
+                childCallIds.add(mCallIdMapper.getCallId(child));
+            }
+        }
+
         return new InCallCall(callId, state, call.getDisconnectCause(), call.getDisconnectMessage(),
-                capabilities, call.getConnectTimeMillis(), call.getHandle(), call.getGatewayInfo(),
-                descriptor, call.getHandoffCallServiceDescriptor());
+                capabilities, connectTimeMillis, call.getHandle(), call.getGatewayInfo(),
+                descriptor, call.getHandoffCallServiceDescriptor(), parentCallId, childCallIds);
     }
 }