Adds more phone states and rules on changing them.

Bug: 10733320
Change-Id: I8176b99777a00b88135e2c954fc5e576bc657ade
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 43ad8b1..bb858b0 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -2149,6 +2149,50 @@
     //
 
     /**
+     * @return true if we're allowed to hold calls, given the current
+     * state of the Phone.
+     */
+    /* package */ static boolean okToHoldCall(CallManager cm) {
+        final Call fgCall = cm.getActiveFgCall();
+        final boolean hasHoldingCall = cm.hasActiveBgCall();
+        final Call.State fgCallState = fgCall.getState();
+
+        // The "Hold" control is disabled entirely if there's
+        // no way to either hold or unhold in the current state.
+        final boolean okToHold = (fgCallState == Call.State.ACTIVE) && !hasHoldingCall;
+        final boolean okToUnhold = cm.hasActiveBgCall() && (fgCallState == Call.State.IDLE);
+        final boolean canHold = okToHold || okToUnhold;
+
+        return canHold;
+    }
+
+    /**
+     * @return true if we support holding calls, given the current
+     * state of the Phone.
+     */
+    /* package */ static boolean okToSupportHold(CallManager cm) {
+        boolean supportsHold = false;
+
+        final Call fgCall = cm.getActiveFgCall();
+        final boolean hasHoldingCall = cm.hasActiveBgCall();
+        final Call.State fgCallState = fgCall.getState();
+
+        if (TelephonyCapabilities.supportsHoldAndUnhold(fgCall.getPhone())) {
+            // This phone has the concept of explicit "Hold" and "Unhold" actions.
+            supportsHold = true;
+        } else if (hasHoldingCall && (fgCallState == Call.State.IDLE)) {
+            // Even when foreground phone device doesn't support hold/unhold, phone devices
+            // for background holding calls may do.
+            final Call bgCall = cm.getFirstActiveBgCall();
+            if (bgCall != null &&
+                    TelephonyCapabilities.supportsHoldAndUnhold(bgCall.getPhone())) {
+                supportsHold = true;
+            }
+        }
+        return supportsHold;
+    }
+
+    /**
      * @return true if we're allowed to swap calls, given the current
      * state of the Phone.
      */