am 760af407: Set the capability to speed up audio setup for IMS MT call

* commit '760af407139bb60033ac5bc8d102b9f153e60ccc':
  Set the capability to speed up audio setup for IMS MT call
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c47db4f..1e5d785 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -147,7 +147,9 @@
     <string name="phone_accounts_configure_account_settings">Configure account settings</string>
 
     <!-- Title for setting to select Wi-Fi call manager account -->
-    <string name="phone_account_wifi_calling">Wi-Fi calling</string>
+    <string name="wifi_calling">Wi-Fi calling</string>
+    <!-- Summary label for wi-fi calling when it is turned off. [CHAR LIMIT=NONE] -->
+    <string name="wifi_calling_off_summary">Off</string>
     <!-- Indication for option to not use a Wi-Fi call manager -->
     <string name="wifi_calling_do_not_use">Do not use Wi-Fi calling</string>
     <!-- Indication for option to not use a call assistant. -->
@@ -427,6 +429,14 @@
     <string name="enhanced_4g_lte_mode_title">Enhanced 4G LTE Mode</string>
     <!-- Cellular network 4G summary [CHAR LIMIT=80] -->
     <string name="enhanced_4g_lte_mode_summary">Use LTE services to improve voice and other communications (recommended)</string>
+
+    <!-- WFC, summary for Wi-Fi Preferred [CHAR LIMIT=100] -->
+    <string name="wfc_mode_wifi_preferred_summary">Wi-Fi preferred (Uses cell network only if Wi-Fi isn\'t available)</string>
+    <!-- WFC, summary for Cellular Preferred [CHAR LIMIT=100] -->
+    <string name="wfc_mode_cellular_preferred_summary">Cellular preferred (Uses Wi-Fi only if cell network isn\'t available)</string>
+    <!-- WFC, summary for Wi-Fi Only [CHAR LIMIT=100] -->
+    <string name="wfc_mode_wifi_only_summary">Wi-Fi only (Never uses cell network. Can\'t make or receive calls if Wi-Fi isn\'t available)</string>
+
     <!-- Mobile network settings screen, data enabling checkbox name -->
     <string name="data_enabled">Data enabled</string>
     <!-- Mobile network settings screen, setting summary text when check box is not selected (explains what selecting it would do) [CHAR LIMITS=40] -->
@@ -807,9 +817,8 @@
     <string name="simContacts_empty">No contacts on your SIM card.</string>
     <!-- Call settings: title of the dialog that lets you select contacts from the SIM. -->
     <string name="simContacts_title">Select contacts to import</string>
-    <!-- Appears when user tries to import contacts in SIM during Airplane mode
-      [CHAR LIMIT=NONE] -->
-    <string name="simContacts_airplaneMode">To import contacts from the SIM card, first turn off Airplane mode.</string>
+    <!-- Appears when user tries to import contacts in SIM during airplane mode [CHAR LIMIT=NONE] -->
+    <string name="simContacts_airplaneMode">Turn off airplane mode to import contacts from the SIM card.</string>
 
     <!-- SIM PIN strings -->
     <!-- Title of "Enable/disable SIM PIN" screen -->
@@ -962,14 +971,18 @@
          [CHAR LIMIT=60] -->
     <string name="notification_missedCall_message">Message</string>
 
-    <!-- In-call screen: call failure message displayed in an error dialog -->
-    <string name="incall_error_power_off">To place a call, first turn off Airplane mode.</string>
+    <!-- In-call screen: call failure message displayed in an error dialog. [CHAR_LIMIT=NONE] -->
+    <string name="incall_error_power_off">Turn off airplane mode to make a call.</string>
+    <!-- In-call screen: call failure message displayed in an error dialog when in airplane mode, WFC is enabled, not wifi-only, and not connected to wireless networks. [CHAR_LIMIT=NONE] -->
+    <string name="incall_error_power_off_wfc">Turn off airplane mode or connect to a wireless network to make a call.</string>
     <!-- In-call screen: call failure message displayed in an error dialog.
          This string is currently unused (see comments in InCallScreen.java.) -->
     <string name="incall_error_emergency_only">Not registered on network.</string>
     <!-- In-call screen: call failure message displayed in an error dialog -->
     <string name="incall_error_out_of_service">Cellular network not available.</string>
     <!-- In-call screen: call failure message displayed in an error dialog -->
+    <string name="incall_error_out_of_service_wfc">Cellular network is not available. Connect to a wireless network to make a call.</string>
+    <!-- In-call screen: call failure message displayed in an error dialog -->
     <string name="incall_error_no_phone_number_supplied">To place a call, enter a valid number.</string>
     <!-- In-call screen: call failure message displayed in an error dialog -->
     <string name="incall_error_call_failed">Can\'t call.</string>
@@ -989,6 +1002,8 @@
     <string name="incall_error_supp_service_reject">Can\'t reject call.</string>
     <!-- In-call screen: message displayed in an error dialog -->
     <string name="incall_error_supp_service_hangup">Can\'t release call(s).</string>
+    <!-- In-call screen: call failure message displayed in an error dialog when WFC is enabled, is wifi-only, and not connected to a wireless network. [CHAR_LIMIT=NONE] -->
+    <string name="incall_error_wfc_only_no_wireless_network">Connect to a wireless network to make a call.</string>
 
     <!-- Dialog title for the "radio enable" UI for emergency calls -->
     <string name="emergency_enable_radio_dialog_title">Emergency call</string>
@@ -1283,4 +1298,6 @@
     <string name="voicemail_notification_vibrate_key">voicemail_notification_vibrate_key</string>
     <!-- DO NOT TRANSLATE. Internal key for tty mode preference. -->
     <string name="tty_mode_key">button_tty_mode_key</string>
+    <!-- DO NOT TRANSLATE. Internal key for a voicemail notification preference. -->
+    <string name="wifi_calling_settings_key">button_wifi_calling_settings_key</string>
 </resources>
diff --git a/res/xml/call_feature_setting.xml b/res/xml/call_feature_setting.xml
index 4ae0bf6..543fae5 100644
--- a/res/xml/call_feature_setting.xml
+++ b/res/xml/call_feature_setting.xml
@@ -82,6 +82,16 @@
         android:title="@string/fdn"
         android:persistent="false" />
 
+    <PreferenceScreen
+        android:key="@string/wifi_calling_settings_key"
+        android:title="@string/wifi_calling">
+
+        <intent android:action="android.intent.action.MAIN"
+            android:targetPackage="com.android.settings"
+            android:targetClass="com.android.settings.Settings$WifiCallingSettingsActivity"/>
+
+    </PreferenceScreen>
+
     <CheckBoxPreference
         android:key="button_enable_video_calling"
         android:title="@string/enable_video_calling_title"
diff --git a/res/xml/network_setting.xml b/res/xml/network_setting.xml
index fcd4439..58c19f7 100644
--- a/res/xml/network_setting.xml
+++ b/res/xml/network_setting.xml
@@ -14,7 +14,6 @@
      limitations under the License.
 -->
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"
         android:title="@string/mobile_networks">
 
     <PreferenceScreen
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index eae9bfc..ed600ee 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -49,6 +49,7 @@
 import android.widget.ListAdapter;
 import android.widget.Toast;
 
+import com.android.ims.ImsConfig;
 import com.android.ims.ImsManager;
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.Phone;
@@ -1337,6 +1338,31 @@
             TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
             tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
         }
+
+        Preference wifiCallingSettings = findPreference(
+                getResources().getString(R.string.wifi_calling_settings_key));
+        if (!ImsManager.isWfcEnabledByPlatform(mPhone.getContext())) {
+            prefSet.removePreference(wifiCallingSettings);
+        } else {
+            int resId = R.string.wifi_calling_off_summary;
+            if (ImsManager.isWfcEnabledByUser(mPhone.getContext())) {
+                int wfcMode = ImsManager.getWfcMode(mPhone.getContext());
+                switch (wfcMode) {
+                    case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY:
+                        resId = R.string.wfc_mode_wifi_only_summary;
+                        break;
+                    case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED:
+                        resId = R.string.wfc_mode_cellular_preferred_summary;
+                        break;
+                    case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED:
+                        resId = R.string.wfc_mode_wifi_preferred_summary;
+                        break;
+                    default:
+                        if (DBG) log("Unexpected WFC mode value: " + wfcMode);
+                }
+            }
+            wifiCallingSettings.setSummary(resId);
+        }
     }
 
     @Override
diff --git a/src/com/android/phone/ImsUtil.java b/src/com/android/phone/ImsUtil.java
index c3d780b..868a0f1 100644
--- a/src/com/android/phone/ImsUtil.java
+++ b/src/com/android/phone/ImsUtil.java
@@ -16,9 +16,16 @@
 
 package com.android.phone;
 
+import android.content.Context;
+import android.util.Log;
+
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsManager;
 import com.android.phone.PhoneGlobals;
 
 public class ImsUtil {
+    private static final String LOG_TAG = ImsUtil.class.getSimpleName();
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private static boolean sImsPhoneSupported = false;
 
@@ -31,10 +38,32 @@
     }
 
     /**
-     * @return true if this device supports voice calls using the built-in SIP stack.
+     * @return {@code true} if this device supports voice calls using the built-in SIP stack.
      */
     static boolean isImsPhoneSupported() {
         return sImsPhoneSupported;
 
     }
+
+    /**
+     * @return {@code true} if WFC is supported by the platform and has been enabled by the user.
+     */
+    public static boolean isWfcEnabled(Context context) {
+        boolean isEnabledByPlatform = ImsManager.isWfcEnabledByPlatform(context);
+        boolean isEnabledByUser = ImsManager.isWfcEnabledByUser(context);
+        if (DBG) Log.d(LOG_TAG, "isWfcEnabled :: isEnabledByPlatform=" + isEnabledByPlatform);
+        if (DBG) Log.d(LOG_TAG, "isWfcEnabled :: isEnabledByUser=" + isEnabledByUser);
+        return isEnabledByPlatform && isEnabledByUser;
+    }
+
+    /**
+     * @return {@code true} if the device is configured to use "Wi-Fi only" mode. If WFC is not
+     * enabled, this will return {@code false}.
+     */
+    public static boolean isWfcModeWifiOnly(Context context) {
+        boolean isWifiOnlyMode =
+                ImsManager.getWfcMode(context) == ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
+        if (DBG) Log.d(LOG_TAG, "isWfcModeWifiOnly :: isWifiOnlyMode" + isWifiOnlyMode);
+        return isWfcEnabled(context) && isWifiOnlyMode;
+    }
 }
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 3e43ba1..bccddeb 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -17,7 +17,6 @@
 package com.android.phone;
 
 import com.android.ims.ImsManager;
-import com.android.ims.ImsException;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
@@ -35,7 +34,6 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.SharedPreferences;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.AsyncResult;
@@ -48,7 +46,6 @@
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
-import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
 import android.preference.SwitchPreference;
 import android.telephony.PhoneStateListener;
@@ -59,12 +56,10 @@
 import android.util.Log;
 import android.view.MenuItem;
 import android.view.View;
-import android.widget.ListView;
 import android.widget.TabHost;
 import android.widget.TabHost.OnTabChangeListener;
 import android.widget.TabHost.TabContentFactory;
 import android.widget.TabHost.TabSpec;
-import android.widget.TabWidget;
 
 /**
  * "Mobile network settings" screen.  This preference screen lets you
@@ -147,11 +142,10 @@
         @Override
         public void onCallStateChanged(int state, String incomingNumber) {
             if (DBG) log("PhoneStateListener.onCallStateChanged: state=" + state);
+            boolean enabled = (state == TelephonyManager.CALL_STATE_IDLE) &&
+                    ImsManager.isNonTtyOrTtyOnVolteEnabled(getApplicationContext());
             Preference pref = getPreferenceScreen().findPreference(BUTTON_4G_LTE_KEY);
-            if (pref != null) {
-                pref.setEnabled((state == TelephonyManager.CALL_STATE_IDLE) &&
-                        ImsManager.isNonTtyOrTtyOnVolteEnabled(getApplicationContext()));
-            }
+            if (pref != null) pref.setEnabled(enabled && hasActiveSubscriptions());
         }
     };
 
@@ -241,7 +235,7 @@
             return true;
         }  else if (preference == mButtonEnabledNetworks) {
             int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
-                    getContentResolver(),
+                            getContentResolver(),
                     android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                     preferredNetworkMode);
             mButtonEnabledNetworks.setValue(Integer.toString(settingsNetworkMode));
@@ -436,7 +430,6 @@
         addPreferencesFromResource(R.xml.network_setting);
 
         mButton4glte = (SwitchPreference)findPreference(BUTTON_4G_LTE_KEY);
-
         mButton4glte.setOnPreferenceChangeListener(this);
 
         try {
@@ -508,9 +501,10 @@
             tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
         }
 
-        mButton4glte.setChecked(ImsManager.isEnhanced4gLteModeSettingEnabledByUser(this)
-                && ImsManager.isNonTtyOrTtyOnVolteEnabled(this));
-        // NOTE: The button will be enabled/disabled in mPhoneStateListener
+        // NOTE: Buttons will be enabled/disabled in mPhoneStateListener
+        boolean enh4glteMode = ImsManager.isEnhanced4gLteModeSettingEnabledByUser(this)
+                && ImsManager.isNonTtyOrTtyOnVolteEnabled(this);
+        mButton4glte.setChecked(enh4glteMode);
 
         mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
 
@@ -518,6 +512,10 @@
 
     }
 
+    private boolean hasActiveSubscriptions() {
+        return mActiveSubInfos.size() > 0;
+    }
+
     private void updateBody() {
         final Context context = getApplicationContext();
         PreferenceScreen prefSet = getPreferenceScreen();
@@ -707,11 +705,15 @@
          * but you do need to remember that this all needs to work when subscriptions
          * change dynamically such as when hot swapping sims.
          */
-        boolean hasActiveSubscriptions = mActiveSubInfos.size() > 0;
+        boolean hasActiveSubscriptions = hasActiveSubscriptions();
+        TelephonyManager tm = (TelephonyManager) getSystemService(
+                Context.TELEPHONY_SERVICE);
+        boolean canChange4glte = (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) &&
+                ImsManager.isNonTtyOrTtyOnVolteEnabled(getApplicationContext());
         mButtonDataRoam.setEnabled(hasActiveSubscriptions);
         mButtonPreferredNetworkMode.setEnabled(hasActiveSubscriptions);
         mButtonEnabledNetworks.setEnabled(hasActiveSubscriptions);
-        mButton4glte.setEnabled(hasActiveSubscriptions);
+        mButton4glte.setEnabled(hasActiveSubscriptions && canChange4glte);
         mLteDataServicePref.setEnabled(hasActiveSubscriptions);
         Preference ps;
         PreferenceScreen root = getPreferenceScreen();
@@ -843,9 +845,10 @@
                         .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
             }
         } else if (preference == mButton4glte) {
-            SwitchPreference ltePref = (SwitchPreference)preference;
-            ltePref.setChecked(!ltePref.isChecked());
-            ImsManager.setEnhanced4gLteModeSetting(this, ltePref.isChecked());
+            SwitchPreference enhanced4gModePref = (SwitchPreference) preference;
+            boolean enhanced4gMode = !enhanced4gModePref.isChecked();
+            enhanced4gModePref.setChecked(enhanced4gMode);
+            ImsManager.setEnhanced4gLteModeSetting(this, enhanced4gModePref.isChecked());
         } else if (preference == mButtonDataRoam) {
             if (DBG) log("onPreferenceTreeClick: preference == mButtonDataRoam.");
 
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 9eb0b0b..4037f6d 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -2259,4 +2259,20 @@
     public boolean isImsRegistered() {
         return mPhone.isImsRegistered();
     }
+
+    /*
+     * {@hide}
+     * Returns the IMS Registration Status
+     */
+    public boolean isWifiCallingEnabled() {
+        return mPhone.isWifiCallingEnabled();
+    }
+
+    /*
+     * {@hide}
+     * Returns the IMS Registration Status
+     */
+    public boolean isVolteEnabled() {
+        return mPhone.isVolteEnabled();
+    }
 }
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 0e9c0d0..aaaf7db 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -22,6 +22,7 @@
 
 import com.android.phone.PhoneGlobals;
 import com.android.phone.common.R;
+import com.android.phone.ImsUtil;
 
 public class DisconnectCauseUtil {
 
@@ -254,15 +255,18 @@
                 break;
 
             case android.telephony.DisconnectCause.POWER_OFF:
-                // Radio is explictly powered off, presumably because the
-                // device is in airplane mode.
-                //
-                // TODO: For now this UI is ultra-simple: we simply display
-                // a message telling the user to turn off airplane mode.
-                // But it might be nicer for the dialog to offer the option
-                // to turn the radio on right there (and automatically retry
-                // the call once network registration is complete.)
-                resourceId = R.string.incall_error_power_off;
+                // Radio is explictly powered off because the device is in airplane mode.
+
+                // TODO: Offer the option to turn the radio on, and automatically retry the call
+                // once network registration is complete.
+
+                if (ImsUtil.isWfcModeWifiOnly(context)) {
+                    resourceId = R.string.incall_error_wfc_only_no_wireless_network;
+                } else if (ImsUtil.isWfcEnabled(context)) {
+                    resourceId = R.string.incall_error_power_off_wfc;
+                } else {
+                    resourceId = R.string.incall_error_power_off;
+                }
                 break;
 
             case android.telephony.DisconnectCause.EMERGENCY_ONLY:
@@ -273,7 +277,13 @@
 
             case android.telephony.DisconnectCause.OUT_OF_SERVICE:
                 // No network connection.
-                resourceId = R.string.incall_error_out_of_service;
+                if (ImsUtil.isWfcModeWifiOnly(context)) {
+                    resourceId = R.string.incall_error_wfc_only_no_wireless_network;
+                } else if (ImsUtil.isWfcEnabled(context)) {
+                    resourceId = R.string.incall_error_out_of_service_wfc;
+                } else {
+                    resourceId = R.string.incall_error_out_of_service;
+                }
                 break;
 
             case android.telephony.DisconnectCause.NO_PHONE_NUMBER_SUPPLIED:
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 73bfe8c..b00aa46 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
@@ -433,8 +450,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) {
@@ -485,6 +509,7 @@
         setVideoState(mOriginalConnection.getVideoState());
         setLocalVideoCapable(mOriginalConnection.isLocalVideoCapable());
         setRemoteVideoCapable(mOriginalConnection.isRemoteVideoCapable());
+        setWifi(mOriginalConnection.isWifi());
         setVideoProvider(mOriginalConnection.getVideoProvider());
         setAudioQuality(mOriginalConnection.getAudioQuality());
 
@@ -699,52 +724,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.
      *
@@ -805,23 +784,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) {
@@ -865,27 +847,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;
+        }
     }
 
     /**
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 57f40e9..22f21ed 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -154,7 +154,7 @@
         boolean useEmergencyCallHelper = false;
 
         if (isEmergencyNumber) {
-            if (state == ServiceState.STATE_POWER_OFF) {
+            if (!phone.isRadioOn()) {
                 useEmergencyCallHelper = true;
             }
         } else {