summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Paul Jensen <pauljensen@google.com> 2014-11-25 15:26:53 -0500
committer Paul Jensen <pauljensen@google.com> 2014-12-02 09:26:17 -0500
commit0cc1732cfb9d68779449b4c12661b4df6bfc720b (patch)
tree6a3b2b1209bba75033958762630cc21dfbf7c607
parentc3056190ae1a6d29ce5943d45ab4711e1e49620c (diff)
Remember to cancel lingering when a network again satsifies a NetworkRequest.
When WiFi's score drops and then comes back up we would previously linger WiFi but forget to cancel the linger timeout, so 30s later WiFi would unexpectedly tear down. Also, make sure this is only done for created Networks as "created" is the signal to initialy match Networks and requests. bug:18169560 Change-Id: Ia69b110f6473371e556c60b950253758e023b7aa
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java66
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java6
2 files changed, 36 insertions, 36 deletions
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5eec0b7692f9..fe6cb70fb208 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2043,6 +2043,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ // Cancel any lingering so the linger timeout doesn't teardown a network.
+ // This should be called when a network begins satisfying a NetworkRequest.
+ // Note: depending on what state the NetworkMonitor is in (e.g.,
+ // if it's awaiting captive portal login, or if validation failed), this
+ // may trigger a re-evaluation of the network.
+ private void unlinger(NetworkAgentInfo nai) {
+ if (VDBG) log("Canceling linger of " + nai.name());
+ nai.networkLingered.clear();
+ nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
+ }
+
private void handleAsyncChannelHalfConnect(Message msg) {
AsyncChannel ac = (AsyncChannel) msg.obj;
if (mNetworkFactoryInfos.containsKey(msg.replyTo)) {
@@ -2078,6 +2089,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
}
+
private void handleAsyncChannelDisconnected(Message msg) {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) {
@@ -2127,11 +2139,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNetworkForRequestId.remove(request.requestId);
sendUpdatedScoreToFactories(request, 0);
NetworkAgentInfo alternative = null;
- for (Map.Entry entry : mNetworkAgentInfos.entrySet()) {
- NetworkAgentInfo existing = (NetworkAgentInfo)entry.getValue();
- if (existing.networkInfo.isConnected() &&
- request.networkCapabilities.satisfiedByNetworkCapabilities(
- existing.networkCapabilities) &&
+ for (NetworkAgentInfo existing : mNetworkAgentInfos.values()) {
+ if (existing.satisfies(request) &&
(alternative == null ||
alternative.getCurrentScore() < existing.getCurrentScore())) {
alternative = existing;
@@ -2151,8 +2160,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
requestNetworkTransitionWakelock(nai.name());
}
for (NetworkAgentInfo networkToActivate : toActivate) {
- networkToActivate.networkLingered.clear();
- networkToActivate.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
+ unlinger(networkToActivate);
rematchNetworkAndRequests(networkToActivate, false);
}
}
@@ -2187,44 +2195,35 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void handleRegisterNetworkRequest(Message msg) {
final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
- final NetworkCapabilities newCap = nri.request.networkCapabilities;
- int score = 0;
mNetworkRequests.put(nri.request, nri);
+ // TODO: This logic may be better replaced with a call to rematchNetworkAndRequests
+
// Check for the best currently alive network that satisfies this request
NetworkAgentInfo bestNetwork = null;
for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
if (DBG) log("handleRegisterNetworkRequest checking " + network.name());
- if (newCap.satisfiedByNetworkCapabilities(network.networkCapabilities)) {
+ if (network.satisfies(nri.request)) {
if (DBG) log("apparently satisfied. currentScore=" + network.getCurrentScore());
- if ((bestNetwork == null) ||
+ if (!nri.isRequest) {
+ // Not setting bestNetwork here as a listening NetworkRequest may be
+ // satisfied by multiple Networks. Instead the request is added to
+ // each satisfying Network and notified about each.
+ network.addRequest(nri.request);
+ notifyNetworkCallback(network, nri);
+ } else if (bestNetwork == null ||
bestNetwork.getCurrentScore() < network.getCurrentScore()) {
- if (!nri.isRequest) {
- // Not setting bestNetwork here as a listening NetworkRequest may be
- // satisfied by multiple Networks. Instead the request is added to
- // each satisfying Network and notified about each.
- network.addRequest(nri.request);
- notifyNetworkCallback(network, nri);
- } else {
- bestNetwork = network;
- }
+ bestNetwork = network;
}
}
}
if (bestNetwork != null) {
if (DBG) log("using " + bestNetwork.name());
- if (bestNetwork.networkInfo.isConnected()) {
- // Cancel any lingering so the linger timeout doesn't teardown this network
- // even though we have a request for it.
- bestNetwork.networkLingered.clear();
- bestNetwork.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
- }
- // TODO: This logic may be better replaced with a call to rematchNetworkAndRequests
+ unlinger(bestNetwork);
bestNetwork.addRequest(nri.request);
mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
notifyNetworkCallback(bestNetwork, nri);
- score = bestNetwork.getCurrentScore();
if (nri.request.legacyType != TYPE_NONE) {
mLegacyTypeTracker.add(nri.request.legacyType, bestNetwork);
}
@@ -2232,6 +2231,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (nri.isRequest) {
if (DBG) log("sending new NetworkRequest to factories");
+ final int score = bestNetwork == null ? 0 : bestNetwork.getCurrentScore();
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
0, nri.request);
@@ -3929,8 +3929,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// check if it satisfies the NetworkCapabilities
if (VDBG) log(" checking if request is satisfied: " + nri.request);
- if (nri.request.networkCapabilities.satisfiedByNetworkCapabilities(
- newNetwork.networkCapabilities)) {
+ if (newNetwork.satisfies(nri.request)) {
if (!nri.isRequest) {
// This is not a request, it's a callback listener.
// Add it to newNetwork regardless of score.
@@ -4010,12 +4009,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_LINGER);
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING);
} else {
- // not going to linger, so kill the list of linger networks.. only
- // notify them of linger if it happens as the result of gaining another,
- // but if they transition and old network stays up, don't tell them of linger
- // or very delayed loss
- nai.networkLingered.clear();
- if (VDBG) log("Lingered for " + nai.name() + " cleared");
+ unlinger(nai);
}
}
if (keep) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 4af920affad2..6feeb7cff2f2 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -96,6 +96,12 @@ public class NetworkAgentInfo {
networkRequests.put(networkRequest.requestId, networkRequest);
}
+ // Does this network satisfy request?
+ public boolean satisfies(NetworkRequest request) {
+ return created &&
+ request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
+ }
+
public boolean isVPN() {
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
}