Merge "[NS01] Add NetworkScore"

This commit is contained in:
Chalard Jean
2021-03-16 06:36:07 +00:00
committed by Gerrit Code Review
10 changed files with 188 additions and 68 deletions

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2021 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.os.Parcel;
import android.os.Parcelable;
/**
* Object representing the quality of a network as perceived by the user.
*
* A NetworkScore object represents the characteristics of a network that affects how good the
* network is considered for a particular use.
* @hide
*/
// TODO : @SystemApi when the implementation is complete
public final class NetworkScore implements Parcelable {
// This will be removed soon. Do *NOT* depend on it for any new code that is not part of
// a migration.
private final int mLegacyInt;
/** @hide */
NetworkScore(final int legacyInt) {
this.mLegacyInt = legacyInt;
}
private NetworkScore(@NonNull final Parcel in) {
mLegacyInt = in.readInt();
}
public int getLegacyInt() {
return mLegacyInt;
}
@Override
public String toString() {
return "Score(" + mLegacyInt + ")";
}
@Override
public void writeToParcel(@NonNull final Parcel dest, final int flags) {
dest.writeInt(mLegacyInt);
}
@Override
public int describeContents() {
return 0;
}
@NonNull public static final Creator<NetworkScore> CREATOR = new Creator<>() {
@Override
@NonNull
public NetworkScore createFromParcel(@NonNull final Parcel in) {
return new NetworkScore(in);
}
@Override
@NonNull
public NetworkScore[] newArray(int size) {
return new NetworkScore[size];
}
};
/**
* A builder for NetworkScore.
*/
public static final class Builder {
private static final int INVALID_LEGACY_INT = Integer.MIN_VALUE;
private int mLegacyInt = INVALID_LEGACY_INT;
/**
* Sets the legacy int for this score.
*
* Do not rely on this. It will be gone by the time S is released.
*
* @param score the legacy int
* @return this
*/
@NonNull
public Builder setLegacyInt(final int score) {
mLegacyInt = score;
return this;
}
/**
* Builds this NetworkScore.
* @return The built NetworkScore object.
*/
@NonNull
public NetworkScore build() {
return new NetworkScore(mLegacyInt);
}
}
}

View File

@@ -3205,10 +3205,6 @@ public class ConnectivityManager {
}
}
// 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.
/**
* @hide
* Register a NetworkAgent with ConnectivityService.
@@ -3218,20 +3214,8 @@ public class ConnectivityManager {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
android.Manifest.permission.NETWORK_FACTORY})
public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp,
NetworkCapabilities nc, int score, NetworkAgentConfig config) {
return registerNetworkAgent(na, ni, lp, nc, score, config, NetworkProvider.ID_NONE);
}
/**
* @hide
* Register a NetworkAgent with ConnectivityService.
* @return Network corresponding to NetworkAgent.
*/
@RequiresPermission(anyOf = {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
android.Manifest.permission.NETWORK_FACTORY})
public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp,
NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) {
NetworkCapabilities nc, @NonNull NetworkScore score, NetworkAgentConfig config,
int providerId) {
try {
return mService.registerNetworkAgent(na, ni, lp, nc, score, config, providerId);
} catch (RemoteException e) {

View File

@@ -30,6 +30,7 @@ import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.NetworkScore;
import android.net.NetworkState;
import android.net.NetworkStateSnapshot;
import android.net.OemNetworkPreferences;
@@ -138,7 +139,7 @@ interface IConnectivityManager
void declareNetworkRequestUnfulfillable(in NetworkRequest request);
Network registerNetworkAgent(in INetworkAgent na, in NetworkInfo ni, in LinkProperties lp,
in NetworkCapabilities nc, int score, in NetworkAgentConfig config,
in NetworkCapabilities nc, in NetworkScore score, in NetworkAgentConfig config,
in int factorySerialNumber);
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType,

View File

@@ -371,6 +371,14 @@ public abstract class NetworkAgent {
return ni;
}
// Temporary backward compatibility constructor
public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
@NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
@NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
this(context, looper, logTag, nc, lp,
new NetworkScore.Builder().setLegacyInt(score).build(), config, provider);
}
/**
* Create a new network agent.
* @param context a {@link Context} to get system services from.
@@ -382,10 +390,12 @@ public abstract class NetworkAgent {
* @param score the initial score of this network. Update with sendNetworkScore.
* @param config an immutable {@link NetworkAgentConfig} for this agent.
* @param provider the {@link NetworkProvider} managing this agent.
* @hide TODO : unhide when impl is complete
*/
public NetworkAgent(@NonNull Context context, @NonNull Looper looper, @NonNull String logTag,
@NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
@NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
@NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
@NonNull NetworkScore score, @NonNull NetworkAgentConfig config,
@Nullable NetworkProvider provider) {
this(looper, context, logTag, nc, lp, score, config,
provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(),
getLegacyNetworkInfo(config));
@@ -395,12 +405,12 @@ public abstract class NetworkAgent {
public final Context context;
public final NetworkCapabilities capabilities;
public final LinkProperties properties;
public final int score;
public final NetworkScore score;
public final NetworkAgentConfig config;
public final NetworkInfo info;
InitialConfiguration(@NonNull Context context, @NonNull NetworkCapabilities capabilities,
@NonNull LinkProperties properties, int score, @NonNull NetworkAgentConfig config,
@NonNull NetworkInfo info) {
@NonNull LinkProperties properties, @NonNull NetworkScore score,
@NonNull NetworkAgentConfig config, @NonNull NetworkInfo info) {
this.context = context;
this.capabilities = capabilities;
this.properties = properties;
@@ -412,8 +422,9 @@ public abstract class NetworkAgent {
private volatile InitialConfiguration mInitialConfiguration;
private NetworkAgent(@NonNull Looper looper, @NonNull Context context, @NonNull String logTag,
@NonNull NetworkCapabilities nc, @NonNull LinkProperties lp, int score,
@NonNull NetworkAgentConfig config, int providerId, @NonNull NetworkInfo ni) {
@NonNull NetworkCapabilities nc, @NonNull LinkProperties lp,
@NonNull NetworkScore score, @NonNull NetworkAgentConfig config, int providerId,
@NonNull NetworkInfo ni) {
mHandler = new NetworkAgentHandler(looper);
LOG_TAG = logTag;
mNetworkInfo = new NetworkInfo(ni);
@@ -872,16 +883,25 @@ public abstract class NetworkAgent {
queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
}
/**
* Must be called by the agent to update the score of this network.
*
* @param score the new score.
* @hide TODO : unhide when impl is complete
*/
public final void sendNetworkScore(@NonNull NetworkScore score) {
Objects.requireNonNull(score);
queueOrSendMessage(reg -> reg.sendScore(score));
}
/**
* Must be called by the agent to update the score of this network.
*
* @param score the new score, between 0 and 99.
* deprecated use sendNetworkScore(NetworkScore) TODO : remove in S.
*/
public final void sendNetworkScore(@IntRange(from = 0, to = 99) int score) {
if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0");
}
queueOrSendMessage(reg -> reg.sendScore(score));
sendNetworkScore(new NetworkScore.Builder().setLegacyInt(score).build());
}
/**

View File

@@ -19,11 +19,12 @@ import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkScore;
import android.net.QosSession;
import android.telephony.data.EpsBearerQosSessionAttributes;
/**
* Interface for NetworkAgents to send network network properties.
* Interface for NetworkAgents to send network properties.
* @hide
*/
oneway interface INetworkAgentRegistry {
@@ -31,7 +32,7 @@ oneway interface INetworkAgentRegistry {
void sendLinkProperties(in LinkProperties lp);
// TODO: consider replacing this by "markConnected()" and removing
void sendNetworkInfo(in NetworkInfo info);
void sendScore(int score);
void sendScore(in NetworkScore score);
void sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial);
void sendSocketKeepaliveEvent(int slot, int reason);
void sendUnderlyingNetworks(in @nullable List<Network> networks);

View File

@@ -117,6 +117,7 @@ import android.net.NetworkMonitorManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.NetworkScore;
import android.net.NetworkSpecifier;
import android.net.NetworkStack;
import android.net.NetworkStackClient;
@@ -1273,12 +1274,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
mDnsManager = new DnsManager(mContext, mDnsResolver);
registerPrivateDnsSettingsCallbacks();
// This NAI is a sentinel used to offer no service to apps that are on a multi-layer
// request that doesn't allow fallback to the default network. It should never be visible
// to apps. As such, it's not in the list of NAIs and doesn't need many of the normal
// arguments like the handler or the DnsResolver.
// TODO : remove this ; it is probably better handled with a sentinel request.
mNoServiceNetwork = new NetworkAgentInfo(null,
new Network(NO_SERVICE_NET_ID),
new NetworkInfo(TYPE_NONE, 0, "", ""),
new LinkProperties(), new NetworkCapabilities(), 0, mContext,
null, new NetworkAgentConfig(), this, null,
null, 0, INVALID_UID, mQosCallbackTracker, mDeps);
new LinkProperties(), new NetworkCapabilities(),
new NetworkScore.Builder().setLegacyInt(0).build(), mContext, null,
new NetworkAgentConfig(), this, null, null, 0, INVALID_UID, mQosCallbackTracker,
mDeps);
}
private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
@@ -2949,7 +2956,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
break;
}
case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
updateNetworkScore(nai, msg.arg1);
updateNetworkScore(nai, (NetworkScore) arg.second);
break;
}
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
@@ -6083,20 +6090,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
return nai == getDefaultNetwork();
}
// TODO : remove this method. It's a stopgap measure to help sheperding a number of dependent
// changes that would conflict throughout the automerger graph. Having this method temporarily
// helps with the process of going through with all these dependent changes across the entire
// tree.
/**
* Register a new agent. {@see #registerNetworkAgent} below.
*/
public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkAgentConfig networkAgentConfig) {
return registerNetworkAgent(na, networkInfo, linkProperties, networkCapabilities,
currentScore, networkAgentConfig, NetworkProvider.ID_NONE);
}
/**
* Register a new agent with ConnectivityService to handle a network.
*
@@ -6107,7 +6100,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
* later : see {@link #updateLinkProperties}.
* @param networkCapabilities the initial capabilites of this network. They can be updated
* later : see {@link #updateCapabilities}.
* @param currentScore the initial score of the network. See
* @param initialScore the initial score of the network. See
* {@link NetworkAgentInfo#getCurrentScore}.
* @param networkAgentConfig metadata about the network. This is never updated.
* @param providerId the ID of the provider owning this NetworkAgent.
@@ -6115,10 +6108,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
@NonNull NetworkScore initialScore, NetworkAgentConfig networkAgentConfig,
int providerId) {
Objects.requireNonNull(networkInfo, "networkInfo must not be null");
Objects.requireNonNull(linkProperties, "linkProperties must not be null");
Objects.requireNonNull(networkCapabilities, "networkCapabilities must not be null");
Objects.requireNonNull(initialScore, "initialScore must not be null");
Objects.requireNonNull(networkAgentConfig, "networkAgentConfig must not be null");
if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS);
@@ -6130,7 +6125,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final long token = Binder.clearCallingIdentity();
try {
return registerNetworkAgentInternal(na, networkInfo, linkProperties,
networkCapabilities, currentScore, networkAgentConfig, providerId, uid);
networkCapabilities, initialScore, networkAgentConfig, providerId, uid);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -6138,7 +6133,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid) {
NetworkScore currentScore, NetworkAgentConfig networkAgentConfig, int providerId,
int uid) {
if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
// Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
// the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
@@ -7862,7 +7858,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final int score) {
private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final NetworkScore score) {
if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score);
nai.setScore(score);
rematchAllNetworksAndRequests();

View File

@@ -35,6 +35,7 @@ import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkMonitorManager;
import android.net.NetworkRequest;
import android.net.NetworkScore;
import android.net.NetworkStateSnapshot;
import android.net.QosCallbackException;
import android.net.QosFilter;
@@ -302,8 +303,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// validated).
private boolean mInactive;
// This represents the quality of the network with no clear scale.
private int mScore;
// This represents the quality of the network.
private NetworkScore mScore;
// The list of NetworkRequests being satisfied by this Network.
private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
@@ -338,7 +339,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
private final QosCallbackTracker mQosCallbackTracker;
public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info,
@NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, int score, Context context,
@NonNull LinkProperties lp, @NonNull NetworkCapabilities nc,
@NonNull NetworkScore score, Context context,
Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid,
QosCallbackTracker qosCallbackTracker, ConnectivityService.Dependencies deps) {
@@ -603,9 +605,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
}
@Override
public void sendScore(int score) {
mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED, score, 0,
new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
public void sendScore(@NonNull final NetworkScore score) {
mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED,
new Pair<>(NetworkAgentInfo.this, score)).sendToTarget();
}
@Override
@@ -857,7 +859,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
}
int score = mScore;
int score = mScore.getLegacyInt();
if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
}
@@ -886,7 +888,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
return getCurrentScore(true);
}
public void setScore(final int score) {
public void setScore(final NetworkScore score) {
mScore = score;
}

View File

@@ -202,6 +202,7 @@ import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkPolicyManager;
import android.net.NetworkRequest;
import android.net.NetworkScore;
import android.net.NetworkSpecifier;
import android.net.NetworkStack;
import android.net.NetworkStackClient;
@@ -9160,7 +9161,8 @@ public class ConnectivityServiceTest {
ConnectivityManager.getNetworkTypeName(TYPE_MOBILE),
TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE));
return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(),
nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0,
nc, new NetworkScore.Builder().setLegacyInt(0).build(),
mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0,
INVALID_UID, mQosCallbackTracker, new ConnectivityService.Dependencies());
}

View File

@@ -40,6 +40,7 @@ import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkProvider;
import android.net.NetworkScore;
import android.os.Binder;
import android.text.format.DateUtils;
@@ -355,8 +356,9 @@ public class LingerMonitorTest {
caps.addCapability(0);
caps.addTransportType(transport);
NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */,
mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
new LinkProperties(), caps, new NetworkScore.Builder().setLegacyInt(50).build(),
mCtx, null, new NetworkAgentConfig() /* config */, mConnService, mNetd,
mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
mQosCallbackTracker, new ConnectivityService.Dependencies());
nai.everValidated = true;
return nai;

View File

@@ -1026,7 +1026,11 @@ public class VpnTest {
.thenReturn(new Network[] { new Network(101) });
when(mConnectivityManager.registerNetworkAgent(any(), any(), any(), any(),
anyInt(), any(), anyInt())).thenReturn(new Network(102));
any(), any(), anyInt())).thenAnswer(invocation -> {
// The runner has registered an agent and is now ready.
legacyRunnerReady.open();
return new Network(102);
});
final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), profile);
final TestDeps deps = (TestDeps) vpn.mDeps;
try {
@@ -1048,7 +1052,7 @@ public class VpnTest {
ArgumentCaptor<NetworkCapabilities> ncCaptor =
ArgumentCaptor.forClass(NetworkCapabilities.class);
verify(mConnectivityManager, timeout(10_000)).registerNetworkAgent(any(), any(),
lpCaptor.capture(), ncCaptor.capture(), anyInt(), any(), anyInt());
lpCaptor.capture(), ncCaptor.capture(), any(), any(), anyInt());
// In this test the expected address is always v4 so /32.
// Note that the interface needs to be specified because RouteInfo objects stored in