From ad50a1fed01e7c24531ad26d9de70c7b0127ea76 Mon Sep 17 00:00:00 2001 From: Paul Jensen Date: Fri, 5 Sep 2014 12:06:44 -0400 Subject: [PATCH] Update Inet state when NetworkMonitor re-evaluates a network. Previously the Inet state (the little exclamation mark beside the WiFi and Cellular bars) only transitioned from bad to good once. With this change it can transition back to bad (and later to good again) if a network re-evaluation is triggered, say by ConnectivityManager.reportBadNetwork. Also, avoid triggering re-evaluation in two unwanted cases. bug:16214361 Change-Id: I7856724249ffcbb0945276dcf45019876231fdaf --- .../android/server/ConnectivityService.java | 28 +++++++++-- .../server/connectivity/NetworkMonitor.java | 49 +++++++++++++++++-- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 7f104c0491851..55d8c09da02a5 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1785,6 +1785,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { } private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) { + if (nai.network == null) return false; final NetworkAgentInfo officialNai; synchronized (mNetworkForNetId) { officialNai = mNetworkForNetId.get(nai.network.netId); @@ -1924,12 +1925,16 @@ public class ConnectivityService extends IConnectivityManager.Stub { } break; } - case NetworkMonitor.EVENT_NETWORK_VALIDATED: { + case NetworkMonitor.EVENT_NETWORK_TESTED: { NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj; if (isLiveNetworkAgent(nai, "EVENT_NETWORK_VALIDATED")) { - if (DBG) log("Validated " + nai.name()); - nai.validated = true; - rematchNetworkAndRequests(nai); + boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID); + if (valid) { + if (DBG) log("Validated " + nai.name()); + nai.validated = true; + rematchNetworkAndRequests(nai); + } + updateInetCondition(nai, valid); } break; } @@ -4716,6 +4721,21 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } + private void updateInetCondition(NetworkAgentInfo nai, boolean valid) { + // Don't bother updating until we've graduated to validated at least once. + if (!nai.validated) return; + // For now only update icons for default connection. + // TODO: Update WiFi and cellular icons separately. b/17237507 + if (!isDefaultNetwork(nai)) return; + + int newInetCondition = valid ? 100 : 0; + // Don't repeat publish. + if (newInetCondition == mDefaultInetConditionPublished) return; + + mDefaultInetConditionPublished = newInetCondition; + sendInetConditionBroadcast(nai.networkInfo); + } + private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) { NetworkInfo.State state = newInfo.getState(); NetworkInfo oldInfo = null; diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index 96872a7ee1c14..9e33205689192 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -95,6 +95,18 @@ public class NetworkMonitor extends StateMachine { "android.net.netmon.captive_portal_logged_in"; private static final String LOGGED_IN_RESULT = "result"; + // After a network has been tested this result can be sent with EVENT_NETWORK_TESTED. + // The network should be used as a default internet connection. It was found to be: + // 1. a functioning network providing internet access, or + // 2. a captive portal and the user decided to use it as is. + public static final int NETWORK_TEST_RESULT_VALID = 0; + // After a network has been tested this result can be sent with EVENT_NETWORK_TESTED. + // The network should not be used as a default internet connection. It was found to be: + // 1. a captive portal and the user is prompted to sign-in, or + // 2. a captive portal and the user did not want to use it, or + // 3. a broken network (e.g. DNS failed, connect failed, HTTP request failed). + public static final int NETWORK_TEST_RESULT_INVALID = 1; + private static final int BASE = Protocol.BASE_NETWORK_MONITOR; /** @@ -104,10 +116,11 @@ public class NetworkMonitor extends StateMachine { public static final int CMD_NETWORK_CONNECTED = BASE + 1; /** - * Inform ConnectivityService that the network is validated. + * Inform ConnectivityService that the network has been tested. * obj = NetworkAgentInfo + * arg1 = One of the NETWORK_TESTED_RESULT_* constants. */ - public static final int EVENT_NETWORK_VALIDATED = BASE + 2; + public static final int EVENT_NETWORK_TESTED = BASE + 2; /** * Inform NetworkMonitor to linger a network. The Monitor should @@ -216,6 +229,9 @@ public class NetworkMonitor extends StateMachine { private String mServer; private boolean mIsCaptivePortalCheckEnabled = false; + // Set if the user explicitly selected "Do not use this network" in captive portal sign-in app. + private boolean mUserDoesNotWant = false; + public boolean systemReady = false; private State mDefaultState = new DefaultState(); @@ -289,10 +305,24 @@ public class NetworkMonitor extends StateMachine { } private class OfflineState extends State { + @Override + public void enter() { + mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, + NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo)); + } + @Override public boolean processMessage(Message message) { if (DBG) log(getName() + message.toString()); - return NOT_HANDLED; + switch (message.what) { + case CMD_FORCE_REEVALUATION: + // If the user has indicated they explicitly do not want to use this network, + // don't allow a reevaluation as this will be pointless and could result in + // the user being annoyed with repeated unwanted notifications. + return mUserDoesNotWant ? HANDLED : NOT_HANDLED; + default: + return NOT_HANDLED; + } } } @@ -300,8 +330,8 @@ public class NetworkMonitor extends StateMachine { @Override public void enter() { if (DBG) log("Validated"); - mConnectivityServiceHandler.sendMessage( - obtainMessage(EVENT_NETWORK_VALIDATED, mNetworkAgentInfo)); + mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, + NETWORK_TEST_RESULT_VALID, 0, mNetworkAgentInfo)); } @Override @@ -393,6 +423,8 @@ public class NetworkMonitor extends StateMachine { @Override public void enter() { + mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, + NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo)); // Wait for user to select sign-in notifcation. mUserRespondedBroadcastReceiver = new UserRespondedBroadcastReceiver( ++mUserPromptedToken); @@ -477,6 +509,7 @@ public class NetworkMonitor extends StateMachine { if (message.arg1 != mCaptivePortalLoggedInToken) return HANDLED; if (message.arg2 == 0) { + mUserDoesNotWant = true; // TODO: Should teardown network. transitionTo(mOfflineState); } else { @@ -544,6 +577,12 @@ public class NetworkMonitor extends StateMachine { mConnectivityServiceHandler.sendMessage( obtainMessage(EVENT_NETWORK_LINGER_COMPLETE, mNetworkAgentInfo)); return HANDLED; + case CMD_FORCE_REEVALUATION: + // Ignore reevaluation attempts when lingering. A reevaluation could result + // in a transition to the validated state which would abort the linger + // timeout. Lingering is the result of score assessment; validity is + // irrelevant. + return HANDLED; default: return NOT_HANDLED; }