Merge "Don't blindly teardown unvalidated networks when releasing NetworkRequests." into lmp-mr1-dev
This commit is contained in:
@@ -2271,6 +2271,46 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is nai unneeded by all NetworkRequests (and should be disconnected)?
|
||||||
|
// For validated Networks this is simply whether it is satsifying any NetworkRequests.
|
||||||
|
// For unvalidated Networks this is whether it is satsifying any NetworkRequests or
|
||||||
|
// were it to become validated, would it have a chance of satisfying any NetworkRequests.
|
||||||
|
private boolean unneeded(NetworkAgentInfo nai) {
|
||||||
|
if (!nai.created || nai.isVPN()) return false;
|
||||||
|
boolean unneeded = true;
|
||||||
|
if (nai.everValidated) {
|
||||||
|
for (int i = 0; i < nai.networkRequests.size() && unneeded; i++) {
|
||||||
|
final NetworkRequest nr = nai.networkRequests.valueAt(i);
|
||||||
|
try {
|
||||||
|
if (isRequest(nr)) unneeded = false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
loge("Request " + nr + " not found in mNetworkRequests.");
|
||||||
|
loge(" it came from request list of " + nai.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||||
|
// 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.
|
||||||
|
if (nri.isRequest && nai.satisfies(nri.request) &&
|
||||||
|
(nai.networkRequests.get(nri.request.requestId) != null ||
|
||||||
|
// Note that this catches two important cases:
|
||||||
|
// 1. Unvalidated cellular will not be reaped when unvalidated WiFi
|
||||||
|
// is currently satisfying the request. This is desirable when
|
||||||
|
// cellular ends up validating but WiFi does not.
|
||||||
|
// 2. Unvalidated WiFi will not be reaped when validated cellular
|
||||||
|
// is currently satsifying the request. This is desirable when
|
||||||
|
// WiFi ends up validating and out scoring cellular.
|
||||||
|
mNetworkForRequestId.get(nri.request.requestId).getCurrentScore() <
|
||||||
|
nai.getCurrentScoreAsValidated())) {
|
||||||
|
unneeded = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unneeded;
|
||||||
|
}
|
||||||
|
|
||||||
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
|
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
|
||||||
NetworkRequestInfo nri = mNetworkRequests.get(request);
|
NetworkRequestInfo nri = mNetworkRequests.get(request);
|
||||||
if (nri != null) {
|
if (nri != null) {
|
||||||
@@ -2292,16 +2332,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
", leaving " + nai.networkRequests.size() +
|
", leaving " + nai.networkRequests.size() +
|
||||||
" requests.");
|
" requests.");
|
||||||
}
|
}
|
||||||
// check if has any requests remaining and if not,
|
if (unneeded(nai)) {
|
||||||
// disconnect (unless it's a VPN).
|
|
||||||
boolean keep = nai.isVPN();
|
|
||||||
for (int i = 0; i < nai.networkRequests.size() && !keep; i++) {
|
|
||||||
NetworkRequest r = nai.networkRequests.valueAt(i);
|
|
||||||
if (isRequest(r)) keep = true;
|
|
||||||
}
|
|
||||||
if (!keep) {
|
|
||||||
if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
|
if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
|
||||||
nai.asyncChannel.disconnect();
|
teardownUnneededNetwork(nai);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4056,19 +4089,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
// Linger any networks that are no longer needed.
|
// Linger any networks that are no longer needed.
|
||||||
for (NetworkAgentInfo nai : affectedNetworks) {
|
for (NetworkAgentInfo nai : affectedNetworks) {
|
||||||
boolean teardown = !nai.isVPN() && nai.everValidated;
|
if (nai.everValidated && unneeded(nai)) {
|
||||||
for (int i = 0; i < nai.networkRequests.size() && teardown; i++) {
|
|
||||||
NetworkRequest nr = nai.networkRequests.valueAt(i);
|
|
||||||
try {
|
|
||||||
if (isRequest(nr)) {
|
|
||||||
teardown = false;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
loge("Request " + nr + " not found in mNetworkRequests.");
|
|
||||||
loge(" it came from request list of " + nai.name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (teardown) {
|
|
||||||
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_LINGER);
|
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_LINGER);
|
||||||
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING);
|
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING);
|
||||||
} else {
|
} else {
|
||||||
@@ -4168,27 +4189,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) {
|
if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) {
|
||||||
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
||||||
if (!nai.created || nai.everValidated || nai.isVPN()) continue;
|
if (!nai.everValidated && unneeded(nai)) {
|
||||||
boolean reap = true;
|
|
||||||
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
|
||||||
// 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 don't reap it.
|
|
||||||
if (nri.isRequest && nai.satisfies(nri.request) &&
|
|
||||||
(nai.networkRequests.get(nri.request.requestId) != null ||
|
|
||||||
// Note that this catches two important cases:
|
|
||||||
// 1. Unvalidated cellular will not be reaped when unvalidated WiFi
|
|
||||||
// is currently satisfying the request. This is desirable when
|
|
||||||
// cellular ends up validating but WiFi does not.
|
|
||||||
// 2. Unvalidated WiFi will not be reaped when validated cellular
|
|
||||||
// is currently satsifying the request. This is desirable when
|
|
||||||
// WiFi ends up validating and out scoring cellular.
|
|
||||||
mNetworkForRequestId.get(nri.request.requestId).getCurrentScore() <
|
|
||||||
nai.getCurrentScoreAsValidated())) {
|
|
||||||
reap = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reap) {
|
|
||||||
if (DBG) log("Reaping " + nai.name());
|
if (DBG) log("Reaping " + nai.name());
|
||||||
teardownUnneededNetwork(nai);
|
teardownUnneededNetwork(nai);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user