Loading core/java/android/net/ConnectivityManager.java +21 −0 Original line number Diff line number Diff line Loading @@ -3197,6 +3197,27 @@ public class ConnectivityManager { } } /** * Informs the system to penalize {@code network}'s score when it becomes unvalidated. This is * only meaningful if the system is configured not to penalize such networks, e.g., if the * {@code config_networkAvoidBadWifi} configuration variable is set to 0 and the {@code * NETWORK_AVOID_BAD_WIFI setting is unset}. * * <p>This method requires the caller to hold the permission * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL} * * @param network The network to accept. * * @hide */ public void setAvoidUnvalidated(Network network) { try { mService.setAvoidUnvalidated(network); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Resets all connectivity manager settings back to factory defaults. * @hide Loading core/java/android/net/IConnectivityManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ interface IConnectivityManager void releaseNetworkRequest(in NetworkRequest networkRequest); void setAcceptUnvalidated(in Network network, boolean accept, boolean always); void setAvoidUnvalidated(in Network network); int getRestoreDefaultNetworkDelay(int networkType); Loading core/java/android/provider/Settings.java +7 −0 Original line number Diff line number Diff line Loading @@ -7489,6 +7489,13 @@ public final class Settings { /** * Whether to automatically switch away from wifi networks that lose Internet access. * Only meaningful if config_networkAvoidBadWifi is set to 0, otherwise the system always * avoids such networks. Valid values are: * * 0: Don't avoid bad wifi, don't prompt the user. Get stuck on bad wifi like it's 2013. * null: Ask the user whether to switch away from bad wifi. * 1: Avoid bad wifi. * * @hide */ public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi"; Loading services/core/java/com/android/server/ConnectivityService.java +47 −15 Original line number Diff line number Diff line Loading @@ -371,6 +371,11 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28; /** * used to specify whether a network should not be penalized when it becomes unvalidated. */ private static final int EVENT_SET_AVOID_UNVALIDATED = 35; /** * used to ask the user to confirm a connection to an unvalidated network. * obj = network Loading Loading @@ -2712,6 +2717,12 @@ public class ConnectivityService extends IConnectivityManager.Stub accept ? 1 : 0, always ? 1: 0, network)); } @Override public void setAvoidUnvalidated(Network network) { enforceConnectivityInternalPermission(); mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); } private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { if (DBG) log("handleSetAcceptUnvalidated network=" + network + " accept=" + accept + " always=" + always); Loading Loading @@ -2752,6 +2763,20 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void handleSetAvoidUnvalidated(Network network) { NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); if (nai == null || nai.lastValidated) { // Nothing to do. The network either disconnected or revalidated. return; } if (!nai.avoidUnvalidated) { int oldScore = nai.getCurrentScore(); nai.avoidUnvalidated = true; rematchAllNetworksAndRequests(nai, oldScore); sendUpdatedScoreToFactories(nai); } } private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) { if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network); mHandler.sendMessageDelayed( Loading @@ -2759,28 +2784,31 @@ public class ConnectivityService extends IConnectivityManager.Stub PROMPT_UNVALIDATED_DELAY_MS); } private boolean mAvoidBadWifi; private boolean mAvoidBadWifi = true; public boolean avoidBadWifi() { return mAvoidBadWifi; } @VisibleForTesting public boolean updateAvoidBadWifi() { // There are two modes: either we always automatically avoid unvalidated wifi, or we show a // dialog and don't switch to it. The behaviour is controlled by the NETWORK_AVOID_BAD_WIFI // setting. If the setting has no value, then the value is taken from the config value, // which can be changed via OEM/carrier overlays. // // The only valid values for NETWORK_AVOID_BAD_WIFI are null and unset. Currently, the unit // test uses 0 in order to avoid having to mock out fetching the carrier setting. int defaultAvoidBadWifi = mContext.getResources().getInteger(R.integer.config_networkAvoidBadWifi); int avoid = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.NETWORK_AVOID_BAD_WIFI, defaultAvoidBadWifi); /** Whether the device or carrier configuration disables avoiding bad wifi by default. */ public boolean configRestrictsAvoidBadWifi() { return mContext.getResources().getInteger(R.integer.config_networkAvoidBadWifi) == 0; } /** Whether we should display a notification when wifi becomes unvalidated. */ public boolean shouldNotifyWifiUnvalidated() { return configRestrictsAvoidBadWifi() && Settings.Global.getString(mContext.getContentResolver(), Settings.Global.NETWORK_AVOID_BAD_WIFI) == null; } private boolean updateAvoidBadWifi() { boolean settingAvoidBadWifi = "1".equals(Settings.Global.getString( mContext.getContentResolver(), Settings.Global.NETWORK_AVOID_BAD_WIFI)); boolean prev = mAvoidBadWifi; mAvoidBadWifi = (avoid == 1); mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi(); return mAvoidBadWifi != prev; } Loading Loading @@ -2833,7 +2861,7 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkCapabilities nc = nai.networkCapabilities; if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc); if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && !avoidBadWifi()) { if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && shouldNotifyWifiUnvalidated()) { showValidationNotification(nai, NotificationType.LOST_INTERNET); } } Loading Loading @@ -2911,6 +2939,10 @@ public class ConnectivityService extends IConnectivityManager.Stub handleSetAcceptUnvalidated((Network) msg.obj, msg.arg1 != 0, msg.arg2 != 0); break; } case EVENT_SET_AVOID_UNVALIDATED: { handleSetAvoidUnvalidated((Network) msg.obj); break; } case EVENT_PROMPT_UNVALIDATED: { handlePromptUnvalidated((Network) msg.obj); break; Loading services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +10 −6 Original line number Diff line number Diff line Loading @@ -140,12 +140,14 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { public boolean everValidated; // The result of the last validation attempt on this network (true if validated, false if not). // This bit exists only because we never unvalidate a network once it's been validated, and that // is because the network scoring and revalidation code does not (may not?) deal properly with // networks becoming unvalidated. // TODO: Fix the network scoring code, remove this, and rename everValidated to validated. public boolean lastValidated; // If true, becoming unvalidated will lower the network's score. This is only meaningful if the // system is configured not to do this for certain networks, e.g., if the // config_networkAvoidBadWifi option is set to 0 and the user has not overridden that via // Settings.Global.NETWORK_AVOID_BAD_WIFI. public boolean avoidUnvalidated; // Whether a captive portal was ever detected on this network. // This is a sticky bit; once set it is never cleared. public boolean everCaptivePortalDetected; Loading Loading @@ -426,8 +428,10 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // 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; boolean isWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); boolean avoidBadWifi = mConnService.avoidBadWifi() || avoidUnvalidated; return isWifi && !avoidBadWifi && everValidated; } // Get the current score for this Network. This may be modified from what the Loading Loading
core/java/android/net/ConnectivityManager.java +21 −0 Original line number Diff line number Diff line Loading @@ -3197,6 +3197,27 @@ public class ConnectivityManager { } } /** * Informs the system to penalize {@code network}'s score when it becomes unvalidated. This is * only meaningful if the system is configured not to penalize such networks, e.g., if the * {@code config_networkAvoidBadWifi} configuration variable is set to 0 and the {@code * NETWORK_AVOID_BAD_WIFI setting is unset}. * * <p>This method requires the caller to hold the permission * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL} * * @param network The network to accept. * * @hide */ public void setAvoidUnvalidated(Network network) { try { mService.setAvoidUnvalidated(network); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Resets all connectivity manager settings back to factory defaults. * @hide Loading
core/java/android/net/IConnectivityManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ interface IConnectivityManager void releaseNetworkRequest(in NetworkRequest networkRequest); void setAcceptUnvalidated(in Network network, boolean accept, boolean always); void setAvoidUnvalidated(in Network network); int getRestoreDefaultNetworkDelay(int networkType); Loading
core/java/android/provider/Settings.java +7 −0 Original line number Diff line number Diff line Loading @@ -7489,6 +7489,13 @@ public final class Settings { /** * Whether to automatically switch away from wifi networks that lose Internet access. * Only meaningful if config_networkAvoidBadWifi is set to 0, otherwise the system always * avoids such networks. Valid values are: * * 0: Don't avoid bad wifi, don't prompt the user. Get stuck on bad wifi like it's 2013. * null: Ask the user whether to switch away from bad wifi. * 1: Avoid bad wifi. * * @hide */ public static final String NETWORK_AVOID_BAD_WIFI = "network_avoid_bad_wifi"; Loading
services/core/java/com/android/server/ConnectivityService.java +47 −15 Original line number Diff line number Diff line Loading @@ -371,6 +371,11 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28; /** * used to specify whether a network should not be penalized when it becomes unvalidated. */ private static final int EVENT_SET_AVOID_UNVALIDATED = 35; /** * used to ask the user to confirm a connection to an unvalidated network. * obj = network Loading Loading @@ -2712,6 +2717,12 @@ public class ConnectivityService extends IConnectivityManager.Stub accept ? 1 : 0, always ? 1: 0, network)); } @Override public void setAvoidUnvalidated(Network network) { enforceConnectivityInternalPermission(); mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_AVOID_UNVALIDATED, network)); } private void handleSetAcceptUnvalidated(Network network, boolean accept, boolean always) { if (DBG) log("handleSetAcceptUnvalidated network=" + network + " accept=" + accept + " always=" + always); Loading Loading @@ -2752,6 +2763,20 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void handleSetAvoidUnvalidated(Network network) { NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network); if (nai == null || nai.lastValidated) { // Nothing to do. The network either disconnected or revalidated. return; } if (!nai.avoidUnvalidated) { int oldScore = nai.getCurrentScore(); nai.avoidUnvalidated = true; rematchAllNetworksAndRequests(nai, oldScore); sendUpdatedScoreToFactories(nai); } } private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) { if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network); mHandler.sendMessageDelayed( Loading @@ -2759,28 +2784,31 @@ public class ConnectivityService extends IConnectivityManager.Stub PROMPT_UNVALIDATED_DELAY_MS); } private boolean mAvoidBadWifi; private boolean mAvoidBadWifi = true; public boolean avoidBadWifi() { return mAvoidBadWifi; } @VisibleForTesting public boolean updateAvoidBadWifi() { // There are two modes: either we always automatically avoid unvalidated wifi, or we show a // dialog and don't switch to it. The behaviour is controlled by the NETWORK_AVOID_BAD_WIFI // setting. If the setting has no value, then the value is taken from the config value, // which can be changed via OEM/carrier overlays. // // The only valid values for NETWORK_AVOID_BAD_WIFI are null and unset. Currently, the unit // test uses 0 in order to avoid having to mock out fetching the carrier setting. int defaultAvoidBadWifi = mContext.getResources().getInteger(R.integer.config_networkAvoidBadWifi); int avoid = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.NETWORK_AVOID_BAD_WIFI, defaultAvoidBadWifi); /** Whether the device or carrier configuration disables avoiding bad wifi by default. */ public boolean configRestrictsAvoidBadWifi() { return mContext.getResources().getInteger(R.integer.config_networkAvoidBadWifi) == 0; } /** Whether we should display a notification when wifi becomes unvalidated. */ public boolean shouldNotifyWifiUnvalidated() { return configRestrictsAvoidBadWifi() && Settings.Global.getString(mContext.getContentResolver(), Settings.Global.NETWORK_AVOID_BAD_WIFI) == null; } private boolean updateAvoidBadWifi() { boolean settingAvoidBadWifi = "1".equals(Settings.Global.getString( mContext.getContentResolver(), Settings.Global.NETWORK_AVOID_BAD_WIFI)); boolean prev = mAvoidBadWifi; mAvoidBadWifi = (avoid == 1); mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi(); return mAvoidBadWifi != prev; } Loading Loading @@ -2833,7 +2861,7 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkCapabilities nc = nai.networkCapabilities; if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc); if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && !avoidBadWifi()) { if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && shouldNotifyWifiUnvalidated()) { showValidationNotification(nai, NotificationType.LOST_INTERNET); } } Loading Loading @@ -2911,6 +2939,10 @@ public class ConnectivityService extends IConnectivityManager.Stub handleSetAcceptUnvalidated((Network) msg.obj, msg.arg1 != 0, msg.arg2 != 0); break; } case EVENT_SET_AVOID_UNVALIDATED: { handleSetAvoidUnvalidated((Network) msg.obj); break; } case EVENT_PROMPT_UNVALIDATED: { handlePromptUnvalidated((Network) msg.obj); break; Loading
services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +10 −6 Original line number Diff line number Diff line Loading @@ -140,12 +140,14 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { public boolean everValidated; // The result of the last validation attempt on this network (true if validated, false if not). // This bit exists only because we never unvalidate a network once it's been validated, and that // is because the network scoring and revalidation code does not (may not?) deal properly with // networks becoming unvalidated. // TODO: Fix the network scoring code, remove this, and rename everValidated to validated. public boolean lastValidated; // If true, becoming unvalidated will lower the network's score. This is only meaningful if the // system is configured not to do this for certain networks, e.g., if the // config_networkAvoidBadWifi option is set to 0 and the user has not overridden that via // Settings.Global.NETWORK_AVOID_BAD_WIFI. public boolean avoidUnvalidated; // Whether a captive portal was ever detected on this network. // This is a sticky bit; once set it is never cleared. public boolean everCaptivePortalDetected; Loading Loading @@ -426,8 +428,10 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // 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; boolean isWifi = networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); boolean avoidBadWifi = mConnService.avoidBadWifi() || avoidUnvalidated; return isWifi && !avoidBadWifi && everValidated; } // Get the current score for this Network. This may be modified from what the Loading