Merge changes from topic "del-factory-and-networkagent-wifi"
* changes: Delete NetworkFactory from frameworks/base/core. New NetworkAgentConfig API to replace NetworkInfo WiFi stuff.
This commit is contained in:
@@ -4641,8 +4641,11 @@ package android.net {
|
||||
method public int getLegacyType();
|
||||
method @NonNull public String getLegacyTypeName();
|
||||
method @Nullable public String getSubscriberId();
|
||||
method public boolean isExplicitlySelected();
|
||||
method public boolean isNat64DetectionEnabled();
|
||||
method public boolean isPartialConnectivityAcceptable();
|
||||
method public boolean isProvisioningNotificationEnabled();
|
||||
method public boolean isUnvalidatedConnectivityAcceptable();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR;
|
||||
}
|
||||
@@ -4652,9 +4655,12 @@ package android.net {
|
||||
method @NonNull public android.net.NetworkAgentConfig build();
|
||||
method @NonNull public android.net.NetworkAgentConfig.Builder disableNat64Detection();
|
||||
method @NonNull public android.net.NetworkAgentConfig.Builder disableProvisioningNotification();
|
||||
method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
|
||||
method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
|
||||
method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
|
||||
method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
|
||||
method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
|
||||
method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean);
|
||||
}
|
||||
|
||||
public final class NetworkCapabilities implements android.os.Parcelable {
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Allows a network transport to provide the system with policy and configuration information about
|
||||
* a particular network when registering a {@link NetworkAgent}. This information cannot change once the agent is registered.
|
||||
@@ -51,23 +53,47 @@ public final class NetworkAgentConfig implements Parcelable {
|
||||
*/
|
||||
public boolean explicitlySelected;
|
||||
|
||||
/**
|
||||
* @return whether this network was explicitly selected by the user.
|
||||
*/
|
||||
public boolean isExplicitlySelected() {
|
||||
return explicitlySelected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the user desires to use this network even if it is unvalidated. This field has meaning
|
||||
* only if {@link explicitlySelected} is true. If it is, this field must also be set to the
|
||||
* appropriate value based on previous user choice.
|
||||
*
|
||||
* TODO : rename this field to match its accessor
|
||||
* @hide
|
||||
*/
|
||||
public boolean acceptUnvalidated;
|
||||
|
||||
/**
|
||||
* @return whether the system should accept this network even if it doesn't validate.
|
||||
*/
|
||||
public boolean isUnvalidatedConnectivityAcceptable() {
|
||||
return acceptUnvalidated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user explicitly set that this network should be validated even if presence of
|
||||
* only partial internet connectivity.
|
||||
*
|
||||
* TODO : rename this field to match its accessor
|
||||
* @hide
|
||||
*/
|
||||
public boolean acceptPartialConnectivity;
|
||||
|
||||
/**
|
||||
* @return whether the system should validate this network even if it only offers partial
|
||||
* Internet connectivity.
|
||||
*/
|
||||
public boolean isPartialConnectivityAcceptable() {
|
||||
return acceptPartialConnectivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to avoid surfacing the "Sign in to network" notification.
|
||||
* if carrier receivers/apps are registered to handle the carrier-specific provisioning
|
||||
@@ -134,9 +160,11 @@ public final class NetworkAgentConfig implements Parcelable {
|
||||
* Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
|
||||
* Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
|
||||
*
|
||||
* This is not parceled, because it would not make sense.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasShownBroken;
|
||||
public transient boolean hasShownBroken;
|
||||
|
||||
/**
|
||||
* The name of the legacy network type. It's a free-form string used in logging.
|
||||
@@ -163,6 +191,7 @@ public final class NetworkAgentConfig implements Parcelable {
|
||||
allowBypass = nac.allowBypass;
|
||||
explicitlySelected = nac.explicitlySelected;
|
||||
acceptUnvalidated = nac.acceptUnvalidated;
|
||||
acceptPartialConnectivity = nac.acceptPartialConnectivity;
|
||||
subscriberId = nac.subscriberId;
|
||||
provisioningNotificationDisabled = nac.provisioningNotificationDisabled;
|
||||
skip464xlat = nac.skip464xlat;
|
||||
@@ -177,6 +206,43 @@ public final class NetworkAgentConfig implements Parcelable {
|
||||
public static class Builder {
|
||||
private final NetworkAgentConfig mConfig = new NetworkAgentConfig();
|
||||
|
||||
/**
|
||||
* Sets whether the network was explicitly selected by the user.
|
||||
*
|
||||
* @return this builder, to facilitate chaining.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setExplicitlySelected(final boolean explicitlySelected) {
|
||||
mConfig.explicitlySelected = explicitlySelected;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the system should validate this network even if it is found not to offer
|
||||
* Internet connectivity.
|
||||
*
|
||||
* @return this builder, to facilitate chaining.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setUnvalidatedConnectivityAcceptable(
|
||||
final boolean unvalidatedConnectivityAcceptable) {
|
||||
mConfig.acceptUnvalidated = unvalidatedConnectivityAcceptable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the system should validate this network even if it is found to only offer
|
||||
* partial Internet connectivity.
|
||||
*
|
||||
* @return this builder, to facilitate chaining.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setPartialConnectivityAcceptable(
|
||||
final boolean partialConnectivityAcceptable) {
|
||||
mConfig.acceptPartialConnectivity = partialConnectivityAcceptable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subscriber ID for this network.
|
||||
*
|
||||
@@ -244,6 +310,45 @@ public final class NetworkAgentConfig implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final NetworkAgentConfig that = (NetworkAgentConfig) o;
|
||||
return allowBypass == that.allowBypass
|
||||
&& explicitlySelected == that.explicitlySelected
|
||||
&& acceptUnvalidated == that.acceptUnvalidated
|
||||
&& acceptPartialConnectivity == that.acceptPartialConnectivity
|
||||
&& provisioningNotificationDisabled == that.provisioningNotificationDisabled
|
||||
&& skip464xlat == that.skip464xlat
|
||||
&& legacyType == that.legacyType
|
||||
&& Objects.equals(subscriberId, that.subscriberId)
|
||||
&& Objects.equals(legacyTypeName, that.legacyTypeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
|
||||
acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
|
||||
skip464xlat, legacyType, legacyTypeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NetworkAgentConfig {"
|
||||
+ " allowBypass = " + allowBypass
|
||||
+ ", explicitlySelected = " + explicitlySelected
|
||||
+ ", acceptUnvalidated = " + acceptUnvalidated
|
||||
+ ", acceptPartialConnectivity = " + acceptPartialConnectivity
|
||||
+ ", provisioningNotificationDisabled = " + provisioningNotificationDisabled
|
||||
+ ", subscriberId = '" + subscriberId + '\''
|
||||
+ ", skip464xlat = " + skip464xlat
|
||||
+ ", legacyType = " + legacyType
|
||||
+ ", hasShownBroken = " + hasShownBroken
|
||||
+ ", legacyTypeName = '" + legacyTypeName + '\''
|
||||
+ "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
@@ -254,9 +359,12 @@ public final class NetworkAgentConfig implements Parcelable {
|
||||
out.writeInt(allowBypass ? 1 : 0);
|
||||
out.writeInt(explicitlySelected ? 1 : 0);
|
||||
out.writeInt(acceptUnvalidated ? 1 : 0);
|
||||
out.writeInt(acceptPartialConnectivity ? 1 : 0);
|
||||
out.writeString(subscriberId);
|
||||
out.writeInt(provisioningNotificationDisabled ? 1 : 0);
|
||||
out.writeInt(skip464xlat ? 1 : 0);
|
||||
out.writeInt(legacyType);
|
||||
out.writeString(legacyTypeName);
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<NetworkAgentConfig> CREATOR =
|
||||
@@ -267,9 +375,12 @@ public final class NetworkAgentConfig implements Parcelable {
|
||||
networkAgentConfig.allowBypass = in.readInt() != 0;
|
||||
networkAgentConfig.explicitlySelected = in.readInt() != 0;
|
||||
networkAgentConfig.acceptUnvalidated = in.readInt() != 0;
|
||||
networkAgentConfig.acceptPartialConnectivity = in.readInt() != 0;
|
||||
networkAgentConfig.subscriberId = in.readString();
|
||||
networkAgentConfig.provisioningNotificationDisabled = in.readInt() != 0;
|
||||
networkAgentConfig.skip464xlat = in.readInt() != 0;
|
||||
networkAgentConfig.legacyType = in.readInt();
|
||||
networkAgentConfig.legacyTypeName = in.readString();
|
||||
return networkAgentConfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,453 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.internal.util.Protocol;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* A NetworkFactory is an entity that creates NetworkAgent objects.
|
||||
* The bearers register with ConnectivityService using {@link #register} and
|
||||
* their factory will start receiving scored NetworkRequests. NetworkRequests
|
||||
* can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by
|
||||
* overridden function. All of these can be dynamic - changing NetworkCapabilities
|
||||
* or score forces re-evaluation of all current requests.
|
||||
*
|
||||
* If any requests pass the filter some overrideable functions will be called.
|
||||
* If the bearer only cares about very simple start/stopNetwork callbacks, those
|
||||
* functions can be overridden. If the bearer needs more interaction, it can
|
||||
* override addNetworkRequest and removeNetworkRequest which will give it each
|
||||
* request that passes their current filters.
|
||||
* @hide
|
||||
**/
|
||||
public class NetworkFactory extends Handler {
|
||||
/* TODO: delete when all callers have migrated to NetworkProvider IDs. */
|
||||
public static class SerialNumber {
|
||||
// Guard used by no network factory.
|
||||
public static final int NONE = -1;
|
||||
// A hardcoded serial number for NetworkAgents representing VPNs. These agents are
|
||||
// not created by any factory, so they use this constant for clarity instead of NONE.
|
||||
public static final int VPN = -2;
|
||||
private static final AtomicInteger sNetworkFactorySerialNumber = new AtomicInteger(1);
|
||||
/** Returns a unique serial number for a factory. */
|
||||
public static final int nextSerialNumber() {
|
||||
return sNetworkFactorySerialNumber.getAndIncrement();
|
||||
}
|
||||
}
|
||||
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean VDBG = false;
|
||||
|
||||
private static final int BASE = Protocol.BASE_NETWORK_FACTORY;
|
||||
/**
|
||||
* Pass a network request to the bearer. If the bearer believes it can
|
||||
* satisfy the request it should connect to the network and create a
|
||||
* NetworkAgent. Once the NetworkAgent is fully functional it will
|
||||
* register itself with ConnectivityService using registerNetworkAgent.
|
||||
* If the bearer cannot immediately satisfy the request (no network,
|
||||
* user disabled the radio, lower-scored network) it should remember
|
||||
* any NetworkRequests it may be able to satisfy in the future. It may
|
||||
* disregard any that it will never be able to service, for example
|
||||
* those requiring a different bearer.
|
||||
* msg.obj = NetworkRequest
|
||||
* msg.arg1 = score - the score of the network currently satisfying this
|
||||
* request. If this bearer knows in advance it cannot
|
||||
* exceed this score it should not try to connect, holding the request
|
||||
* for the future.
|
||||
* Note that subsequent events may give a different (lower
|
||||
* or higher) score for this request, transmitted to each
|
||||
* NetworkFactory through additional CMD_REQUEST_NETWORK msgs
|
||||
* with the same NetworkRequest but an updated score.
|
||||
* Also, network conditions may change for this bearer
|
||||
* allowing for a better score in the future.
|
||||
* msg.arg2 = the ID of the NetworkProvider currently responsible for the
|
||||
* NetworkAgent handling this request, or NetworkProvider.ID_NONE if none.
|
||||
*/
|
||||
public static final int CMD_REQUEST_NETWORK = BASE;
|
||||
|
||||
/**
|
||||
* Cancel a network request
|
||||
* msg.obj = NetworkRequest
|
||||
*/
|
||||
public static final int CMD_CANCEL_REQUEST = BASE + 1;
|
||||
|
||||
/**
|
||||
* Internally used to set our best-guess score.
|
||||
* msg.arg1 = new score
|
||||
*/
|
||||
private static final int CMD_SET_SCORE = BASE + 2;
|
||||
|
||||
/**
|
||||
* Internally used to set our current filter for coarse bandwidth changes with
|
||||
* technology changes.
|
||||
* msg.obj = new filter
|
||||
*/
|
||||
private static final int CMD_SET_FILTER = BASE + 3;
|
||||
|
||||
private final Context mContext;
|
||||
private final ArrayList<Message> mPreConnectedQueue = new ArrayList<Message>();
|
||||
private final String LOG_TAG;
|
||||
|
||||
private final SparseArray<NetworkRequestInfo> mNetworkRequests =
|
||||
new SparseArray<NetworkRequestInfo>();
|
||||
|
||||
private int mScore;
|
||||
private NetworkCapabilities mCapabilityFilter;
|
||||
|
||||
private int mRefCount = 0;
|
||||
private Messenger mMessenger = null;
|
||||
private NetworkProvider mProvider = null;
|
||||
private int mProviderId;
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public NetworkFactory(Looper looper, Context context, String logTag,
|
||||
NetworkCapabilities filter) {
|
||||
super(looper);
|
||||
LOG_TAG = logTag;
|
||||
mContext = context;
|
||||
mCapabilityFilter = filter;
|
||||
}
|
||||
|
||||
public void register() {
|
||||
if (mProvider != null) {
|
||||
Log.e(LOG_TAG, "Ignoring attempt to register already-registered NetworkFactory");
|
||||
return;
|
||||
}
|
||||
if (DBG) log("Registering NetworkFactory");
|
||||
|
||||
mProvider = new NetworkProvider(mContext, NetworkFactory.this.getLooper(), LOG_TAG) {
|
||||
@Override
|
||||
public void onNetworkRequested(@NonNull NetworkRequest request, int score,
|
||||
int servingProviderId) {
|
||||
handleAddRequest((NetworkRequest) request, score, servingProviderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestWithdrawn(@NonNull NetworkRequest request) {
|
||||
handleRemoveRequest(request);
|
||||
}
|
||||
};
|
||||
|
||||
mMessenger = new Messenger(this);
|
||||
mProviderId = ConnectivityManager.from(mContext).registerNetworkProvider(mProvider);
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
if (mProvider == null) {
|
||||
Log.e(LOG_TAG, "Ignoring attempt to unregister unregistered NetworkFactory");
|
||||
return;
|
||||
}
|
||||
if (DBG) log("Unregistering NetworkFactory");
|
||||
|
||||
ConnectivityManager.from(mContext).unregisterNetworkProvider(mProvider);
|
||||
mProvider = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case CMD_REQUEST_NETWORK: {
|
||||
handleAddRequest((NetworkRequest) msg.obj, msg.arg1, msg.arg2);
|
||||
break;
|
||||
}
|
||||
case CMD_CANCEL_REQUEST: {
|
||||
handleRemoveRequest((NetworkRequest) msg.obj);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_SCORE: {
|
||||
handleSetScore(msg.arg1);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_FILTER: {
|
||||
handleSetFilter((NetworkCapabilities) msg.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NetworkRequestInfo {
|
||||
public final NetworkRequest request;
|
||||
public int score;
|
||||
public boolean requested; // do we have a request outstanding, limited by score
|
||||
public int providerId;
|
||||
|
||||
NetworkRequestInfo(NetworkRequest request, int score, int providerId) {
|
||||
this.request = request;
|
||||
this.score = score;
|
||||
this.requested = false;
|
||||
this.providerId = providerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + request + ", score=" + score + ", requested=" + requested + "}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a NetworkRequest that the bearer may want to attempt to satisfy.
|
||||
* @see #CMD_REQUEST_NETWORK
|
||||
*
|
||||
* @param request the request to handle.
|
||||
* @param score the score of the NetworkAgent currently satisfying this request.
|
||||
*/
|
||||
// TODO : remove this method. It is a stopgap measure to help sheperding a number
|
||||
// of dependent changes that would conflict throughout the automerger graph. Having this
|
||||
// temporarily helps with the process of going through with all these dependent changes across
|
||||
// the entire tree.
|
||||
@VisibleForTesting
|
||||
protected void handleAddRequest(NetworkRequest request, int score) {
|
||||
handleAddRequest(request, score, NetworkProvider.ID_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a NetworkRequest that the bearer may want to attempt to satisfy.
|
||||
* @see #CMD_REQUEST_NETWORK
|
||||
*
|
||||
* @param request the request to handle.
|
||||
* @param score the score of the NetworkAgent currently satisfying this request.
|
||||
* @param servingProviderId the ID of the NetworkProvider that created the NetworkAgent
|
||||
* currently satisfying this request.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected void handleAddRequest(NetworkRequest request, int score, int servingProviderId) {
|
||||
NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
|
||||
if (n == null) {
|
||||
if (DBG) {
|
||||
log("got request " + request + " with score " + score
|
||||
+ " and providerId " + servingProviderId);
|
||||
}
|
||||
n = new NetworkRequestInfo(request, score, servingProviderId);
|
||||
mNetworkRequests.put(n.request.requestId, n);
|
||||
} else {
|
||||
if (VDBG) {
|
||||
log("new score " + score + " for exisiting request " + request
|
||||
+ " and providerId " + servingProviderId);
|
||||
}
|
||||
n.score = score;
|
||||
n.providerId = servingProviderId;
|
||||
}
|
||||
if (VDBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
|
||||
|
||||
evalRequest(n);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void handleRemoveRequest(NetworkRequest request) {
|
||||
NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
|
||||
if (n != null) {
|
||||
mNetworkRequests.remove(request.requestId);
|
||||
if (n.requested) releaseNetworkFor(n.request);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSetScore(int score) {
|
||||
mScore = score;
|
||||
evalRequests();
|
||||
}
|
||||
|
||||
private void handleSetFilter(NetworkCapabilities netCap) {
|
||||
mCapabilityFilter = netCap;
|
||||
evalRequests();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridable function to provide complex filtering.
|
||||
* Called for every request every time a new NetworkRequest is seen
|
||||
* and whenever the filterScore or filterNetworkCapabilities change.
|
||||
*
|
||||
* acceptRequest can be overridden to provide complex filter behavior
|
||||
* for the incoming requests
|
||||
*
|
||||
* For output, this class will call {@link #needNetworkFor} and
|
||||
* {@link #releaseNetworkFor} for every request that passes the filters.
|
||||
* If you don't need to see every request, you can leave the base
|
||||
* implementations of those two functions and instead override
|
||||
* {@link #startNetwork} and {@link #stopNetwork}.
|
||||
*
|
||||
* If you want to see every score fluctuation on every request, set
|
||||
* your score filter to a very high number and watch {@link #needNetworkFor}.
|
||||
*
|
||||
* @return {@code true} to accept the request.
|
||||
*/
|
||||
public boolean acceptRequest(NetworkRequest request, int score) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void evalRequest(NetworkRequestInfo n) {
|
||||
if (VDBG) {
|
||||
log("evalRequest");
|
||||
log(" n.requests = " + n.requested);
|
||||
log(" n.score = " + n.score);
|
||||
log(" mScore = " + mScore);
|
||||
log(" n.providerId = " + n.providerId);
|
||||
log(" mProviderId = " + mProviderId);
|
||||
}
|
||||
if (shouldNeedNetworkFor(n)) {
|
||||
if (VDBG) log(" needNetworkFor");
|
||||
needNetworkFor(n.request, n.score);
|
||||
n.requested = true;
|
||||
} else if (shouldReleaseNetworkFor(n)) {
|
||||
if (VDBG) log(" releaseNetworkFor");
|
||||
releaseNetworkFor(n.request);
|
||||
n.requested = false;
|
||||
} else {
|
||||
if (VDBG) log(" done");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldNeedNetworkFor(NetworkRequestInfo n) {
|
||||
// If this request is already tracked, it doesn't qualify for need
|
||||
return !n.requested
|
||||
// If the score of this request is higher or equal to that of this factory and some
|
||||
// other factory is responsible for it, then this factory should not track the request
|
||||
// because it has no hope of satisfying it.
|
||||
&& (n.score < mScore || n.providerId == mProviderId)
|
||||
// If this factory can't satisfy the capability needs of this request, then it
|
||||
// should not be tracked.
|
||||
&& n.request.networkCapabilities.satisfiedByNetworkCapabilities(mCapabilityFilter)
|
||||
// Finally if the concrete implementation of the factory rejects the request, then
|
||||
// don't track it.
|
||||
&& acceptRequest(n.request, n.score);
|
||||
}
|
||||
|
||||
private boolean shouldReleaseNetworkFor(NetworkRequestInfo n) {
|
||||
// Don't release a request that's not tracked.
|
||||
return n.requested
|
||||
// The request should be released if it can't be satisfied by this factory. That
|
||||
// means either of the following conditions are met :
|
||||
// - Its score is too high to be satisfied by this factory and it's not already
|
||||
// assigned to the factory
|
||||
// - This factory can't satisfy the capability needs of the request
|
||||
// - The concrete implementation of the factory rejects the request
|
||||
&& ((n.score > mScore && n.providerId != mProviderId)
|
||||
|| !n.request.networkCapabilities.satisfiedByNetworkCapabilities(
|
||||
mCapabilityFilter)
|
||||
|| !acceptRequest(n.request, n.score));
|
||||
}
|
||||
|
||||
private void evalRequests() {
|
||||
for (int i = 0; i < mNetworkRequests.size(); i++) {
|
||||
NetworkRequestInfo n = mNetworkRequests.valueAt(i);
|
||||
evalRequest(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a command, on this NetworkFactory Handler, to re-evaluate all
|
||||
* oustanding requests. Can be called from a factory implementation.
|
||||
*/
|
||||
protected void reevaluateAllRequests() {
|
||||
post(() -> {
|
||||
evalRequests();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be called by a factory to release a request as unfulfillable: the request will be
|
||||
* removed, and the caller will get a
|
||||
* {@link ConnectivityManager.NetworkCallback#onUnavailable()} callback after this function
|
||||
* returns.
|
||||
*
|
||||
* Note: this should only be called by factory which KNOWS that it is the ONLY factory which
|
||||
* is able to fulfill this request!
|
||||
*/
|
||||
protected void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) {
|
||||
post(() -> {
|
||||
if (DBG) log("releaseRequestAsUnfulfillableByAnyFactory: " + r);
|
||||
ConnectivityManager.from(mContext).declareNetworkRequestUnfulfillable(r);
|
||||
});
|
||||
}
|
||||
|
||||
// override to do simple mode (request independent)
|
||||
protected void startNetwork() { }
|
||||
protected void stopNetwork() { }
|
||||
|
||||
// override to do fancier stuff
|
||||
protected void needNetworkFor(NetworkRequest networkRequest, int score) {
|
||||
if (++mRefCount == 1) startNetwork();
|
||||
}
|
||||
|
||||
protected void releaseNetworkFor(NetworkRequest networkRequest) {
|
||||
if (--mRefCount == 0) stopNetwork();
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
public void setScoreFilter(int score) {
|
||||
sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
|
||||
}
|
||||
|
||||
public void setCapabilityFilter(NetworkCapabilities netCap) {
|
||||
sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected int getRequestCount() {
|
||||
return mNetworkRequests.size();
|
||||
}
|
||||
|
||||
/* TODO: delete when all callers have migrated to NetworkProvider IDs. */
|
||||
public int getSerialNumber() {
|
||||
return mProviderId;
|
||||
}
|
||||
|
||||
public int getProviderId() {
|
||||
return mProviderId;
|
||||
}
|
||||
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, s);
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
|
||||
pw.println(toString());
|
||||
pw.increaseIndent();
|
||||
for (int i = 0; i < mNetworkRequests.size(); i++) {
|
||||
pw.println(mNetworkRequests.valueAt(i));
|
||||
}
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - mProviderId=")
|
||||
.append(mProviderId).append(", ScoreFilter=")
|
||||
.append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests=")
|
||||
.append(mNetworkRequests.size()).append(", refCount=").append(mRefCount)
|
||||
.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ java_library_static {
|
||||
"netd_aidl_interface-unstable-java",
|
||||
"netlink-client",
|
||||
"networkstack-client",
|
||||
"net-utils-services-common",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
39
tests/net/common/java/android/net/NetworkAgentConfigTest.kt
Normal file
39
tests/net/common/java/android/net/NetworkAgentConfigTest.kt
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net
|
||||
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.runner.AndroidJUnit4
|
||||
import com.android.testutils.assertParcelSane
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@SmallTest
|
||||
class NetworkAgentConfigTest {
|
||||
@Test
|
||||
fun testParcelNetworkAgentConfig() {
|
||||
val config = NetworkAgentConfig.Builder().apply {
|
||||
setExplicitlySelected(true)
|
||||
setLegacyType(ConnectivityManager.TYPE_ETHERNET)
|
||||
setSubscriberId("MySubId")
|
||||
setPartialConnectivityAcceptable(false)
|
||||
setUnvalidatedConnectivityAcceptable(true)
|
||||
}.build()
|
||||
assertParcelSane(config, 9)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user