diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 515a91c4d4223..6949e43d99912 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7441,6 +7441,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 b80b0a70a0368..3dbcdafcc99b6 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 924d338091240..def40dbcbd041 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1746,6 +1746,7 @@
+
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5d0508c56b35b..4c30dc2661ec8 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2704,6 +2704,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 780be3c4610fc..3503eacb07354 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -113,6 +113,7 @@ import java.util.TreeSet;
// a NetworkRequest, ConnectivityService will cancel the future disconnection of the NetworkAgent's
// AsyncChannel, and the network is no longer considered "lingering".
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.
@@ -354,13 +355,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() {