Move the request type from NetworkRequestInfo to NetworkRequest.

This will allow us to simplify code that deals with
NetworkRequests outside ConnectivityService.

Bug: 23113288
Change-Id: I9b3a859d0c68cad73d7f6baa4b584d13ffd2ae36
This commit is contained in:
Lorenzo Colitti
2016-07-01 13:19:21 +09:00
parent 2dfee89086
commit eafe85717c
2 changed files with 110 additions and 103 deletions

View File

@@ -47,15 +47,55 @@ public class NetworkRequest implements Parcelable {
public final int legacyType;
/**
* A NetworkRequest as used by the system can be one of three types:
*
* - LISTEN, for which the framework will issue callbacks about any
* and all networks that match the specified NetworkCapabilities,
*
* - REQUEST, capable of causing a specific network to be created
* first (e.g. a telephony DUN request), the framework will issue
* callbacks about the single, highest scoring current network
* (if any) that matches the specified NetworkCapabilities, or
*
* - TRACK_DEFAULT, a hybrid of the two designed such that the
* framework will issue callbacks for the single, highest scoring
* current network (if any) that matches the capabilities of the
* default Internet request (mDefaultRequest), but which cannot cause
* the framework to either create or retain the existence of any
* specific network.
*
* - The value NONE is used only by applications. When an application
* creates a NetworkRequest, it does not have a type; the type is set
* by the system depending on the method used to file the request
* (requestNetwork, registerNetworkCallback, etc.).
*
* @hide
*/
public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId) {
public static enum Type {
NONE,
LISTEN,
TRACK_DEFAULT,
REQUEST
};
/**
* The type of the request. This is only used by the system and is always NONE elsewhere.
*
* @hide
*/
public final Type type;
/**
* @hide
*/
public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId, Type type) {
if (nc == null) {
throw new NullPointerException();
}
requestId = rId;
networkCapabilities = nc;
this.legacyType = legacyType;
this.type = type;
}
/**
@@ -65,6 +105,7 @@ public class NetworkRequest implements Parcelable {
networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
requestId = that.requestId;
this.legacyType = that.legacyType;
this.type = that.type;
}
/**
@@ -90,7 +131,7 @@ public class NetworkRequest implements Parcelable {
final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
nc.maybeMarkCapabilitiesRestricted();
return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
ConnectivityManager.REQUEST_ID_UNSET);
ConnectivityManager.REQUEST_ID_UNSET, Type.NONE);
}
/**
@@ -223,6 +264,7 @@ public class NetworkRequest implements Parcelable {
dest.writeParcelable(networkCapabilities, flags);
dest.writeInt(legacyType);
dest.writeInt(requestId);
// type intentionally not preserved across process boundaries.
}
public static final Creator<NetworkRequest> CREATOR =
new Creator<NetworkRequest>() {
@@ -230,7 +272,8 @@ public class NetworkRequest implements Parcelable {
NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
int legacyType = in.readInt();
int requestId = in.readInt();
NetworkRequest result = new NetworkRequest(nc, legacyType, requestId);
// type intentionally not preserved across process boundaries.
NetworkRequest result = new NetworkRequest(nc, legacyType, requestId, Type.NONE);
return result;
}
public NetworkRequest[] newArray(int size) {
@@ -238,8 +281,27 @@ public class NetworkRequest implements Parcelable {
}
};
/**
* Returns true iff. the contained NetworkRequest is one that:
*
* - should be associated with at most one satisfying network
* at a time;
*
* - should cause a network to be kept up if it is the best network
* which can satisfy the NetworkRequest.
*
* For full detail of how isRequest() is used for pairing Networks with
* NetworkRequests read rematchNetworkAndRequests().
*
* @hide
*/
public boolean isRequest() {
return type == Type.TRACK_DEFAULT || type == Type.REQUEST;
}
public String toString() {
return "NetworkRequest [ id=" + requestId + ", legacyType=" + legacyType +
return "NetworkRequest [ " + type + " id=" + requestId +
(legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") +
", " + networkCapabilities.toString() + " ]";
}
@@ -248,6 +310,7 @@ public class NetworkRequest implements Parcelable {
NetworkRequest that = (NetworkRequest)obj;
return (that.legacyType == this.legacyType &&
that.requestId == this.requestId &&
that.type == this.type &&
((that.networkCapabilities == null && this.networkCapabilities == null) ||
(that.networkCapabilities != null &&
that.networkCapabilities.equals(this.networkCapabilities))));
@@ -255,6 +318,6 @@ public class NetworkRequest implements Parcelable {
public int hashCode() {
return requestId + (legacyType * 1013) +
(networkCapabilities.hashCode() * 1051);
(networkCapabilities.hashCode() * 1051) + type.hashCode() * 17;
}
}

View File

@@ -656,8 +656,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (DBG) log("ConnectivityService starting up");
mDefaultRequest = createInternetRequestForTransport(-1);
NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest,
new Binder(), NetworkRequestType.REQUEST);
NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder());
mNetworkRequests.put(mDefaultRequest, defaultNRI);
mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI);
@@ -808,7 +807,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (transportType > -1) {
netCap.addTransportType(transportType);
}
return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(),
NetworkRequest.Type.REQUEST);
}
// Used only for testing.
@@ -832,7 +832,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (enable) {
handleRegisterNetworkRequest(new NetworkRequestInfo(
null, mDefaultMobileDataRequest, new Binder(), NetworkRequestType.REQUEST));
null, mDefaultMobileDataRequest, new Binder()));
} else {
handleReleaseNetworkRequest(mDefaultMobileDataRequest, Process.SYSTEM_UID);
}
@@ -2014,10 +2014,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
return false;
}
private boolean isRequest(NetworkRequest request) {
return mNetworkRequests.get(request).isRequest();
}
// must be stateless - things change under us.
private class NetworkStateTrackerHandler extends Handler {
public NetworkStateTrackerHandler(Looper looper) {
@@ -2234,7 +2230,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (VDBG) log("NetworkFactory connected");
// A network factory has connected. Send it all current NetworkRequests.
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (!nri.isRequest()) continue;
if (!nri.request.isRequest()) continue;
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
(nai != null ? nai.getCurrentScore() : 0), 0, nri.request);
@@ -2375,7 +2371,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void handleRegisterNetworkRequest(NetworkRequestInfo nri) {
mNetworkRequests.put(nri.request, nri);
mNetworkRequestInfoLogs.log("REGISTER " + nri);
if (!nri.isRequest()) {
if (!nri.request.isRequest()) {
for (NetworkAgentInfo network : mNetworkAgentInfos.values()) {
if (nri.request.networkCapabilities.hasSignalStrength() &&
network.satisfiesImmutableCapabilitiesOf(nri.request)) {
@@ -2384,7 +2380,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
rematchAllNetworksAndRequests(null, 0);
if (nri.isRequest() && mNetworkForRequestId.get(nri.request.requestId) == null) {
if (nri.request.isRequest() && mNetworkForRequestId.get(nri.request.requestId) == null) {
sendUpdatedScoreToFactories(nri.request, 0);
}
}
@@ -2405,7 +2401,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
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) &&
if (nri.request.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
@@ -2429,7 +2425,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (DBG) log("Attempt to release unowned NetworkRequest " + request);
return;
}
if (VDBG || (DBG && nri.isRequest())) log("releasing NetworkRequest " + request);
if (VDBG || (DBG && nri.request.isRequest())) log("releasing " + request);
nri.unlinkDeathRecipient();
mNetworkRequests.remove(request);
synchronized (mUidToNetworkRequestCount) {
@@ -2445,7 +2441,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
mNetworkRequestInfoLogs.log("RELEASE " + nri);
if (nri.isRequest()) {
if (nri.request.isRequest()) {
// Find all networks that are satisfying this request and remove the request
// from their request lists.
// TODO - it's my understanding that for a request there is only a single
@@ -2487,7 +2483,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
for (int i = 0; i < nai.networkRequests.size(); i++) {
NetworkRequest otherRequest = nai.networkRequests.valueAt(i);
if (otherRequest.legacyType == nri.request.legacyType &&
isRequest(otherRequest)) {
otherRequest.isRequest()) {
if (DBG) log(" still have other legacy request - leaving");
doRemove = false;
}
@@ -3823,32 +3819,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
/**
* A NetworkRequest as registered by an application can be one of three
* types:
*
* - "listen", for which the framework will issue callbacks about any
* and all networks that match the specified NetworkCapabilities,
*
* - "request", capable of causing a specific network to be created
* first (e.g. a telephony DUN request), the framework will issue
* callbacks about the single, highest scoring current network
* (if any) that matches the specified NetworkCapabilities, or
*
* - "track the default network", a hybrid of the two designed such
* that the framework will issue callbacks for the single, highest
* scoring current network (if any) that matches the capabilities of
* the default Internet request (mDefaultRequest), but which cannot
* cause the framework to either create or retain the existence of
* any specific network.
*
*/
private static enum NetworkRequestType {
LISTEN,
TRACK_DEFAULT,
REQUEST
};
/**
* Tracks info about the requester.
* Also used to notice when the calling process dies so we can self-expire
@@ -3861,27 +3831,26 @@ public class ConnectivityService extends IConnectivityManager.Stub
final int mPid;
final int mUid;
final Messenger messenger;
private final NetworkRequestType mType;
NetworkRequestInfo(NetworkRequest r, PendingIntent pi, NetworkRequestType type) {
NetworkRequestInfo(NetworkRequest r, PendingIntent pi) {
request = r;
ensureRequestHasType();
mPendingIntent = pi;
messenger = null;
mBinder = null;
mPid = getCallingPid();
mUid = getCallingUid();
mType = type;
enforceRequestCountLimit();
}
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestType type) {
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder) {
super();
messenger = m;
request = r;
ensureRequestHasType();
mBinder = binder;
mPid = getCallingPid();
mUid = getCallingUid();
mType = type;
mPendingIntent = null;
enforceRequestCountLimit();
@@ -3892,6 +3861,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
private void ensureRequestHasType() {
if (request.type == NetworkRequest.Type.NONE) {
throw new IllegalArgumentException(
"All NetworkRequests in ConnectivityService must have a type");
}
}
private void enforceRequestCountLimit() {
synchronized (mUidToNetworkRequestCount) {
int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
@@ -3902,16 +3878,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
private String typeString() {
switch (mType) {
case LISTEN: return "Listen";
case REQUEST: return "Request";
case TRACK_DEFAULT: return "Track default";
default:
return "unknown type";
}
}
void unlinkDeathRecipient() {
if (mBinder != null) {
mBinder.unlinkToDeath(this, 0);
@@ -3924,29 +3890,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
releaseNetworkRequest(request);
}
/**
* Returns true iff. the contained NetworkRequest is one that:
*
* - should be associated with at most one satisfying network
* at a time;
*
* - should cause a network to be kept up if it is the only network
* which can satisfy the NetworkReqeust.
*
* For full detail of how isRequest() is used for pairing Networks with
* NetworkRequests read rematchNetworkAndRequests().
*
* TODO: Rename to something more properly descriptive.
*/
public boolean isRequest() {
return (mType == NetworkRequestType.TRACK_DEFAULT) ||
(mType == NetworkRequestType.REQUEST);
}
public String toString() {
return typeString() +
" from uid/pid:" + mUid + "/" + mPid +
" for " + request +
return "uid/pid:" + mUid + "/" + mPid + " " + request +
(mPendingIntent == null ? "" : " to trigger " + mPendingIntent);
}
}
@@ -3996,13 +3941,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
final NetworkRequestType type = (networkCapabilities == null)
? NetworkRequestType.TRACK_DEFAULT
: NetworkRequestType.REQUEST;
final NetworkRequest.Type type = (networkCapabilities == null)
? NetworkRequest.Type.TRACK_DEFAULT
: NetworkRequest.Type.REQUEST;
// If the requested networkCapabilities is null, take them instead from
// the default network request. This allows callers to keep track of
// the system default network.
if (type == NetworkRequestType.TRACK_DEFAULT) {
if (type == NetworkRequest.Type.TRACK_DEFAULT) {
networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities);
enforceAccessPermission();
} else {
@@ -4023,8 +3968,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
nextNetworkRequestId());
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder, type);
nextNetworkRequestId(), type);
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
if (DBG) log("requestNetwork for " + nri);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST, nri));
@@ -4094,9 +4039,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
ensureRequestableCapabilities(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
nextNetworkRequestId());
NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
NetworkRequestType.REQUEST);
nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
if (DBG) log("pendingRequest for " + nri);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_REQUEST_WITH_INTENT,
nri));
@@ -4146,9 +4090,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
NetworkRequest networkRequest = new NetworkRequest(
new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId());
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
NetworkRequestType.LISTEN);
new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(),
NetworkRequest.Type.LISTEN);
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
if (VDBG) log("listenForNetwork for " + nri);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -4164,9 +4108,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
NetworkRequest networkRequest = new NetworkRequest(
new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId());
NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation,
NetworkRequestType.LISTEN);
new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(),
NetworkRequest.Type.LISTEN);
NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation);
if (VDBG) log("pendingListenForNetwork for " + nri);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -4485,7 +4429,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
for (int i = 0; i < nai.networkRequests.size(); i++) {
NetworkRequest nr = nai.networkRequests.valueAt(i);
// Don't send listening requests to factories. b/17393458
if (!isRequest(nr)) continue;
if (!nr.isRequest()) continue;
sendUpdatedScoreToFactories(nr, nai.getCurrentScore());
}
}
@@ -4578,7 +4522,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
for (int i = 0; i < nai.networkRequests.size(); i++) {
NetworkRequest nr = nai.networkRequests.valueAt(i);
// Ignore listening requests.
if (!isRequest(nr)) continue;
if (!nr.isRequest()) continue;
loge("Dead network still had at least " + nr);
break;
}
@@ -4662,7 +4606,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// check if it satisfies the NetworkCapabilities
if (VDBG) log(" checking if request is satisfied: " + nri.request);
if (satisfies) {
if (!nri.isRequest()) {
if (!nri.request.isRequest()) {
// This is not a request, it's a callback listener.
// Add it to newNetwork regardless of score.
if (newNetwork.addRequest(nri.request)) addedRequests.add(nri);
@@ -4722,7 +4666,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNetworkForRequestId.remove(nri.request.requestId);
sendUpdatedScoreToFactories(nri.request, 0);
} else {
if (nri.isRequest()) {
if (nri.request.isRequest()) {
Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " +
newNetwork.name() +
" without updating mNetworkForRequestId or factories!");
@@ -4824,7 +4768,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// This is on top of the multiple intent sequencing referenced in the todo above.
for (int i = 0; i < newNetwork.networkRequests.size(); i++) {
NetworkRequest nr = newNetwork.networkRequests.valueAt(i);
if (nr.legacyType != TYPE_NONE && isRequest(nr)) {
if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
// legacy type tracker filters out repeat adds
mLegacyTypeTracker.add(nr.legacyType, newNetwork);
}