Set CAPABILITY_WIFI on TelephonyConnection.

+ Add listener for when wifi capability has changed on the original
Telephony Connection, and update the Telecom Connection.
~ Refactor some of the helpers and logic for how capabilities are
applied and removed, to remove redundant code.

Bug: 19151548
Change-Id: I04b8e47201bf2ec48aebaecb6a245024902333b0
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 71e4cae..8499263 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -158,6 +158,17 @@
         }
 
         /**
+         * Used by {@link com.android.internal.telephony.Connection} to report a change in whether
+         * the call is being made over a wifi network.
+         *
+         * @param isWifi True if call is made over wifi.
+         */
+        @Override
+        public void onWifiChanged(boolean isWifi) {
+            setWifi(isWifi);
+        }
+
+        /**
          * Used by the {@link com.android.internal.telephony.Connection} to report a change in the
          * audio quality for the current call.
          *
@@ -167,7 +178,6 @@
         public void onAudioQualityChanged(int audioQuality) {
             setAudioQuality(audioQuality);
         }
-
         /**
          * Handles a change in the state of conference participant(s), as reported by the
          * {@link com.android.internal.telephony.Connection}.
@@ -210,11 +220,18 @@
     private boolean mRemoteVideoCapable;
 
     /**
-     * Determines the current audio quality for the {@link TelephonyConnection}.
+     * Determines if the {@link TelephonyConnection} is using wifi.
+     * This is used when {@link TelephonyConnection#updateConnectionCapabilities} is called to
+     * indicate wheter a call has the {@link Connection#CAPABILITY_WIFI} capability.
+     */
+    private boolean mIsWifi;
+
+    /**
+     * Determines the audio quality is high for the {@link TelephonyConnection}.
      * This is used when {@link TelephonyConnection#updateConnectionCapabilities}} is called to
      * indicate whether a call has the {@link Connection#CAPABILITY_HIGH_DEF_AUDIO} capability.
      */
-    private int mAudioQuality;
+    private boolean mHasHighDefAudio;
 
     /**
      * Listeners to our TelephonyConnection specific callbacks
@@ -430,8 +447,15 @@
 
     protected final void updateConnectionCapabilities() {
         int newCapabilities = buildConnectionCapabilities();
-        newCapabilities = applyVideoCapabilities(newCapabilities);
-        newCapabilities = applyAudioQualityCapabilities(newCapabilities);
+
+        newCapabilities = changeCapability(newCapabilities,
+                CAPABILITY_SUPPORTS_VT_REMOTE, mRemoteVideoCapable);
+        newCapabilities = changeCapability(newCapabilities,
+                CAPABILITY_SUPPORTS_VT_LOCAL, mLocalVideoCapable);
+        newCapabilities = changeCapability(newCapabilities,
+                CAPABILITY_HIGH_DEF_AUDIO, mHasHighDefAudio);
+        newCapabilities = changeCapability(newCapabilities, CAPABILITY_WIFI, mIsWifi);
+
         newCapabilities = applyConferenceTerminationCapabilities(newCapabilities);
 
         if (getConnectionCapabilities() != newCapabilities) {
@@ -482,6 +506,7 @@
         setVideoState(mOriginalConnection.getVideoState());
         setLocalVideoCapable(mOriginalConnection.isLocalVideoCapable());
         setRemoteVideoCapable(mOriginalConnection.isRemoteVideoCapable());
+        setWifi(mOriginalConnection.isWifi());
         setVideoProvider(mOriginalConnection.getVideoProvider());
         setAudioQuality(mOriginalConnection.getAudioQuality());
 
@@ -696,52 +721,6 @@
     }
 
     /**
-     * Applies the video capability states to the CallCapabilities bit-mask.
-     *
-     * @param capabilities The CallCapabilities bit-mask.
-     * @return The capabilities with video capabilities applied.
-     */
-    private int applyVideoCapabilities(int capabilities) {
-        int currentCapabilities = capabilities;
-        if (mRemoteVideoCapable) {
-            currentCapabilities = applyCapability(currentCapabilities,
-                    CAPABILITY_SUPPORTS_VT_REMOTE);
-        } else {
-            currentCapabilities = removeCapability(currentCapabilities,
-                    CAPABILITY_SUPPORTS_VT_REMOTE);
-        }
-
-        if (mLocalVideoCapable) {
-            currentCapabilities = applyCapability(currentCapabilities,
-                    CAPABILITY_SUPPORTS_VT_LOCAL);
-        } else {
-            currentCapabilities = removeCapability(currentCapabilities,
-                    CAPABILITY_SUPPORTS_VT_LOCAL);
-        }
-        return currentCapabilities;
-    }
-
-    /**
-     * Applies the audio capabilities to the {@code CallCapabilities} bit-mask.  A call with high
-     * definition audio is considered to have the {@code HIGH_DEF_AUDIO} call capability.
-     *
-     * @param capabilities The {@code CallCapabilities} bit-mask.
-     * @return The capabilities with the audio capabilities applied.
-     */
-    private int applyAudioQualityCapabilities(int capabilities) {
-        int currentCapabilities = capabilities;
-
-        if (mAudioQuality ==
-                com.android.internal.telephony.Connection.AUDIO_QUALITY_HIGH_DEFINITION) {
-            currentCapabilities = applyCapability(currentCapabilities, CAPABILITY_HIGH_DEF_AUDIO);
-        } else {
-            currentCapabilities = removeCapability(currentCapabilities, CAPABILITY_HIGH_DEF_AUDIO);
-        }
-
-        return currentCapabilities;
-    }
-
-    /**
      * Applies capabilities specific to conferences termination to the
      * {@code CallCapabilities} bit-mask.
      *
@@ -802,23 +781,26 @@
     }
 
     /**
-     * Sets the current call audio quality.  Used during rebuild of the capabilities
+     * Sets whether the call is using wifi. Used when rebuilding the capabilities to set or unset
+     * the {@link Connection#CAPABILITY_WIFI} capability.
+     */
+    public void setWifi(boolean isWifi) {
+        mIsWifi = isWifi;
+        updateConnectionCapabilities();
+    }
+
+    /**
+     * Sets the current call audio quality. Used during rebuild of the capabilities
      * to set or unset the {@link Connection#CAPABILITY_HIGH_DEF_AUDIO} capability.
      *
      * @param audioQuality The audio quality.
      */
     public void setAudioQuality(int audioQuality) {
-        mAudioQuality = audioQuality;
+        mHasHighDefAudio = audioQuality ==
+                com.android.internal.telephony.Connection.AUDIO_QUALITY_HIGH_DEFINITION;
         updateConnectionCapabilities();
     }
 
-    /**
-     * Obtains the current call audio quality.
-     */
-    public int getAudioQuality() {
-        return mAudioQuality;
-    }
-
     void resetStateForConference() {
         if (getState() == Connection.STATE_HOLDING) {
             if (mOriginalConnection.getState() == Call.State.ACTIVE) {
@@ -862,27 +844,19 @@
     }
 
     /**
-     * Applies a capability to a capabilities bit-mask.
+     * Changes a capabilities bit-mask to add or remove a capability.
      *
      * @param capabilities The capabilities bit-mask.
-     * @param capability The capability to apply.
-     * @return The capabilities bit-mask with the capability applied.
+     * @param capability The capability to change.
+     * @param enabled Whether the capability should be set or removed.
+     * @return The capabilities bit-mask with the capability changed.
      */
-    private int applyCapability(int capabilities, int capability) {
-        int newCapabilities = capabilities | capability;
-        return newCapabilities;
-    }
-
-    /**
-     * Removes a capability from a capabilities bit-mask.
-     *
-     * @param capabilities The capabilities bit-mask.
-     * @param capability The capability to remove.
-     * @return The capabilities bit-mask with the capability removed.
-     */
-    private int removeCapability(int capabilities, int capability) {
-        int newCapabilities = capabilities & ~capability;
-        return newCapabilities;
+    private int changeCapability(int capabilities, int capability, boolean enabled) {
+        if (enabled) {
+            return capabilities | capability;
+        } else {
+            return capabilities & ~capability;
+        }
     }
 
     /**