Update to unneeded for multilayered requests

Update to ConnectivityService.unneeded in order to support multilayered
requests.

Bug: 173432311
Bug: 171991028
Test: atest FrameworksNetTests
atest FrameworksNetIntegrationTests
atest CtsNetTestCasesLatestSdk

Change-Id: If040d61e33d86a9f9bbc7d50ead596d210a4f82c
This commit is contained in:
James Mattis
2020-11-16 16:46:28 -08:00
parent 39b703a229
commit 3d2298960a

View File

@@ -3560,15 +3560,42 @@ public class ConnectivityService extends IConnectivityManager.Stub
return false; return false;
} }
for (NetworkRequestInfo nri : mNetworkRequests.values()) { for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (reason == UnneededFor.LINGER && nri.request.isBackgroundRequest()) { if (reason == UnneededFor.LINGER
&& !nri.isMultilayerRequest()
&& nri.mRequests.get(0).isBackgroundRequest()) {
// Background requests don't affect lingering. // Background requests don't affect lingering.
continue; continue;
} }
if (isNetworkPotentialSatisfier(nai, nri)) {
return false;
}
}
return true;
}
private boolean isNetworkPotentialSatisfier(
@NonNull final NetworkAgentInfo candidate, @NonNull final NetworkRequestInfo nri) {
// listen requests won't keep up a network satisfying it. If this is not a multilayer
// request, we can return immediately. For multilayer requests, we have to check to see if
// any of the multilayer requests may have a potential satisfier.
if (!nri.isMultilayerRequest() && nri.mRequests.get(0).isListen()) {
return false;
}
for (final NetworkRequest req : nri.mRequests) {
// As non-multilayer listen requests have already returned, the below would only happen
// for a multilayer request therefore continue to the next request if available.
if (req.isListen()) {
continue;
}
// If this Network is already the highest scoring Network for a request, or if // If this Network is already the highest scoring Network for a request, or if
// there is hope for it to become one if it validated, then it is needed. // there is hope for it to become one if it validated, then it is needed.
if (nri.request.isRequest() && nai.satisfies(nri.request) && if (candidate.satisfies(req)) {
(nai.isSatisfyingRequest(nri.request.requestId) || // As soon as a network is found that satisfies a request, return. Specifically for
// multilayer requests, returning as soon as a NetworkAgentInfo satisfies a request
// is important so as to not evaluate lower priority requests further in
// nri.mRequests.
final boolean isNetworkNeeded = candidate.isSatisfyingRequest(req.requestId)
// Note that this catches two important cases: // Note that this catches two important cases:
// 1. Unvalidated cellular will not be reaped when unvalidated WiFi // 1. Unvalidated cellular will not be reaped when unvalidated WiFi
// is currently satisfying the request. This is desirable when // is currently satisfying the request. This is desirable when
@@ -3576,13 +3603,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
// 2. Unvalidated WiFi will not be reaped when validated cellular // 2. Unvalidated WiFi will not be reaped when validated cellular
// is currently satisfying the request. This is desirable when // is currently satisfying the request. This is desirable when
// WiFi ends up validating and out scoring cellular. // WiFi ends up validating and out scoring cellular.
nri.mSatisfier.getCurrentScore() || nri.mSatisfier.getCurrentScore()
< nai.getCurrentScoreAsValidated())) { < candidate.getCurrentScoreAsValidated();
return isNetworkNeeded;
}
}
return false; return false;
} }
}
return true;
}
private NetworkRequestInfo getNriForAppRequest( private NetworkRequestInfo getNriForAppRequest(
NetworkRequest request, int callingUid, String requestedOperation) { NetworkRequest request, int callingUid, String requestedOperation) {
@@ -5451,6 +5479,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
this(r, null); this(r, null);
} }
boolean isMultilayerRequest() {
return mRequests.size() > 1;
}
private List<NetworkRequest> initializeRequests(NetworkRequest r) { private List<NetworkRequest> initializeRequests(NetworkRequest r) {
final ArrayList<NetworkRequest> tempRequests = new ArrayList<>(); final ArrayList<NetworkRequest> tempRequests = new ArrayList<>();
tempRequests.add(new NetworkRequest(r)); tempRequests.add(new NetworkRequest(r));