Added support for VoLTE conference hold and resume.

Bug: 17368957
Change-Id: I0aa1034f24c4860dbf5a2baafc340b89cc41f03a
diff --git a/src/java/com/android/ims/ImsCall.java b/src/java/com/android/ims/ImsCall.java
index 1879dc4..f8bbfc2 100644
--- a/src/java/com/android/ims/ImsCall.java
+++ b/src/java/com/android/ims/ImsCall.java
@@ -939,6 +939,20 @@
             log("hold :: session=" + mSession);
         }
 
+        // perform operation on owner before doing any local checks: local
+        // call may not have its status updated
+        synchronized (mLockObj) {
+            CallGroup callGroup = mCallGroup;
+            if (callGroup != null && !callGroup.isOwner(ImsCall.this)) {
+                log("hold owner of the call group");
+                ImsCall owner = (ImsCall) callGroup.getOwner();
+                if (owner != null) {
+                    owner.hold();
+                    return;
+                }
+            }
+        }
+
         if (isOnHold()) {
             if (DBG) {
                 log("hold :: call is already on hold");
@@ -977,6 +991,20 @@
             log("resume :: session=" + mSession);
         }
 
+        // perform operation on owner before doing any local checks: local
+        // call may not have its status updated
+        synchronized (mLockObj) {
+            CallGroup callGroup = mCallGroup;
+            if (callGroup != null && !callGroup.isOwner(ImsCall.this)) {
+                log("resume owner of the call group");
+                ImsCall owner = (ImsCall) callGroup.getOwner();
+                if (owner != null) {
+                    owner.resume();
+                    return;
+                }
+            }
+        }
+
         if (!isOnHold()) {
             if (DBG) {
                 log("resume :: call is in conversation");
@@ -1435,10 +1463,10 @@
         ImsCall.Listener listener;
 
         if (mCallGroup.isOwner(ImsCall.this)) {
-            loge("Group Owner! Size of referrers list = " + mCallGroup.getReferrers().size());
+            log("Group Owner! Size of referrers list = " + mCallGroup.getReferrers().size());
             while (mCallGroup.hasReferrer()) {
                 ImsCall call = (ImsCall) mCallGroup.getReferrers().get(0);
-                loge("onCallTerminated to be called for the call:: " + call);
+                log("onCallTerminated to be called for the call:: " + call);
 
                 if (call == null) {
                     continue;
@@ -1471,6 +1499,42 @@
         }
     }
 
+    private void notifyConferenceStateUpdatedThroughGroupOwner(int update) {
+        ImsCall.Listener listener;
+
+        if (mCallGroup.isOwner(ImsCall.this)) {
+            log("Group Owner! Size of referrers list = " + mCallGroup.getReferrers().size());
+            for (ICall icall : mCallGroup.getReferrers()) {
+                ImsCall call = (ImsCall) icall;
+                log("notifyConferenceStateUpdatedThroughGroupOwner to be called for the call:: " + call);
+
+                if (call == null) {
+                    continue;
+                }
+
+                listener = call.mListener;
+
+                if (listener != null) {
+                    try {
+                        switch (update) {
+                            case UPDATE_HOLD:
+                                listener.onCallHeld(call);
+                                break;
+                            case UPDATE_RESUME:
+                                listener.onCallResumed(call);
+                                break;
+                            default:
+                                loge("notifyConferenceStateUpdatedThroughGroupOwner :: not handled update "
+                                        + update);
+                        }
+                    } catch (Throwable t) {
+                        loge("notifyConferenceStateUpdatedThroughGroupOwner :: ", t);
+                    }
+                }
+            }
+        }
+    }
+
     private void notifyConferenceStateUpdated(ImsConferenceState state) {
         Set<Entry<String, Bundle>> paticipants = state.mParticipants.entrySet();
 
@@ -1683,6 +1747,10 @@
                     loge("callSessionHeld :: ", t);
                 }
             }
+
+            if (mCallGroup != null) {
+                notifyConferenceStateUpdatedThroughGroupOwner(UPDATE_HOLD);
+            }
         }
 
         @Override
@@ -1764,6 +1832,10 @@
                     loge("callSessionResumed :: ", t);
                 }
             }
+
+            if (mCallGroup != null) {
+                notifyConferenceStateUpdatedThroughGroupOwner(UPDATE_RESUME);
+            }
         }
 
         @Override