Merge "Hide/show Telephony video setting according to if IMS is enabled." into lmp-mr1-dev
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index 3242e64..779cb70 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -160,6 +160,9 @@
         if (mAllowMute) {
             capabilities |= PhoneCapabilities.MUTE;
         }
+        if (getConference() == null) {
+            capabilities |= PhoneCapabilities.ADD_CALL;
+        }
         return capabilities;
     }
 
diff --git a/src/com/android/services/telephony/GsmConnection.java b/src/com/android/services/telephony/GsmConnection.java
index da03fa1..1632457 100644
--- a/src/com/android/services/telephony/GsmConnection.java
+++ b/src/com/android/services/telephony/GsmConnection.java
@@ -65,6 +65,7 @@
     @Override
     protected int buildCallCapabilities() {
         int capabilities = super.buildCallCapabilities();
+        capabilities |= PhoneCapabilities.ADD_CALL;
         capabilities |= PhoneCapabilities.MUTE;
         capabilities |= PhoneCapabilities.SUPPORT_HOLD;
         if (getState() == STATE_ACTIVE || getState() == STATE_HOLDING) {
diff --git a/src/com/android/services/telephony/TelephonyConference.java b/src/com/android/services/telephony/TelephonyConference.java
index b493523..fdb7261 100644
--- a/src/com/android/services/telephony/TelephonyConference.java
+++ b/src/com/android/services/telephony/TelephonyConference.java
@@ -36,6 +36,7 @@
     public TelephonyConference(PhoneAccountHandle phoneAccount) {
         super(phoneAccount);
         setCapabilities(
+                PhoneCapabilities.ADD_CALL |
                 PhoneCapabilities.SUPPORT_HOLD |
                 PhoneCapabilities.HOLD |
                 PhoneCapabilities.MUTE |
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index f508f30..b8d3142 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -263,12 +263,17 @@
     @Override
     public void onConferenceChanged() {
         Conference conference = getConference();
-        // If the conference was an IMS connection but is no longer, disable conference management.
-        if (conference != null && mWasImsConnection && !isImsConnection()) {
-            int oldCapabilities = conference.getCapabilities();
-            if(PhoneCapabilities.can(oldCapabilities, PhoneCapabilities.MANAGE_CONFERENCE)) {
-                int newCapabilities = PhoneCapabilities.remove(
-                        oldCapabilities, PhoneCapabilities.MANAGE_CONFERENCE);
+        if (conference == null) {
+            return;
+        }
+
+        // If the conference was an IMS connection currently or before, disable MANAGE_CONFERENCE
+        // as the default behavior. If there is a conference event package, this may be overridden.
+        if (mWasImsConnection) {
+            int capabilities = conference.getCapabilities();
+            if (PhoneCapabilities.can(capabilities, PhoneCapabilities.MANAGE_CONFERENCE)) {
+                int newCapabilities =
+                        PhoneCapabilities.remove(capabilities, PhoneCapabilities.MANAGE_CONFERENCE);
                 conference.setCapabilities(newCapabilities);
             }
         }
@@ -348,6 +353,7 @@
     protected int buildCallCapabilities() {
         int callCapabilities = 0;
         if (isImsConnection()) {
+            callCapabilities |= PhoneCapabilities.ADD_CALL;
             callCapabilities |= PhoneCapabilities.SUPPORT_HOLD;
             if (getState() == STATE_ACTIVE || getState() == STATE_HOLDING) {
                 callCapabilities |= PhoneCapabilities.HOLD;
@@ -532,7 +538,7 @@
                 case IDLE:
                     break;
                 case ACTIVE:
-                    setActive();
+                    setActiveInternal();
                     break;
                 case HOLDING:
                     setOnHold();
@@ -558,6 +564,31 @@
         updateAddress();
     }
 
+    private void setActiveInternal() {
+        if (getState() == STATE_ACTIVE) {
+            Log.w(this, "Should not be called if this is already ACTIVE");
+            return;
+        }
+
+        // When we set a call to active, we need to make sure that there are no other active
+        // calls. However, the ordering of state updates to connections can be non-deterministic
+        // since all connections register for state changes on the phone independently.
+        // To "optimize", we check here to see if there already exists any active calls.  If so,
+        // we issue an update for those calls first to make sure we only have one top-level
+        // active call.
+        if (getConnectionService() != null) {
+            for (Connection current : getConnectionService().getAllConnections()) {
+                if (current != this && current instanceof TelephonyConnection) {
+                    TelephonyConnection other = (TelephonyConnection) current;
+                    if (other.getState() == STATE_ACTIVE) {
+                        other.updateState();
+                    }
+                }
+            }
+        }
+        setActive();
+    }
+
     private void close() {
         Log.v(this, "close");
         if (getPhone() != null) {