Fix listening NetworkRequests to listen for all networks.
This is a small change but should fix a number of functional problems:
1. When registering a listening NetworkRequest and when a Network is
validated, we should always add the listening NetworkRequest to the
Network's list of NetworkRequests if the Network satisfies the
NetworkRequest. Previously in both cases this was only done for
the highest scoring network. This enables the listening
NetworkRequest to listen for all networks, not just the highest
scoring network.
2. No longer add listening NetworkRequests to mNetworkForRequestId as
it doesn't make sense as it's a 1:1 mapping but listening
NetworkRequests to Networks is a many:many mapping.
3. Don't "keep" a Network that's finished validating when only a
listening NetworkRequest requests it.
4. Don't send updated scores to NetworkFactories from listening
NetworkRequests. NetworkFactories and NetworkAgents shouldn't
concern themselves with listening NetworkRequests.
bug:16680764
Change-Id: Iaba14263227771e4bd84ee4bce488beaef20a8a3
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 67c01e5..b69cdfa 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2089,13 +2089,21 @@
if (newCap.satisfiedByNetworkCapabilities(network.networkCapabilities)) {
if (VDBG) log("apparently satisfied. currentScore=" + network.currentScore);
if ((bestNetwork == null) || bestNetwork.currentScore < network.currentScore) {
- bestNetwork = network;
+ 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;
+ }
}
}
}
if (bestNetwork != null) {
if (VDBG) log("using " + bestNetwork.name());
- if (nri.isRequest && bestNetwork.networkInfo.isConnected()) {
+ 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();
@@ -2105,7 +2113,7 @@
mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
notifyNetworkCallback(bestNetwork, nri);
score = bestNetwork.currentScore;
- if (nri.isRequest && nri.request.legacyType != TYPE_NONE) {
+ if (nri.request.legacyType != TYPE_NONE) {
mLegacyTypeTracker.add(nri.request.legacyType, bestNetwork);
}
}
@@ -4386,6 +4394,10 @@
if (VDBG) log(" checking if request is satisfied: " + nri.request);
if (nri.request.networkCapabilities.satisfiedByNetworkCapabilities(
newNetwork.networkCapabilities)) {
+ if (!nri.isRequest) {
+ newNetwork.addRequest(nri.request);
+ continue;
+ }
// next check if it's better than any current network we're using for
// this request
if (VDBG) {