Add a "Cellular data fallback" pref.

Also adjust working of the "lost internet" notification.

Bug: 31075769
Change-Id: I17e18516c9bfdc32b38686191327b6d6f87aed95
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 78ed150..7105bc1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1588,7 +1588,10 @@
     <string name="wifi_limit_optimizations_summary">Limit battery used by Wi\u2011Fi</string>
     <!-- Checkbox title. Should we switch to using cellular data if Wi-Fi is still connected but the Wi-Fi network we're connected to no longer has Internet access (e.g., due to an outage)? -->
     <string name="wifi_switch_away_when_unvalidated">Switch to cellular data if Wi\u2011Fi loses Internet access.</string>
-
+    <!-- Preference title for option to automatically switch away from bad wifi networks [CHAR LIMIT=60]-->
+    <string name="wifi_cellular_data_fallback_title">Cellular data fallback</string>
+    <!-- Preference summary for option to automatically switch away from bad wifi networks [CHAR LIMIT=None]-->
+    <string name="wifi_cellular_data_fallback_summary">Use cellular data when Wi\u2011Fi loses Internet access. Additional charges may apply.</string>
     <!-- Action bar text message to manually add a wifi network [CHAR LIMIT=20]-->
     <string name="wifi_add_network">Add network</string>
     <!-- Header for the list of wifi networks-->
@@ -1749,11 +1752,10 @@
     <string name="no_internet_access_remember">Don\u2019t ask again for this network</string>
 
     <!-- Dialog text to tell the user that the selected network has lost Internet access, and asking the user whether they want to avoid this network. -->
-    <string name="lost_internet_access_title">Wi\u2011Fi has no Internet access</string>
-    <string name="lost_internet_access_text">Your device can automatically switch to other saved Wi\u2011Fi networks or cellular data. Cellular charges may apply.</string>
-    <string name="lost_internet_access_switch">Switch networks</string>
-    <string name="lost_internet_access_cancel">Cancel</string>
-
+    <string name="lost_internet_access_title">Switch to cellular data?</string>
+    <string name="lost_internet_access_text">Wi\u2011Fi lost Internet access. Your device can switch to cellular automatically when Wi\u2011Fi isn\u2019t working. Additional charges may apply.</string>
+    <string name="lost_internet_access_switch">Switch automatically</string>
+    <string name="lost_internet_access_cancel">Stay on Wi\u2011Fi</string>
 
     <!-- Button label to connect to a Wi-Fi network -->
     <string name="wifi_connect">Connect</string>
diff --git a/res/xml/wifi_configure_settings.xml b/res/xml/wifi_configure_settings.xml
index 3aeb83e..863007c 100644
--- a/res/xml/wifi_configure_settings.xml
+++ b/res/xml/wifi_configure_settings.xml
@@ -41,6 +41,11 @@
         android:summary="@string/wifi_automatically_connect_summary"
         android:dialogTitle="@string/wifi_select_assistant_dialog_title" />
 
+    <SwitchPreference
+        android:key="wifi_cellular_data_fallback"
+        android:title="@string/wifi_cellular_data_fallback_title"
+        android:summary="@string/wifi_cellular_data_fallback_summary"/>
+
     <com.android.settings.DividerPreference
         android:key="mac_address"
         android:title="@string/wifi_advanced_mac_address_title"
diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java
index aa79080..5ac5a7b 100644
--- a/src/com/android/settings/wifi/ConfigureWifiSettings.java
+++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.Resources;
 import android.net.NetworkScoreManager;
 import android.net.NetworkScorerAppManager;
 import android.net.wifi.WifiConfiguration;
@@ -51,6 +52,7 @@
     private static final String KEY_CURRENT_IP_ADDRESS = "current_ip_address";
     private static final String KEY_NOTIFY_OPEN_NETWORKS = "notify_open_networks";
     private static final String KEY_SLEEP_POLICY = "sleep_policy";
+    private static final String KEY_CELLULAR_FALLBACK = "wifi_cellular_data_fallback";
     private static final String KEY_WIFI_ASSISTANT = "wifi_assistant";
 
     private WifiManager mWifiManager;
@@ -103,6 +105,20 @@
         notifyOpenNetworks.setEnabled(mWifiManager.isWifiEnabled());
 
         final Context context = getActivity();
+        if (avoidBadWifiConfig()) {
+            // Hide preference toggle, always avoid bad wifi networks.
+            removePreference(KEY_CELLULAR_FALLBACK);
+        } else {
+            // Show preference toggle, initialized based on current settings value.
+            boolean currentSetting = avoidBadWifiCurrentSettings();
+            SwitchPreference pref = (SwitchPreference) findPreference(KEY_CELLULAR_FALLBACK);
+            // TODO: can this ever be null? The return value of avoidBadWifiConfig() can only
+            // change if the resources change, but if that happens the activity will be recreated...
+            if (pref != null) {
+                pref.setChecked(currentSetting);
+            }
+        }
+
         mWifiAssistantPreference = (AppListSwitchPreference) findPreference(KEY_WIFI_ASSISTANT);
         Collection<NetworkScorerAppManager.NetworkScorerAppData> scorers =
                 NetworkScorerAppManager.getAllValidScorers(context);
@@ -148,6 +164,16 @@
         Log.e(TAG, "Invalid sleep policy value: " + value);
     }
 
+    private boolean avoidBadWifiConfig() {
+        return getActivity().getResources().getInteger(
+                com.android.internal.R.integer.config_networkAvoidBadWifi) == 1;
+    }
+
+    private boolean avoidBadWifiCurrentSettings() {
+        return Settings.Global.getInt(getContentResolver(),
+                Settings.Global.NETWORK_AVOID_BAD_WIFI, 0) == 1;
+    }
+
     @Override
     public boolean onPreferenceTreeClick(Preference preference) {
         String key = preference.getKey();
@@ -156,6 +182,18 @@
             Settings.Global.putInt(getContentResolver(),
                     Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
                     ((SwitchPreference) preference).isChecked() ? 1 : 0);
+        } else if (KEY_CELLULAR_FALLBACK.equals(key)) {
+            String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;
+            if (((SwitchPreference) preference).isChecked()) {
+                // The user wants to avoid bad wifi networks. Remember the choice.
+                Settings.Global.putInt(getContentResolver(), settingName, 1);
+            } else {
+                // Unset the setting. ConnectivityService interprets null to mean "use the carrier
+                // default". We don't set the setting to 0 because if we do, and the user switches
+                // to a carrier that does not restrict cellular fallback, then there is no way to
+                // set it to 1 again because on such a carrier the toggle is never shown.
+                Settings.Global.putString(getContentResolver(), settingName, null);
+            }
         } else {
             return super.onPreferenceTreeClick(preference);
         }
diff --git a/src/com/android/settings/wifi/WifiNoInternetDialog.java b/src/com/android/settings/wifi/WifiNoInternetDialog.java
index 289e0fc..0924498 100644
--- a/src/com/android/settings/wifi/WifiNoInternetDialog.java
+++ b/src/com/android/settings/wifi/WifiNoInternetDialog.java
@@ -173,8 +173,12 @@
         } else {
             final String action = (accept ? "Switch" : "Cancel");
             Log.d(TAG, "LOST_INTERNET: " + action);
-            Settings.Global.putInt(mAlertParams.mContext.getContentResolver(),
-                    Settings.Global.NETWORK_AVOID_BAD_WIFI, accept ? 1 : 0);
+            // Only ever set the setting to 1. The values understood by ConnectivityService are null
+            // (use carrier default) or 1 (avoid bad networks regardless of carrier).
+            if (accept) {
+                Settings.Global.putInt(mAlertParams.mContext.getContentResolver(),
+                        Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
+            }
         }
     }
 }