diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 79f11513e7989..1e66c55ada5dc 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7450,6 +7450,12 @@ public final class Settings {
public static final String NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS =
"network_switch_notification_rate_limit_millis";
+ /**
+ * Whether to automatically switch away from wifi networks that lose Internet access.
+ * @hide
+ */
+ public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi";
+
/**
* Whether Wifi display is enabled/disabled
* 0=disabled. 1=enabled.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 004b31f3a3ae7..b047cdf3c69fa 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -275,6 +275,11 @@
+
+ 1
+
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 39127a43f0a30..4613b78033768 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1747,6 +1747,7 @@
+
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ee455af5e31a7..da08e626b7c6a 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2735,6 +2735,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
PROMPT_UNVALIDATED_DELAY_MS);
}
+ @VisibleForTesting
+ public boolean avoidBadWifi() {
+ int defaultAvoidBadWifi =
+ mContext.getResources().getInteger(R.integer.config_networkAvoidBadWifi);
+ int avoid = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.NETWORK_AVOID_BAD_WIFI, defaultAvoidBadWifi);
+ return avoid == 1;
+ }
+
private void handlePromptUnvalidated(Network network) {
if (VDBG) log("handlePromptUnvalidated " + network);
NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index ba39ec016674b..cb4bb8840b5a0 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -115,6 +115,7 @@ import java.util.TreeSet;
// is satisfying one or more background NetworkRequests it is kept up in the background. If it is
// not, ConnectivityService disconnects the NetworkAgent's AsyncChannel.
public class NetworkAgentInfo implements Comparable {
+
public NetworkInfo networkInfo;
// This Network object should always be used if possible, so as to encourage reuse of the
// enclosed socket factory and connection pool. Avoid creating other Network objects.
@@ -415,13 +416,20 @@ public class NetworkAgentInfo implements Comparable {
}
int score = currentScore;
- if (!lastValidated && !pretendValidated) {
+ if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty()) {
score -= UNVALIDATED_SCORE_PENALTY;
}
if (score < 0) score = 0;
return score;
}
+ // Return true on devices configured to ignore score penalty for wifi networks
+ // that become unvalidated (b/31075769).
+ private boolean ignoreWifiUnvalidationPenalty() {
+ boolean isWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+ return isWifi && !mConnService.avoidBadWifi() && everValidated;
+ }
+
// Get the current score for this Network. This may be modified from what the
// NetworkAgent sent, as it has modifiers applied to it.
public int getCurrentScore() {