Merge changes from topic 'networkrequest_private' into nyc-mr1-dev
* changes:
Make the NetworkRequest list private to NetworkAgentInfo.
Move the request type from NetworkRequestInfo to NetworkRequest.
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index f1edcbe..5ac24d5 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -47,15 +47,55 @@
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 @@
networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
requestId = that.requestId;
this.legacyType = that.legacyType;
+ this.type = that.type;
}
/**
@@ -90,7 +131,7 @@
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 @@
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 @@
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 @@
}
};
+ /**
+ * 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 @@
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 int hashCode() {
return requestId + (legacyType * 1013) +
- (networkCapabilities.hashCode() * 1051);
+ (networkCapabilities.hashCode() * 1051) + type.hashCode() * 17;
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1a7a2bf..7abb967 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -656,8 +656,7 @@
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 @@
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 @@
if (enable) {
handleRegisterNetworkRequest(new NetworkRequestInfo(
- null, mDefaultMobileDataRequest, new Binder(), NetworkRequestType.REQUEST));
+ null, mDefaultMobileDataRequest, new Binder()));
} else {
handleReleaseNetworkRequest(mDefaultMobileDataRequest, Process.SYSTEM_UID);
}
@@ -1904,8 +1904,8 @@
pw.increaseIndent();
pw.println("Requests:");
pw.increaseIndent();
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- pw.println(nai.networkRequests.valueAt(i).toString());
+ for (int i = 0; i < nai.numNetworkRequests(); i++) {
+ pw.println(nai.requestAt(i).toString());
}
pw.decreaseIndent();
pw.println("Lingered:");
@@ -2014,10 +2014,6 @@
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 @@
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);
@@ -2269,7 +2265,7 @@
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) {
if (DBG) {
- log(nai.name() + " got DISCONNECTED, was satisfying " + nai.networkRequests.size());
+ log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
}
// A network agent has disconnected.
// TODO - if we move the logic to the network agent (have them disconnect
@@ -2306,15 +2302,15 @@
mNetworkForNetId.remove(nai.network.netId);
}
// Remove all previously satisfied requests.
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- NetworkRequest request = nai.networkRequests.valueAt(i);
+ for (int i = 0; i < nai.numNetworkRequests(); i++) {
+ NetworkRequest request = nai.requestAt(i);
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId);
if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
mNetworkForRequestId.remove(request.requestId);
sendUpdatedScoreToFactories(request, 0);
}
}
- if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
+ if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
removeDataActivityTracking(nai);
notifyLockdownVpn(nai);
requestNetworkTransitionWakelock(nai.name());
@@ -2375,7 +2371,7 @@
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 @@
}
}
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,8 +2401,8 @@
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 ||
+ if (nri.request.isRequest() && nai.satisfies(nri.request) &&
+ (nai.isSatisfyingRequest(nri.request.requestId) ||
// 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
@@ -2429,7 +2425,7 @@
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,19 +2441,18 @@
}
}
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
// network satisfying it, so this loop is wasteful
boolean wasKept = false;
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
- if (nai.networkRequests.get(nri.request.requestId) != null) {
- nai.networkRequests.remove(nri.request.requestId);
+ if (nai.isSatisfyingRequest(nri.request.requestId)) {
+ nai.removeRequest(nri.request.requestId);
if (VDBG) {
log(" Removing from current network " + nai.name() +
- ", leaving " + nai.networkRequests.size() +
- " requests.");
+ ", leaving " + nai.numNetworkRequests() + " requests.");
}
if (unneeded(nai)) {
if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
@@ -2484,10 +2479,10 @@
if (wasKept) {
// check if any of the remaining requests for this network are for the
// same legacy type - if so, don't remove the nai
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- NetworkRequest otherRequest = nai.networkRequests.valueAt(i);
+ for (int i = 0; i < nai.numNetworkRequests(); i++) {
+ NetworkRequest otherRequest = nai.requestAt(i);
if (otherRequest.legacyType == nri.request.legacyType &&
- isRequest(otherRequest)) {
+ otherRequest.isRequest()) {
if (DBG) log(" still have other legacy request - leaving");
doRemove = false;
}
@@ -2507,7 +2502,7 @@
// listens don't have a singular affectedNetwork. Check all networks to see
// if this listen request applies and remove it.
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
- nai.networkRequests.remove(nri.request.requestId);
+ nai.removeRequest(nri.request.requestId);
if (nri.request.networkCapabilities.hasSignalStrength() &&
nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
updateSignalStrengthThresholds(nai, "RELEASE", nri.request);
@@ -3824,32 +3819,6 @@
}
/**
- * 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 +3830,26 @@
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 +3860,13 @@
}
}
+ 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 +3877,6 @@
}
}
- 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 +3889,8 @@
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 +3940,13 @@
@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 +3967,8 @@
}
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 +4038,8 @@
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 +4089,9 @@
}
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 +4107,9 @@
}
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));
@@ -4482,10 +4425,10 @@
}
private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- NetworkRequest nr = nai.networkRequests.valueAt(i);
+ for (int i = 0; i < nai.numNetworkRequests(); i++) {
+ NetworkRequest nr = nai.requestAt(i);
// Don't send listening requests to factories. b/17393458
- if (!isRequest(nr)) continue;
+ if (!nr.isRequest()) continue;
sendUpdatedScoreToFactories(nr, nai.getCurrentScore());
}
}
@@ -4575,12 +4518,14 @@
}
private void teardownUnneededNetwork(NetworkAgentInfo nai) {
- for (int i = 0; i < nai.networkRequests.size(); i++) {
- NetworkRequest nr = nai.networkRequests.valueAt(i);
- // Ignore listening requests.
- if (!isRequest(nr)) continue;
- loge("Dead network still had at least " + nr);
- break;
+ if (nai.numRequestNetworkRequests() != 0) {
+ for (int i = 0; i < nai.numNetworkRequests(); i++) {
+ NetworkRequest nr = nai.requestAt(i);
+ // Ignore listening requests.
+ if (!nr.isRequest()) continue;
+ loge("Dead network still had at least " + nr);
+ break;
+ }
}
nai.asyncChannel.disconnect();
}
@@ -4662,7 +4607,7 @@
// 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);
@@ -4681,7 +4626,7 @@
if (VDBG) log("rematch for " + newNetwork.name());
if (currentNetwork != null) {
if (VDBG) log(" accepting network in place of " + currentNetwork.name());
- currentNetwork.networkRequests.remove(nri.request.requestId);
+ currentNetwork.removeRequest(nri.request.requestId);
currentNetwork.networkLingered.add(nri.request);
affectedNetworks.add(currentNetwork);
} else {
@@ -4705,7 +4650,7 @@
oldDefaultNetwork = currentNetwork;
}
}
- } else if (newNetwork.networkRequests.get(nri.request.requestId) != null) {
+ } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) {
// If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri",
// mark it as no longer satisfying "nri". Because networks are processed by
// rematchAllNetworkAndRequests() in descending score order, "currentNetwork" will
@@ -4717,12 +4662,12 @@
log("Network " + newNetwork.name() + " stopped satisfying" +
" request " + nri.request.requestId);
}
- newNetwork.networkRequests.remove(nri.request.requestId);
+ newNetwork.removeRequest(nri.request.requestId);
if (currentNetwork == newNetwork) {
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!");
@@ -4822,9 +4767,9 @@
// (notification callbacks) and then uses the old api (getNetworkInfo(type))
// they may get old info. Reverse this after the old startUsing api is removed.
// 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)) {
+ for (int i = 0; i < newNetwork.numNetworkRequests(); i++) {
+ NetworkRequest nr = newNetwork.requestAt(i);
+ if (nr.legacyType != TYPE_NONE && nr.isRequest()) {
// legacy type tracker filters out repeat adds
mLegacyTypeTracker.add(nr.legacyType, newNetwork);
}
@@ -5083,7 +5028,7 @@
intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
}
NetworkAgentInfo newDefaultAgent = null;
- if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
+ if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
newDefaultAgent = getDefaultNetwork();
if (newDefaultAgent != null) {
intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
@@ -5103,8 +5048,8 @@
protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
if (VDBG) log("notifyType " + notifyTypeToName(notifyType) + " for " + networkAgent.name());
- for (int i = 0; i < networkAgent.networkRequests.size(); i++) {
- NetworkRequest nr = networkAgent.networkRequests.valueAt(i);
+ for (int i = 0; i < networkAgent.numNetworkRequests(); i++) {
+ NetworkRequest nr = networkAgent.requestAt(i);
NetworkRequestInfo nri = mNetworkRequests.get(nr);
if (VDBG) log(" sending notification for " + nr);
if (nri.mPendingIntent == null) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index d487bd0..15b872d 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -162,11 +162,13 @@
private static final int MAXIMUM_NETWORK_SCORE = 100;
// The list of NetworkRequests being satisfied by this Network.
- public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
+ private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
// The list of NetworkRequests that this Network previously satisfied with the highest
// score. A non-empty list indicates that if this Network was validated it is lingered.
// NOTE: This list is only used for debugging.
public final ArrayList<NetworkRequest> networkLingered = new ArrayList<NetworkRequest>();
+ // How many of the satisfied requests are actual requests and not listens.
+ private int mNumRequestNetworkRequests = 0;
public final Messenger messenger;
public final AsyncChannel asyncChannel;
@@ -188,18 +190,63 @@
networkMisc = misc;
}
+ // Functions for manipulating the requests satisfied by this network.
+ //
+ // These functions must only called on ConnectivityService's main thread.
+
/**
* Add {@code networkRequest} to this network as it's satisfied by this network.
- * NOTE: This function must only be called on ConnectivityService's main thread.
* @return true if {@code networkRequest} was added or false if {@code networkRequest} was
* already present.
*/
public boolean addRequest(NetworkRequest networkRequest) {
- if (networkRequests.get(networkRequest.requestId) == networkRequest) return false;
- networkRequests.put(networkRequest.requestId, networkRequest);
+ NetworkRequest existing = mNetworkRequests.get(networkRequest.requestId);
+ if (existing == networkRequest) return false;
+ if (existing != null && existing.isRequest()) mNumRequestNetworkRequests--;
+ mNetworkRequests.put(networkRequest.requestId, networkRequest);
+ if (networkRequest.isRequest()) mNumRequestNetworkRequests++;
return true;
}
+ /**
+ * Remove the specified request from this network.
+ */
+ public void removeRequest(int requestId) {
+ NetworkRequest existing = mNetworkRequests.get(requestId);
+ if (existing != null && existing.isRequest()) mNumRequestNetworkRequests--;
+ mNetworkRequests.remove(requestId);
+ }
+
+ /**
+ * Returns whether this network is currently satisfying the request with the specified ID.
+ */
+ public boolean isSatisfyingRequest(int id) {
+ return mNetworkRequests.get(id) != null;
+ }
+
+ /**
+ * Returns the request at the specified position in the list of requests satisfied by this
+ * network.
+ */
+ public NetworkRequest requestAt(int index) {
+ return mNetworkRequests.valueAt(index);
+ }
+
+ /**
+ * Returns the number of requests currently satisfied by this network for which
+ * {@link android.net.NetworkRequest#isRequest} returns {@code true}.
+ */
+ public int numRequestNetworkRequests() {
+ return mNumRequestNetworkRequests;
+ }
+
+ /**
+ * Returns the number of requests of any type currently satisfied by this network.
+ */
+ public int numNetworkRequests() {
+ return mNetworkRequests.size();
+ }
+
// Does this network satisfy request?
public boolean satisfies(NetworkRequest request) {
return created &&