Updates to handler logic for multilayer requests
Updates to ConnectivityService network request handler's logic to support (or disallow support of) multilayer network requests. Bug: 175239920 Bug: 171991028 Test: atest FrameworksNetTests atest NetworkStackTests atest FrameworksNetIntegrationTests atest NetworkStackIntegrationTests atest CtsNetTestCasesLatestSdk Change-Id: Ic67cff950d72745d6508a0a037bd33f932d5132c
This commit is contained in:
@@ -3513,42 +3513,63 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRegisterNetworkRequestWithIntent(Message msg) {
|
private void handleRegisterNetworkRequestWithIntent(@NonNull final Message msg) {
|
||||||
final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
|
final NetworkRequestInfo nri = (NetworkRequestInfo) (msg.obj);
|
||||||
|
// handleRegisterNetworkRequestWithIntent() doesn't apply to multilayer requests.
|
||||||
NetworkRequestInfo existingRequest = findExistingNetworkRequestInfo(nri.mPendingIntent);
|
ensureNotMultilayerRequest(nri, "handleRegisterNetworkRequestWithIntent");
|
||||||
|
final NetworkRequestInfo existingRequest =
|
||||||
|
findExistingNetworkRequestInfo(nri.mPendingIntent);
|
||||||
if (existingRequest != null) { // remove the existing request.
|
if (existingRequest != null) { // remove the existing request.
|
||||||
if (DBG) log("Replacing " + existingRequest.request + " with "
|
if (DBG) {
|
||||||
+ nri.request + " because their intents matched.");
|
log("Replacing " + existingRequest.mRequests.get(0) + " with "
|
||||||
handleReleaseNetworkRequest(existingRequest.request, getCallingUid(),
|
+ nri.mRequests.get(0) + " because their intents matched.");
|
||||||
|
}
|
||||||
|
handleReleaseNetworkRequest(existingRequest.mRequests.get(0), getCallingUid(),
|
||||||
/* callOnUnavailable */ false);
|
/* callOnUnavailable */ false);
|
||||||
}
|
}
|
||||||
handleRegisterNetworkRequest(nri);
|
handleRegisterNetworkRequest(nri);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
|
private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) {
|
||||||
ensureRunningOnConnectivityServiceThread();
|
ensureRunningOnConnectivityServiceThread();
|
||||||
mNetworkRequests.put(nri.request, nri);
|
|
||||||
mNetworkRequestInfoLogs.log("REGISTER " + nri);
|
mNetworkRequestInfoLogs.log("REGISTER " + nri);
|
||||||
if (nri.request.isListen()) {
|
for (final NetworkRequest req : nri.mRequests) {
|
||||||
for (NetworkAgentInfo network : mNetworkAgentInfos) {
|
mNetworkRequests.put(req, nri);
|
||||||
if (nri.request.networkCapabilities.hasSignalStrength() &&
|
if (req.isListen()) {
|
||||||
network.satisfiesImmutableCapabilitiesOf(nri.request)) {
|
for (final NetworkAgentInfo network : mNetworkAgentInfos) {
|
||||||
updateSignalStrengthThresholds(network, "REGISTER", nri.request);
|
if (req.networkCapabilities.hasSignalStrength()
|
||||||
|
&& network.satisfiesImmutableCapabilitiesOf(req)) {
|
||||||
|
updateSignalStrengthThresholds(network, "REGISTER", req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rematchAllNetworksAndRequests();
|
rematchAllNetworksAndRequests();
|
||||||
if (nri.request.isRequest() && nri.getSatisfier() == null) {
|
// If an active request exists, return as its score has already been sent if needed.
|
||||||
sendUpdatedScoreToFactories(nri.request, null);
|
if (null != nri.getActiveRequest()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As this request was not satisfied on rematch and thus never had any scores sent to the
|
||||||
|
// factories, send null now for each request of type REQUEST.
|
||||||
|
for (final NetworkRequest req : nri.mRequests) {
|
||||||
|
if (!req.isRequest()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sendUpdatedScoreToFactories(req, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleReleaseNetworkRequestWithIntent(PendingIntent pendingIntent,
|
private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent,
|
||||||
int callingUid) {
|
final int callingUid) {
|
||||||
NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
|
final NetworkRequestInfo nri = findExistingNetworkRequestInfo(pendingIntent);
|
||||||
if (nri != null) {
|
if (nri != null) {
|
||||||
handleReleaseNetworkRequest(nri.request, callingUid, /* callOnUnavailable */ false);
|
// handleReleaseNetworkRequestWithIntent() paths don't apply to multilayer requests.
|
||||||
|
ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequestWithIntent");
|
||||||
|
handleReleaseNetworkRequest(
|
||||||
|
nri.mRequests.get(0),
|
||||||
|
callingUid,
|
||||||
|
/* callOnUnavailable */ false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3652,30 +3673,45 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return nri;
|
return nri;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
|
private void ensureNotMultilayerRequest(@NonNull final NetworkRequestInfo nri,
|
||||||
|
final String callingMethod) {
|
||||||
|
if (nri.isMultilayerRequest()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
callingMethod + " does not support multilayer requests.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleTimedOutNetworkRequest(@NonNull final NetworkRequestInfo nri) {
|
||||||
ensureRunningOnConnectivityServiceThread();
|
ensureRunningOnConnectivityServiceThread();
|
||||||
if (mNetworkRequests.get(nri.request) == null) {
|
// handleTimedOutNetworkRequest() is part of the requestNetwork() flow which works off of a
|
||||||
|
// single NetworkRequest and thus does not apply to multilayer requests.
|
||||||
|
ensureNotMultilayerRequest(nri, "handleTimedOutNetworkRequest");
|
||||||
|
if (mNetworkRequests.get(nri.mRequests.get(0)) == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nri.getSatisfier() != null) {
|
if (nri.getSatisfier() != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (VDBG || (DBG && nri.request.isRequest())) {
|
if (VDBG || (DBG && nri.mRequests.get(0).isRequest())) {
|
||||||
log("releasing " + nri.request + " (timeout)");
|
log("releasing " + nri.mRequests.get(0) + " (timeout)");
|
||||||
}
|
}
|
||||||
handleRemoveNetworkRequest(nri);
|
handleRemoveNetworkRequest(nri);
|
||||||
callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
|
callCallbackForRequest(
|
||||||
|
nri, null, ConnectivityManager.CALLBACK_UNAVAIL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid,
|
private void handleReleaseNetworkRequest(@NonNull final NetworkRequest request,
|
||||||
boolean callOnUnavailable) {
|
final int callingUid,
|
||||||
|
final boolean callOnUnavailable) {
|
||||||
final NetworkRequestInfo nri =
|
final NetworkRequestInfo nri =
|
||||||
getNriForAppRequest(request, callingUid, "release NetworkRequest");
|
getNriForAppRequest(request, callingUid, "release NetworkRequest");
|
||||||
if (nri == null) {
|
if (nri == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (VDBG || (DBG && nri.request.isRequest())) {
|
// handleReleaseNetworkRequest() paths don't apply to multilayer requests.
|
||||||
log("releasing " + nri.request + " (release request)");
|
ensureNotMultilayerRequest(nri, "handleReleaseNetworkRequest");
|
||||||
|
if (VDBG || (DBG && request.isRequest())) {
|
||||||
|
log("releasing " + request + " (release request)");
|
||||||
}
|
}
|
||||||
handleRemoveNetworkRequest(nri);
|
handleRemoveNetworkRequest(nri);
|
||||||
if (callOnUnavailable) {
|
if (callOnUnavailable) {
|
||||||
@@ -5451,12 +5487,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks info about the requester.
|
* Tracks info about the requester.
|
||||||
* Also used to notice when the calling process dies so we can self-expire
|
* Also used to notice when the calling process dies so as to self-expire
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected class NetworkRequestInfo implements IBinder.DeathRecipient {
|
protected class NetworkRequestInfo implements IBinder.DeathRecipient {
|
||||||
final List<NetworkRequest> mRequests;
|
final List<NetworkRequest> mRequests;
|
||||||
final NetworkRequest request;
|
|
||||||
|
|
||||||
// mSatisfier and mActiveRequest rely on one another therefore set them together.
|
// mSatisfier and mActiveRequest rely on one another therefore set them together.
|
||||||
void setSatisfier(
|
void setSatisfier(
|
||||||
@@ -5492,7 +5527,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
final Messenger messenger;
|
final Messenger messenger;
|
||||||
|
|
||||||
NetworkRequestInfo(NetworkRequest r, PendingIntent pi) {
|
NetworkRequestInfo(NetworkRequest r, PendingIntent pi) {
|
||||||
request = r;
|
|
||||||
mRequests = initializeRequests(r);
|
mRequests = initializeRequests(r);
|
||||||
ensureAllNetworkRequestsHaveType(mRequests);
|
ensureAllNetworkRequestsHaveType(mRequests);
|
||||||
mPendingIntent = pi;
|
mPendingIntent = pi;
|
||||||
@@ -5506,7 +5540,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) {
|
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) {
|
||||||
super();
|
super();
|
||||||
messenger = m;
|
messenger = m;
|
||||||
request = r;
|
|
||||||
mRequests = initializeRequests(r);
|
mRequests = initializeRequests(r);
|
||||||
ensureAllNetworkRequestsHaveType(mRequests);
|
ensureAllNetworkRequestsHaveType(mRequests);
|
||||||
mBinder = binder;
|
mBinder = binder;
|
||||||
@@ -5961,13 +5994,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void declareNetworkRequestUnfulfillable(NetworkRequest request) {
|
public void declareNetworkRequestUnfulfillable(@NonNull final NetworkRequest request) {
|
||||||
if (request.hasTransport(TRANSPORT_TEST)) {
|
if (request.hasTransport(TRANSPORT_TEST)) {
|
||||||
enforceNetworkFactoryOrTestNetworksPermission();
|
enforceNetworkFactoryOrTestNetworksPermission();
|
||||||
} else {
|
} else {
|
||||||
enforceNetworkFactoryPermission();
|
enforceNetworkFactoryPermission();
|
||||||
}
|
}
|
||||||
mHandler.post(() -> handleReleaseNetworkRequest(request, mDeps.getCallingUid(), true));
|
final NetworkRequestInfo nri = mNetworkRequests.get(request);
|
||||||
|
if (nri != null) {
|
||||||
|
// declareNetworkRequestUnfulfillable() paths don't apply to multilayer requests.
|
||||||
|
ensureNotMultilayerRequest(nri, "declareNetworkRequestUnfulfillable");
|
||||||
|
mHandler.post(() -> handleReleaseNetworkRequest(
|
||||||
|
nri.mRequests.get(0), mDeps.getCallingUid(), true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Accessed on multiple threads, must be synchronized on itself.
|
// NOTE: Accessed on multiple threads, must be synchronized on itself.
|
||||||
|
|||||||
Reference in New Issue
Block a user