From ab313f8443c7dade78b7ae53d18dba002a144425 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 26 Nov 2015 16:55:15 +0900 Subject: [PATCH] Don't show "Connected, no Internet" any longer than necessary. Currently, both the wifi detail view in Quick Settings and the wifi settings screen show "connected, no internet" for a few seconds after a network connects. This makes it seem that network validation is slow, even though usually it only takes tens or hundreds of milliseconds. Fix this by updating the access point list when we receive an onCapabilitiesChanged NetworkCallback for the current wifi connection. This also allows us to stop listening to the RSSI_CHANGED_ACTION broadcast, because: 1. WifiStateMachine only ever sends out that broadcast just after calling updateCapabilities, which causes an onCapabilitiesChanged callback to be received. 2. We don't use any of the extras in the RSSI_CHANGED_ACTION broadcast, only call updateNetworkInfo, which we do on every onCapabilitiesChanged callback anyway. While I'm at it, move a variable assignment around to improve clarity. Change-Id: I57d3a13754ba4d8c6d58c566713d3f07d0ed2476 --- .../android/settingslib/wifi/WifiTracker.java | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index e28b2e5e530af..2b1c66d99994d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -19,8 +19,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; +import android.net.NetworkRequest; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; @@ -62,6 +66,9 @@ public class WifiTracker { private final Context mContext; private final WifiManager mWifiManager; private final IntentFilter mFilter; + private final ConnectivityManager mConnectivityManager; + private final NetworkRequest mNetworkRequest; + private WifiTrackerNetworkCallback mNetworkCallback; private final AtomicBoolean mConnected = new AtomicBoolean(false); private final WifiListener mListener; @@ -104,13 +111,15 @@ public class WifiTracker { public WifiTracker(Context context, WifiListener wifiListener, Looper workerLooper, boolean includeSaved, boolean includeScans, boolean includePasspoints) { this(context, wifiListener, workerLooper, includeSaved, includeScans, includePasspoints, - (WifiManager) context.getSystemService(Context.WIFI_SERVICE), Looper.myLooper()); + context.getSystemService(WifiManager.class), + context.getSystemService(ConnectivityManager.class), Looper.myLooper()); } @VisibleForTesting WifiTracker(Context context, WifiListener wifiListener, Looper workerLooper, boolean includeSaved, boolean includeScans, boolean includePasspoints, - WifiManager wifiManager, Looper currentLooper) { + WifiManager wifiManager, ConnectivityManager connectivityManager, + Looper currentLooper) { if (!includeSaved && !includeScans) { throw new IllegalArgumentException("Must include either saved or scans"); } @@ -127,6 +136,7 @@ public class WifiTracker { mIncludeScans = includeScans; mIncludePasspoints = includePasspoints; mListener = wifiListener; + mConnectivityManager = connectivityManager; // check if verbose logging has been turned on or off sVerboseLogging = mWifiManager.getVerboseLoggingLevel(); @@ -139,7 +149,11 @@ public class WifiTracker { mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + + mNetworkRequest = new NetworkRequest.Builder() + .clearCapabilities() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); } /** @@ -192,6 +206,9 @@ public class WifiTracker { resumeScanning(); if (!mRegistered) { mContext.registerReceiver(mReceiver, mFilter); + // NetworkCallback objects cannot be reused. http://b/20701525 . + mNetworkCallback = new WifiTrackerNetworkCallback(); + mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback); mRegistered = true; } } @@ -207,6 +224,7 @@ public class WifiTracker { mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS); mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_NETWORK_INFO); mContext.unregisterReceiver(mReceiver); + mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); mRegistered = false; } pauseScanning(); @@ -461,12 +479,12 @@ public class WifiTracker { mMainHandler.sendEmptyMessage(MainHandler.MSG_RESUME_SCANNING); } - mLastInfo = mWifiManager.getConnectionInfo(); if (networkInfo != null) { mLastNetworkInfo = networkInfo; } WifiConfiguration connectionConfig = null; + mLastInfo = mWifiManager.getConnectionInfo(); if (mLastInfo != null) { connectionConfig = getWifiConfigurationForNetworkId(mLastInfo.getNetworkId()); } @@ -532,12 +550,21 @@ public class WifiTracker { mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_ACCESS_POINTS); mWorkHandler.obtainMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO, info) .sendToTarget(); - } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) { - mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO); } } }; + private final class WifiTrackerNetworkCallback extends ConnectivityManager.NetworkCallback { + public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) { + if (network.equals(mWifiManager.getCurrentNetwork())) { + // We don't send a NetworkInfo object along with this message, because even if we + // fetch one from ConnectivityManager, it might be older than the most recent + // NetworkInfo message we got via a WIFI_STATE_CHANGED broadcast. + mWorkHandler.sendEmptyMessage(WorkHandler.MSG_UPDATE_NETWORK_INFO); + } + } + } + private final class MainHandler extends Handler { private static final int MSG_CONNECTED_CHANGED = 0; private static final int MSG_WIFI_STATE_CHANGED = 1;