Merge "Clear UIDs when sharing NetworkCapabilties for ConnectivityDiagnostics."
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 589b1aa..d8a97de 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -53,7 +53,6 @@
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
-import android.os.SystemClock;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -808,7 +807,7 @@
private INetworkManagementService mNMService;
private INetworkPolicyManager mNPManager;
- private TetheringManager mTetheringManager;
+ private final TetheringManager mTetheringManager;
/**
* Tests if a given integer represents a valid network type.
@@ -2275,6 +2274,7 @@
public ConnectivityManager(Context context, IConnectivityManager service) {
mContext = Preconditions.checkNotNull(context, "missing context");
mService = Preconditions.checkNotNull(service, "missing IConnectivityManager");
+ mTetheringManager = (TetheringManager) mContext.getSystemService(Context.TETHERING_SERVICE);
sInstance = this;
}
@@ -2348,28 +2348,6 @@
return getInstanceOrNull();
}
- private static final int TETHERING_TIMEOUT_MS = 60_000;
- private final Object mTetheringLock = new Object();
-
- private TetheringManager getTetheringManager() {
- synchronized (mTetheringLock) {
- if (mTetheringManager != null) {
- return mTetheringManager;
- }
- final long before = System.currentTimeMillis();
- while ((mTetheringManager = (TetheringManager) mContext.getSystemService(
- Context.TETHERING_SERVICE)) == null) {
- if (System.currentTimeMillis() - before > TETHERING_TIMEOUT_MS) {
- Log.e(TAG, "Timeout waiting tethering service not ready yet");
- throw new IllegalStateException("No tethering service yet");
- }
- SystemClock.sleep(100);
- }
-
- return mTetheringManager;
- }
- }
-
/**
* Get the set of tetherable, available interfaces. This list is limited by
* device configuration and current interface existence.
@@ -2383,7 +2361,7 @@
@UnsupportedAppUsage
@Deprecated
public String[] getTetherableIfaces() {
- return getTetheringManager().getTetherableIfaces();
+ return mTetheringManager.getTetherableIfaces();
}
/**
@@ -2398,7 +2376,7 @@
@UnsupportedAppUsage
@Deprecated
public String[] getTetheredIfaces() {
- return getTetheringManager().getTetheredIfaces();
+ return mTetheringManager.getTetheredIfaces();
}
/**
@@ -2419,7 +2397,7 @@
@UnsupportedAppUsage
@Deprecated
public String[] getTetheringErroredIfaces() {
- return getTetheringManager().getTetheringErroredIfaces();
+ return mTetheringManager.getTetheringErroredIfaces();
}
/**
@@ -2463,7 +2441,7 @@
@UnsupportedAppUsage
@Deprecated
public int tether(String iface) {
- return getTetheringManager().tether(iface);
+ return mTetheringManager.tether(iface);
}
/**
@@ -2487,7 +2465,7 @@
@UnsupportedAppUsage
@Deprecated
public int untether(String iface) {
- return getTetheringManager().untether(iface);
+ return mTetheringManager.untether(iface);
}
/**
@@ -2513,7 +2491,7 @@
@RequiresPermission(anyOf = {android.Manifest.permission.TETHER_PRIVILEGED,
android.Manifest.permission.WRITE_SETTINGS})
public boolean isTetheringSupported() {
- return getTetheringManager().isTetheringSupported();
+ return mTetheringManager.isTetheringSupported();
}
/**
@@ -2606,7 +2584,7 @@
final TetheringRequest request = new TetheringRequest.Builder(type)
.setSilentProvisioning(!showProvisioningUi).build();
- getTetheringManager().startTethering(request, executor, tetheringCallback);
+ mTetheringManager.startTethering(request, executor, tetheringCallback);
}
/**
@@ -2625,7 +2603,7 @@
@Deprecated
@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)
public void stopTethering(int type) {
- getTetheringManager().stopTethering(type);
+ mTetheringManager.stopTethering(type);
}
/**
@@ -2683,7 +2661,7 @@
synchronized (mTetheringEventCallbacks) {
mTetheringEventCallbacks.put(callback, tetherCallback);
- getTetheringManager().registerTetheringEventCallback(executor, tetherCallback);
+ mTetheringManager.registerTetheringEventCallback(executor, tetherCallback);
}
}
@@ -2705,7 +2683,7 @@
synchronized (mTetheringEventCallbacks) {
final TetheringEventCallback tetherCallback =
mTetheringEventCallbacks.remove(callback);
- getTetheringManager().unregisterTetheringEventCallback(tetherCallback);
+ mTetheringManager.unregisterTetheringEventCallback(tetherCallback);
}
}
@@ -2725,7 +2703,7 @@
@UnsupportedAppUsage
@Deprecated
public String[] getTetherableUsbRegexs() {
- return getTetheringManager().getTetherableUsbRegexs();
+ return mTetheringManager.getTetherableUsbRegexs();
}
/**
@@ -2743,7 +2721,7 @@
@UnsupportedAppUsage
@Deprecated
public String[] getTetherableWifiRegexs() {
- return getTetheringManager().getTetherableWifiRegexs();
+ return mTetheringManager.getTetherableWifiRegexs();
}
/**
@@ -2762,7 +2740,7 @@
@UnsupportedAppUsage
@Deprecated
public String[] getTetherableBluetoothRegexs() {
- return getTetheringManager().getTetherableBluetoothRegexs();
+ return mTetheringManager.getTetherableBluetoothRegexs();
}
/**
@@ -2786,7 +2764,7 @@
@UnsupportedAppUsage
@Deprecated
public int setUsbTethering(boolean enable) {
- return getTetheringManager().setUsbTethering(enable);
+ return mTetheringManager.setUsbTethering(enable);
}
/**
@@ -2903,7 +2881,7 @@
@UnsupportedAppUsage
@Deprecated
public int getLastTetherError(String iface) {
- return getTetheringManager().getLastTetherError(iface);
+ return mTetheringManager.getLastTetherError(iface);
}
/** @hide */
@@ -2974,7 +2952,7 @@
}
};
- getTetheringManager().requestLatestTetheringEntitlementResult(type, wrappedListener,
+ mTetheringManager.requestLatestTetheringEntitlementResult(type, wrappedListener,
showEntitlementUi);
}
@@ -3244,7 +3222,9 @@
/** {@hide} - returns the factory serial number */
@UnsupportedAppUsage
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_FACTORY})
public int registerNetworkFactory(Messenger messenger, String name) {
try {
return mService.registerNetworkFactory(messenger, name);
@@ -3255,7 +3235,9 @@
/** {@hide} */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_FACTORY})
public void unregisterNetworkFactory(Messenger messenger) {
try {
mService.unregisterNetworkFactory(messenger);
@@ -3275,7 +3257,9 @@
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_FACTORY})
public int registerNetworkProvider(@NonNull NetworkProvider provider) {
if (provider.getProviderId() != NetworkProvider.ID_NONE) {
throw new IllegalStateException("NetworkProviders can only be registered once");
@@ -3298,7 +3282,9 @@
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_FACTORY})
public void unregisterNetworkProvider(@NonNull NetworkProvider provider) {
try {
mService.unregisterNetworkProvider(provider.getMessenger());
@@ -3310,7 +3296,9 @@
/** @hide exposed via the NetworkProvider class. */
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_FACTORY})
public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {
try {
mService.declareNetworkRequestUnfulfillable(request);
@@ -3328,7 +3316,9 @@
* Register a NetworkAgent with ConnectivityService.
* @return Network corresponding to NetworkAgent.
*/
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_FACTORY})
public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
NetworkCapabilities nc, int score, NetworkAgentConfig config) {
return registerNetworkAgent(messenger, ni, lp, nc, score, config, NetworkProvider.ID_NONE);
@@ -3339,9 +3329,12 @@
* Register a NetworkAgent with ConnectivityService.
* @return Network corresponding to NetworkAgent.
*/
- @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_FACTORY})
public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) {
+
try {
return mService.registerNetworkAgent(messenger, ni, lp, nc, score, config, providerId);
} catch (RemoteException e) {
@@ -4469,7 +4462,7 @@
public void factoryReset() {
try {
mService.factoryReset();
- getTetheringManager().stopAllTethering();
+ mTetheringManager.stopAllTethering();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 61a1484..fef353f 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -33,6 +33,7 @@
import com.android.internal.util.Protocol;
import java.util.ArrayList;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -50,20 +51,29 @@
/**
* The {@link Network} corresponding to this object.
*/
- @NonNull
- public final Network network;
+ @Nullable
+ private volatile Network mNetwork;
+
+ // Whether this NetworkAgent is using the legacy (never unhidden) API. The difference is
+ // that the legacy API uses NetworkInfo to convey the state, while the current API is
+ // exposing methods to manage it and generate it internally instead.
+ // TODO : remove this as soon as all agents have been converted.
+ private final boolean mIsLegacy;
private final Handler mHandler;
private volatile AsyncChannel mAsyncChannel;
private final String LOG_TAG;
private static final boolean DBG = true;
private static final boolean VDBG = false;
- private final Context mContext;
private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
private volatile long mLastBwRefreshTime = 0;
private static final long BW_REFRESH_MIN_WIN_MS = 500;
private boolean mBandwidthUpdateScheduled = false;
private AtomicBoolean mBandwidthUpdatePending = new AtomicBoolean(false);
+ // Not used by legacy agents. Non-legacy agents use this to convert the NetworkAgent system API
+ // into the internal API of ConnectivityService.
+ @NonNull
+ private NetworkInfo mNetworkInfo;
/**
* The ID of the {@link NetworkProvider} that created this object, or
@@ -116,7 +126,7 @@
/**
* Sent by the NetworkAgent to ConnectivityService to pass the current
* network score.
- * obj = network score Integer
+ * arg1 = network score int
* @hide
*/
public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
@@ -266,31 +276,38 @@
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score) {
this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE);
+ // Register done by the constructor called in the previous line
}
/** @hide TODO: remove and replace usage with the public constructor. */
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config) {
this(looper, context, logTag, ni, nc, lp, score, config, NetworkProvider.ID_NONE);
+ // Register done by the constructor called in the previous line
}
/** @hide TODO: remove and replace usage with the public constructor. */
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score, int providerId) {
this(looper, context, logTag, ni, nc, lp, score, null, providerId);
+ // Register done by the constructor called in the previous line
}
/** @hide TODO: remove and replace usage with the public constructor. */
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config,
int providerId) {
- this(looper, context, logTag, nc, lp, score, config, providerId, ni);
+ this(looper, context, logTag, nc, lp, score, config, providerId, ni, true /* legacy */);
+ register();
}
private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
// The subtype can be changed with (TODO) setLegacySubtype, but it starts
// with the type and an empty description.
- return new NetworkInfo(config.legacyType, config.legacyType, config.legacyTypeName, "");
+ final NetworkInfo ni = new NetworkInfo(config.legacyType, config.legacyType,
+ config.legacyTypeName, "");
+ ni.setIsAvailable(true);
+ return ni;
}
/**
@@ -310,26 +327,44 @@
@NonNull NetworkAgentConfig config, @Nullable NetworkProvider provider) {
this(looper, context, logTag, nc, lp, score, config,
provider == null ? NetworkProvider.ID_NONE : provider.getProviderId(),
- getLegacyNetworkInfo(config));
+ getLegacyNetworkInfo(config), false /* legacy */);
}
- private NetworkAgent(Looper looper, Context context, String logTag, NetworkCapabilities nc,
- LinkProperties lp, int score, NetworkAgentConfig config, int providerId,
- NetworkInfo ni) {
+ private static class InitialConfiguration {
+ public final Context context;
+ public final NetworkCapabilities capabilities;
+ public final LinkProperties properties;
+ public final int 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) {
+ this.context = context;
+ this.capabilities = capabilities;
+ this.properties = properties;
+ this.score = score;
+ this.config = config;
+ this.info = info;
+ }
+ }
+ 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,
+ boolean legacy) {
mHandler = new NetworkAgentHandler(looper);
LOG_TAG = logTag;
- mContext = context;
+ mIsLegacy = legacy;
+ mNetworkInfo = new NetworkInfo(ni);
this.providerId = providerId;
if (ni == null || nc == null || lp == null) {
throw new IllegalArgumentException();
}
- if (VDBG) log("Registering NetworkAgent");
- ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- network = cm.registerNetworkAgent(new Messenger(mHandler), new NetworkInfo(ni),
- new LinkProperties(lp), new NetworkCapabilities(nc), score, config,
- providerId);
+ mInitialConfiguration = new InitialConfiguration(context, new NetworkCapabilities(nc),
+ new LinkProperties(lp), score, config, ni);
}
private class NetworkAgentHandler extends Handler {
@@ -451,6 +486,32 @@
}
}
+ /**
+ * Register this network agent with ConnectivityService.
+ * @return the Network associated with this network agent (which can also be obtained later
+ * by calling getNetwork() on this agent).
+ */
+ @NonNull
+ public Network register() {
+ if (VDBG) log("Registering NetworkAgent");
+ final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ mNetwork = cm.registerNetworkAgent(new Messenger(mHandler),
+ new NetworkInfo(mInitialConfiguration.info),
+ mInitialConfiguration.properties, mInitialConfiguration.capabilities,
+ mInitialConfiguration.score, mInitialConfiguration.config, providerId);
+ mInitialConfiguration = null; // All this memory can now be GC'd
+ return mNetwork;
+ }
+
+ /**
+ * @return The Network associated with this agent, or null if it's not registered yet.
+ */
+ @Nullable
+ public Network getNetwork() {
+ return mNetwork;
+ }
+
private void queueOrSendMessage(int what, Object obj) {
queueOrSendMessage(what, 0, 0, obj);
}
@@ -483,15 +544,89 @@
* @param linkProperties the new LinkProperties.
*/
public void sendLinkProperties(@NonNull LinkProperties linkProperties) {
+ Objects.requireNonNull(linkProperties);
queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
}
/**
+ * Inform ConnectivityService that this agent has now connected.
+ */
+ public void setConnected() {
+ if (mIsLegacy) {
+ throw new UnsupportedOperationException(
+ "Legacy agents can't call setConnected.");
+ }
+ mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
+ queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+ }
+
+ /**
+ * Unregister this network agent.
+ *
+ * This signals the network has disconnected and ends its lifecycle. After this is called,
+ * the network is torn down and this agent can no longer be used.
+ */
+ public void unregister() {
+ if (mIsLegacy) {
+ throw new UnsupportedOperationException(
+ "Legacy agents can't call unregister.");
+ }
+ mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
+ queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+ }
+
+ /**
+ * Change the legacy subtype of this network agent.
+ *
+ * This is only for backward compatibility and should not be used by non-legacy network agents,
+ * or agents that did not use to set a subtype. As such, only TYPE_MOBILE type agents can use
+ * this and others will be thrown an exception if they try.
+ *
+ * @deprecated this is for backward compatibility only.
+ * @param legacySubtype the legacy subtype.
+ */
+ @Deprecated
+ public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) {
+ if (mIsLegacy) {
+ throw new UnsupportedOperationException("Legacy agents can't call setLegacySubtype.");
+ }
+ mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName);
+ queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+ }
+
+ /**
+ * Set the ExtraInfo of this network agent.
+ *
+ * This sets the ExtraInfo field inside the NetworkInfo returned by legacy public API and the
+ * broadcasts about the corresponding Network.
+ * This is only for backward compatibility and should not be used by non-legacy network agents,
+ * who will be thrown an exception if they try. The extra info should only be :
+ * <ul>
+ * <li>For cellular agents, the APN name.</li>
+ * <li>For ethernet agents, the interface name.</li>
+ * </ul>
+ *
+ * @deprecated this is for backward compatibility only.
+ * @param extraInfo the ExtraInfo.
+ */
+ @Deprecated
+ public void setLegacyExtraInfo(@Nullable final String extraInfo) {
+ if (mIsLegacy) {
+ throw new UnsupportedOperationException("Legacy agents can't call setLegacyExtraInfo.");
+ }
+ mNetworkInfo.setExtraInfo(extraInfo);
+ queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo);
+ }
+
+ /**
* Must be called by the agent when it has a new NetworkInfo object.
* @hide TODO: expose something better.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public void sendNetworkInfo(NetworkInfo networkInfo) {
+ if (!mIsLegacy) {
+ throw new UnsupportedOperationException("Only legacy agents can call sendNetworkInfo.");
+ }
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo));
}
@@ -500,6 +635,7 @@
* @param networkCapabilities the new NetworkCapabilities.
*/
public void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
+ Objects.requireNonNull(networkCapabilities);
mBandwidthUpdatePending.set(false);
mLastBwRefreshTime = System.currentTimeMillis();
queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
@@ -514,18 +650,7 @@
if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0");
}
- final NetworkScore ns = new NetworkScore();
- ns.putIntExtension(NetworkScore.LEGACY_SCORE, score);
- updateScore(ns);
- }
-
- /**
- * Must be called by the agent when it has a new {@link NetworkScore} for this network.
- * @param ns the new score.
- * @hide TODO: unhide the NetworkScore class, and rename to sendNetworkScore.
- */
- public void updateScore(@NonNull NetworkScore ns) {
- queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new NetworkScore(ns));
+ queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score, 0);
}
/**
diff --git a/core/java/android/net/NetworkAgentConfig.java b/core/java/android/net/NetworkAgentConfig.java
index 2c5a113..7e2db4a 100644
--- a/core/java/android/net/NetworkAgentConfig.java
+++ b/core/java/android/net/NetworkAgentConfig.java
@@ -22,6 +22,8 @@
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.
@@ -52,23 +54,47 @@
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
* procedure, a carrier specific provisioning notification will be placed.
@@ -134,9 +160,11 @@
* 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 @@
allowBypass = nac.allowBypass;
explicitlySelected = nac.explicitlySelected;
acceptUnvalidated = nac.acceptUnvalidated;
+ acceptPartialConnectivity = nac.acceptPartialConnectivity;
subscriberId = nac.subscriberId;
provisioningNotificationDisabled = nac.provisioningNotificationDisabled;
skip464xlat = nac.skip464xlat;
@@ -178,6 +207,43 @@
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.
*
* @return this builder, to facilitate chaining.
@@ -245,6 +311,45 @@
}
@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 @@
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 @@
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;
}
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index d0c5363..08fe159 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -17,9 +17,11 @@
package android.net;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation.NetworkType;
import com.android.internal.annotations.VisibleForTesting;
@@ -150,10 +152,19 @@
private boolean mIsRoaming;
/**
- * @hide
+ * Create a new instance of NetworkInfo.
+ *
+ * This may be useful for apps to write unit tests.
+ *
+ * @param type the legacy type of the network, as one of the ConnectivityManager.TYPE_*
+ * constants.
+ * @param subtype the subtype if applicable, as one of the TelephonyManager.NETWORK_TYPE_*
+ * constants.
+ * @param typeName a human-readable string for the network type, or an empty string or null.
+ * @param subtypeName a human-readable string for the subtype, or an empty string or null.
*/
- @UnsupportedAppUsage
- public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
+ public NetworkInfo(int type, @NetworkType int subtype,
+ @Nullable String typeName, @Nullable String subtypeName) {
if (!ConnectivityManager.isNetworkTypeValid(type)
&& type != ConnectivityManager.TYPE_NONE) {
throw new IllegalArgumentException("Invalid network type: " + type);
@@ -462,17 +473,19 @@
/**
* Sets the fine-grained state of the network.
+ *
+ * This is only useful for testing.
+ *
* @param detailedState the {@link DetailedState}.
* @param reason a {@code String} indicating the reason for the state change,
* if one was supplied. May be {@code null}.
* @param extraInfo an optional {@code String} providing addditional network state
* information passed up from the lower networking layers.
* @deprecated Use {@link NetworkCapabilities} instead.
- * @hide
*/
@Deprecated
- @UnsupportedAppUsage
- public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
+ public void setDetailedState(@NonNull DetailedState detailedState, @Nullable String reason,
+ @Nullable String extraInfo) {
synchronized (this) {
this.mDetailedState = detailedState;
this.mState = stateMap.get(detailedState);
diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java
deleted file mode 100644
index 13f2994..0000000
--- a/core/java/android/net/NetworkScore.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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 android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * 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
- */
-public final class NetworkScore implements Parcelable {
-
- // The key of bundle which is used to get the legacy network score of NetworkAgentInfo.
- // TODO: Remove this when the transition to NetworkScore is over.
- public static final String LEGACY_SCORE = "LEGACY_SCORE";
- @NonNull
- private final Bundle mExtensions;
-
- public NetworkScore() {
- mExtensions = new Bundle();
- }
-
- public NetworkScore(@NonNull NetworkScore source) {
- mExtensions = new Bundle(source.mExtensions);
- }
-
- /**
- * Put the value of parcelable inside the bundle by key.
- */
- public void putExtension(@Nullable String key, @Nullable Parcelable value) {
- mExtensions.putParcelable(key, value);
- }
-
- /**
- * Put the value of int inside the bundle by key.
- */
- public void putIntExtension(@Nullable String key, int value) {
- mExtensions.putInt(key, value);
- }
-
- /**
- * Get the value of non primitive type by key.
- */
- public <T extends Parcelable> T getExtension(@Nullable String key) {
- return mExtensions.getParcelable(key);
- }
-
- /**
- * Get the value of int by key.
- */
- public int getIntExtension(@Nullable String key) {
- return mExtensions.getInt(key);
- }
-
- /**
- * Remove the entry by given key.
- */
- public void removeExtension(@Nullable String key) {
- mExtensions.remove(key);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- synchronized (this) {
- dest.writeBundle(mExtensions);
- }
- }
-
- public static final @NonNull Creator<NetworkScore> CREATOR = new Creator<NetworkScore>() {
- @Override
- public NetworkScore createFromParcel(@NonNull Parcel in) {
- return new NetworkScore(in);
- }
-
- @Override
- public NetworkScore[] newArray(int size) {
- return new NetworkScore[size];
- }
- };
-
- private NetworkScore(@NonNull Parcel in) {
- mExtensions = in.readBundle();
- }
-
- // TODO: Modify this method once new fields are added into this class.
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof NetworkScore)) {
- return false;
- }
- final NetworkScore other = (NetworkScore) obj;
- return bundlesEqual(mExtensions, other.mExtensions);
- }
-
- @Override
- public int hashCode() {
- int result = 29;
- for (String key : mExtensions.keySet()) {
- final Object value = mExtensions.get(key);
- // The key may be null, so call Objects.hash() is safer.
- result += 31 * value.hashCode() + 37 * Objects.hash(key);
- }
- return result;
- }
-
- // mExtensions won't be null since the constructor will create it.
- private boolean bundlesEqual(@NonNull Bundle bundle1, @NonNull Bundle bundle2) {
- if (bundle1 == bundle2) {
- return true;
- }
-
- // This is unlikely but it's fine to add this clause here.
- if (null == bundle1 || null == bundle2) {
- return false;
- }
-
- if (bundle1.size() != bundle2.size()) {
- return false;
- }
-
- for (String key : bundle1.keySet()) {
- final Object value1 = bundle1.get(key);
- final Object value2 = bundle2.get(key);
- if (!Objects.equals(value1, value2)) {
- return false;
- }
- }
- return true;
- }
-
- /** Convert to a string */
- public String toString() {
- return "NetworkScore[" + mExtensions.toString() + "]";
- }
-}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 845a322..6211769 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -104,7 +104,6 @@
import android.net.NetworkProvider;
import android.net.NetworkQuotaInfo;
import android.net.NetworkRequest;
-import android.net.NetworkScore;
import android.net.NetworkSpecifier;
import android.net.NetworkStack;
import android.net.NetworkStackClient;
@@ -2094,9 +2093,9 @@
}
private void enforceNetworkFactoryPermission() {
- mContext.enforceCallingOrSelfPermission(
+ enforceAnyPermissionOf(
android.Manifest.permission.NETWORK_FACTORY,
- "ConnectivityService");
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
}
private boolean checkSettingsPermission() {
@@ -2724,8 +2723,7 @@
break;
}
case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
- final NetworkScore ns = (NetworkScore) msg.obj;
- updateNetworkScore(nai, ns);
+ updateNetworkScore(nai, msg.arg1);
break;
}
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
@@ -5812,12 +5810,10 @@
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest.
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
- final NetworkScore ns = new NetworkScore();
- ns.putIntExtension(NetworkScore.LEGACY_SCORE, currentScore);
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
- ns, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), this,
- mNetd, mDnsResolver, mNMS, providerId);
+ currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
+ this, mNetd, mDnsResolver, mNMS, providerId);
// Make sure the network capabilities reflect what the agent info says.
nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
final String extraInfo = networkInfo.getExtraInfo();
@@ -7075,9 +7071,9 @@
}
}
- private void updateNetworkScore(NetworkAgentInfo nai, NetworkScore ns) {
- if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + ns);
- nai.setNetworkScore(ns);
+ private void updateNetworkScore(@NonNull final NetworkAgentInfo nai, final int score) {
+ if (VDBG || DDBG) log("updateNetworkScore for " + nai.toShortString() + " to " + score);
+ nai.setScore(score);
rematchAllNetworksAndRequests();
sendUpdatedScoreToFactories(nai);
}
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index a7e36b2..95ac900 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -219,7 +219,7 @@
// Has to be in TestNetworkAgent to ensure all teardown codepaths properly clean up
// resources, even for binder death or unwanted calls.
synchronized (mTestNetworkTracker) {
- mTestNetworkTracker.remove(network.netId);
+ mTestNetworkTracker.remove(getNetwork().netId);
}
}
}
@@ -338,7 +338,7 @@
callingUid,
binder);
- mTestNetworkTracker.put(agent.network.netId, agent);
+ mTestNetworkTracker.put(agent.getNetwork().netId, agent);
}
} catch (SocketException e) {
throw new UncheckedIOException(e);
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 58b5cba..23b954c 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -32,7 +32,6 @@
import android.net.NetworkInfo;
import android.net.NetworkMonitorManager;
import android.net.NetworkRequest;
-import android.net.NetworkScore;
import android.net.NetworkState;
import android.os.Handler;
import android.os.INetworkManagementService;
@@ -236,10 +235,8 @@
// validated).
private boolean mLingering;
- // This represents the characteristics of a network that affects how good the network is
- // considered for a particular use.
- @NonNull
- private NetworkScore mNetworkScore;
+ // This represents the quality of the network with no clear scale.
+ private int mScore;
// The list of NetworkRequests being satisfied by this Network.
private final SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
@@ -268,7 +265,7 @@
private final Handler mHandler;
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
- LinkProperties lp, NetworkCapabilities nc, @NonNull NetworkScore ns, Context context,
+ LinkProperties lp, NetworkCapabilities nc, int score, Context context,
Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) {
this.messenger = messenger;
@@ -277,7 +274,7 @@
networkInfo = info;
linkProperties = lp;
networkCapabilities = nc;
- mNetworkScore = ns;
+ mScore = score;
clatd = new Nat464Xlat(this, netd, dnsResolver, nms);
mConnService = connService;
mContext = context;
@@ -491,7 +488,7 @@
return ConnectivityConstants.EXPLICITLY_SELECTED_NETWORK_SCORE;
}
- int score = mNetworkScore.getIntExtension(NetworkScore.LEGACY_SCORE);
+ int score = mScore;
if (!lastValidated && !pretendValidated && !ignoreWifiUnvalidationPenalty() && !isVPN()) {
score -= ConnectivityConstants.UNVALIDATED_SCORE_PENALTY;
}
@@ -520,13 +517,8 @@
return getCurrentScore(true);
}
- public void setNetworkScore(@NonNull NetworkScore ns) {
- mNetworkScore = ns;
- }
-
- @NonNull
- public NetworkScore getNetworkScore() {
- return mNetworkScore;
+ public void setScore(final int score) {
+ mScore = score;
}
public NetworkState getNetworkState() {
diff --git a/tests/net/common/java/android/net/CaptivePortalTest.java b/tests/net/common/java/android/net/CaptivePortalTest.java
index ca4ba63..7a60cc1 100644
--- a/tests/net/common/java/android/net/CaptivePortalTest.java
+++ b/tests/net/common/java/android/net/CaptivePortalTest.java
@@ -18,19 +18,26 @@
import static org.junit.Assert.assertEquals;
+import android.os.Build;
import android.os.RemoteException;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class CaptivePortalTest {
+ @Rule
+ public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
+
private static final int DEFAULT_TIMEOUT_MS = 5000;
private static final String TEST_PACKAGE_NAME = "com.google.android.test";
@@ -84,6 +91,7 @@
assertEquals(result.mCode, CaptivePortal.APP_RETURN_WANTED_AS_IS);
}
+ @IgnoreUpTo(Build.VERSION_CODES.Q)
@Test
public void testReevaluateNetwork() {
final MyCaptivePortalImpl result = runCaptivePortalTest(c -> c.reevaluateNetwork());
diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java
index 06c6301..99dac14 100644
--- a/tests/net/common/java/android/net/LinkAddressTest.java
+++ b/tests/net/common/java/android/net/LinkAddressTest.java
@@ -28,8 +28,8 @@
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
@@ -38,11 +38,17 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import android.os.Build;
import android.os.SystemClock;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,6 +63,8 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LinkAddressTest {
+ @Rule
+ public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
private static final String V4 = "192.0.2.1";
private static final String V6 = "2001:db8::1";
@@ -318,15 +326,29 @@
l = new LinkAddress(V6_ADDRESS, 64, 123, 456);
assertParcelingIsLossless(l);
- l = new LinkAddress(V6_ADDRESS, 64, 123, 456,
- 1L, 3600000L);
- assertParcelingIsLossless(l);
l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK);
- assertParcelSane(l, 6);
+ assertParcelingIsLossless(l);
}
- @Test
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ public void testLifetimeParceling() {
+ final LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, 456, 1L, 3600000L);
+ assertParcelingIsLossless(l);
+ }
+
+ @Test @IgnoreAfter(Build.VERSION_CODES.Q)
+ public void testFieldCount_Q() {
+ assertFieldCountEquals(4, LinkAddress.class);
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ public void testFieldCount() {
+ // Make sure any new field is covered by the above parceling tests when changing this number
+ assertFieldCountEquals(6, LinkAddress.class);
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
public void testDeprecationTime() {
try {
new LinkAddress(V6_ADDRESS, 64, 0, 456,
@@ -347,7 +369,7 @@
} catch (IllegalArgumentException expected) { }
}
- @Test
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
public void testExpirationTime() {
try {
new LinkAddress(V6_ADDRESS, 64, 0, 456,
@@ -366,10 +388,13 @@
public void testGetFlags() {
LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 123, RT_SCOPE_HOST);
assertEquals(123, l.getFlags());
+ }
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ public void testGetFlags_Deprecation() {
// Test if deprecated bit was added/remove automatically based on the provided deprecation
// time
- l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_HOST,
+ LinkAddress l = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_HOST,
1L, LinkAddress.LIFETIME_PERMANENT);
// Check if the flag is added automatically.
assertTrue((l.getFlags() & IFA_F_DEPRECATED) != 0);
@@ -458,8 +483,11 @@
(IFA_F_TEMPORARY|IFA_F_TENTATIVE|IFA_F_OPTIMISTIC),
RT_SCOPE_UNIVERSE);
assertGlobalPreferred(l, "v6,global,tempaddr+optimistic");
+ }
- l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED,
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ public void testIsGlobalPreferred_DeprecatedInFuture() {
+ final LinkAddress l = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED,
RT_SCOPE_UNIVERSE, SystemClock.elapsedRealtime() + 100000,
SystemClock.elapsedRealtime() + 200000);
// Although the deprecated bit is set, but the deprecation time is in the future, test
diff --git a/tests/net/common/java/android/net/NetworkAgentConfigTest.kt b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
new file mode 100644
index 0000000..173dbd1
--- /dev/null
+++ b/tests/net/common/java/android/net/NetworkAgentConfigTest.kt
@@ -0,0 +1,46 @@
+/*
+ * 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 android.os.Build
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
+import com.android.testutils.assertParcelSane
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class NetworkAgentConfigTest {
+ @Rule @JvmField
+ val ignoreRule = DevSdkIgnoreRule()
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
+ fun testParcelNetworkAgentConfig() {
+ val config = NetworkAgentConfig.Builder().apply {
+ setExplicitlySelected(true)
+ setLegacyType(ConnectivityManager.TYPE_ETHERNET)
+ setSubscriberId("MySubId")
+ setPartialConnectivityAcceptable(false)
+ setUnvalidatedConnectivityAcceptable(true)
+ }.build()
+ assertParcelSane(config, 9)
+ }
+}
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index 1c69209..a35fb40 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -222,7 +222,7 @@
@Override
public Network getNetwork() {
- return mNetworkAgent.network;
+ return mNetworkAgent.getNetwork();
}
public void expectPreventReconnectReceived(long timeoutMs) {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 2980ff7..c1999db 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -646,7 +646,7 @@
}
};
- assertEquals(na.network.netId, nmNetworkCaptor.getValue().netId);
+ assertEquals(na.getNetwork().netId, nmNetworkCaptor.getValue().netId);
mNmCallbacks = nmCbCaptor.getValue();
mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor);
@@ -5926,6 +5926,12 @@
final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64");
final String kNat64PrefixString = "2001:db8:64:64:64:64::";
final IpPrefix kNat64Prefix = new IpPrefix(InetAddress.getByName(kNat64PrefixString), 96);
+ final RouteInfo defaultRoute = new RouteInfo((IpPrefix) null, myIpv6.getAddress(),
+ MOBILE_IFNAME);
+ final RouteInfo ipv6Subnet = new RouteInfo(myIpv6, null, MOBILE_IFNAME);
+ final RouteInfo ipv4Subnet = new RouteInfo(myIpv4, null, MOBILE_IFNAME);
+ final RouteInfo stackedDefault = new RouteInfo((IpPrefix) null, myIpv4.getAddress(),
+ CLAT_PREFIX + MOBILE_IFNAME);
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_CELLULAR)
@@ -5938,15 +5944,13 @@
final LinkProperties cellLp = new LinkProperties();
cellLp.setInterfaceName(MOBILE_IFNAME);
cellLp.addLinkAddress(myIpv6);
- cellLp.addRoute(new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME));
- cellLp.addRoute(new RouteInfo(myIpv6, null, MOBILE_IFNAME));
+ cellLp.addRoute(defaultRoute);
+ cellLp.addRoute(ipv6Subnet);
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
reset(mNetworkManagementService);
reset(mMockDnsResolver);
reset(mMockNetd);
reset(mBatteryStatsService);
- when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
- .thenReturn(getClatInterfaceConfig(myIpv4));
// Connect with ipv6 link properties. Expect prefix discovery to be started.
mCellNetworkAgent.connect(true);
@@ -5954,6 +5958,7 @@
waitForIdle();
verify(mMockNetd, times(1)).networkCreatePhysical(eq(cellNetId), anyInt());
+ assertRoutesAdded(cellNetId, ipv6Subnet, defaultRoute);
verify(mMockDnsResolver, times(1)).createNetworkCache(eq(cellNetId));
verify(mBatteryStatsService).noteNetworkInterfaceType(cellLp.getInterfaceName(),
TYPE_MOBILE);
@@ -5969,6 +5974,7 @@
cellLp.addLinkAddress(myIpv4);
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ assertRoutesAdded(cellNetId, ipv4Subnet);
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
@@ -5979,15 +5985,18 @@
verifyNoMoreInteractions(mMockNetd);
verifyNoMoreInteractions(mMockDnsResolver);
+ reset(mNetworkManagementService);
reset(mMockNetd);
reset(mMockDnsResolver);
+ when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
+ .thenReturn(getClatInterfaceConfig(myIpv4));
// Remove IPv4 address. Expect prefix discovery to be started again.
cellLp.removeLinkAddress(myIpv4);
- cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
+ assertRoutesRemoved(cellNetId, ipv4Subnet);
// When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent);
@@ -6006,6 +6015,7 @@
List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork())
.getStackedLinks();
assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0));
+ assertRoutesAdded(cellNetId, stackedDefault);
// Change trivial linkproperties and see if stacked link is preserved.
cellLp.addDnsServer(InetAddress.getByName("8.8.8.8"));
@@ -6031,9 +6041,10 @@
// Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
// linkproperties are cleaned up.
cellLp.addLinkAddress(myIpv4);
- cellLp.addRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
+ cellLp.addRoute(ipv4Subnet);
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ assertRoutesAdded(cellNetId, ipv4Subnet);
verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
@@ -6044,6 +6055,7 @@
expected.setNat64Prefix(kNat64Prefix);
assertEquals(expected, actualLpAfterIpv4);
assertEquals(0, actualLpAfterIpv4.getStackedLinks().size());
+ assertRoutesRemoved(cellNetId, stackedDefault);
// The interface removed callback happens but has no effect after stop is called.
clat.interfaceRemoved(CLAT_PREFIX + MOBILE_IFNAME);
@@ -6051,8 +6063,11 @@
verifyNoMoreInteractions(mMockNetd);
verifyNoMoreInteractions(mMockDnsResolver);
+ reset(mNetworkManagementService);
reset(mMockNetd);
reset(mMockDnsResolver);
+ when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
+ .thenReturn(getClatInterfaceConfig(myIpv4));
// Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
@@ -6066,6 +6081,7 @@
cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8"));
mCellNetworkAgent.sendLinkProperties(cellLp);
networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added.
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
kNat64PrefixString, 96);
@@ -6077,15 +6093,20 @@
clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
(lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null);
+ assertRoutesAdded(cellNetId, stackedDefault);
// NAT64 prefix is removed. Expect that clat is stopped.
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
kNat64PrefixString, 96);
networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
(lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null);
+ assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault);
+
+ // Stop has no effect because clat is already stopped.
verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
(lp) -> lp.getStackedLinks().size() == 0);
+ verifyNoMoreInteractions(mMockNetd);
// Clean up.
mCellNetworkAgent.disconnect();
@@ -6653,6 +6674,20 @@
}
}
+ private void assertRoutesAdded(int netId, RouteInfo... routes) throws Exception {
+ InOrder inOrder = inOrder(mNetworkManagementService);
+ for (int i = 0; i < routes.length; i++) {
+ inOrder.verify(mNetworkManagementService).addRoute(eq(netId), eq(routes[i]));
+ }
+ }
+
+ private void assertRoutesRemoved(int netId, RouteInfo... routes) throws Exception {
+ InOrder inOrder = inOrder(mNetworkManagementService);
+ for (int i = 0; i < routes.length; i++) {
+ inOrder.verify(mNetworkManagementService).removeRoute(eq(netId), eq(routes[i]));
+ }
+ }
+
@Test
public void testRegisterUnregisterConnectivityDiagnosticsCallback() throws Exception {
final NetworkRequest wifiRequest =
@@ -6714,7 +6749,7 @@
public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception {
final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo(
- null, null, null, null, null, new NetworkCapabilities(), null,
+ null, null, null, null, null, new NetworkCapabilities(), 0,
mServiceContext, null, null, mService, null, null, null, 0);
mServiceContext.setPermission(
@@ -6730,7 +6765,7 @@
public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception {
final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo(
- null, null, null, null, null, new NetworkCapabilities(), null,
+ null, null, null, null, null, new NetworkCapabilities(), 0,
mServiceContext, null, null, mService, null, null, null, 0);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
@@ -6746,7 +6781,7 @@
public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception {
final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo(
- null, null, null, null, null, new NetworkCapabilities(), null,
+ null, null, null, null, null, new NetworkCapabilities(), 0,
mServiceContext, null, null, mService, null, null, null, 0);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
@@ -6772,7 +6807,7 @@
nc.setAdministratorUids(Arrays.asList(Process.myUid()));
final NetworkAgentInfo naiWithUid =
new NetworkAgentInfo(
- null, null, null, null, null, nc, null, mServiceContext, null, null,
+ null, null, null, null, null, nc, 0, mServiceContext, null, null,
mService, null, null, null, 0);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
@@ -6794,7 +6829,7 @@
nc.setAdministratorUids(Arrays.asList(Process.myUid()));
final NetworkAgentInfo naiWithUid =
new NetworkAgentInfo(
- null, null, null, null, null, nc, null, mServiceContext, null, null,
+ null, null, null, null, null, nc, 0, mServiceContext, null, null,
mService, null, null, null, 0);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index e863266..24a8717 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -38,7 +38,6 @@
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkProvider;
-import android.net.NetworkScore;
import android.os.INetworkManagementService;
import android.text.format.DateUtils;
@@ -353,10 +352,8 @@
NetworkCapabilities caps = new NetworkCapabilities();
caps.addCapability(0);
caps.addTransportType(transport);
- NetworkScore ns = new NetworkScore();
- ns.putIntExtension(NetworkScore.LEGACY_SCORE, 50);
NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
- caps, ns, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS,
+ caps, 50, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS,
NetworkProvider.ID_NONE);
nai.everValidated = true;
return nai;
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index a9e0b9a..36deca3 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -64,6 +64,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.annotation.NonNull;
import android.app.AlarmManager;
import android.app.usage.NetworkStatsManager;
import android.content.Context;
@@ -163,7 +164,6 @@
private @Mock IBinder mBinder;
private @Mock AlarmManager mAlarmManager;
private HandlerThread mHandlerThread;
- private Handler mHandler;
private NetworkStatsService mService;
private INetworkStatsSession mSession;
@@ -192,15 +192,11 @@
PowerManager.WakeLock wakeLock =
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
- mService = new NetworkStatsService(
- mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock,
- mServiceContext.getSystemService(TelephonyManager.class), mSettings,
- mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir));
mHandlerThread = new HandlerThread("HandlerThread");
- mHandlerThread.start();
- Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService);
- mHandler = new Handler(mHandlerThread.getLooper(), callback);
- mService.setHandler(mHandler, callback);
+ final NetworkStatsService.Dependencies deps = makeDependencies();
+ mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock,
+ mClock, mServiceContext.getSystemService(TelephonyManager.class), mSettings,
+ mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps);
mElapsedRealtime = 0L;
@@ -217,11 +213,21 @@
// catch INetworkManagementEventObserver during systemReady()
ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
- ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
+ ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
verify(mNetManager).registerObserver(networkObserver.capture());
mNetworkObserver = networkObserver.getValue();
}
+ @NonNull
+ private NetworkStatsService.Dependencies makeDependencies() {
+ return new NetworkStatsService.Dependencies() {
+ @Override
+ public HandlerThread makeHandlerThread() {
+ return mHandlerThread;
+ }
+ };
+ }
+
@After
public void tearDown() throws Exception {
IoUtils.deleteContents(mStatsDir);
@@ -234,6 +240,8 @@
mSession.close();
mService = null;
+
+ mHandlerThread.quitSafely();
}
@Test
@@ -939,9 +947,7 @@
long minThresholdInBytes = 2 * 1024 * 1024; // 2 MB
assertEquals(minThresholdInBytes, request.thresholdInBytes);
- // Send dummy message to make sure that any previous message has been handled
- mHandler.sendMessage(mHandler.obtainMessage(-1));
- HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT);
+ HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
// Make sure that the caller binder gets connected
verify(mBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
@@ -1077,7 +1083,7 @@
// Simulates alert quota of the provider has been reached.
cb.onAlertReached();
- HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT);
+ HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
// Verifies that polling is triggered by alert reached.
provider.expectStatsUpdate(0 /* unused */);
@@ -1294,9 +1300,7 @@
private void forcePollAndWaitForIdle() {
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
- // Send dummy message to make sure that any previous message has been handled
- mHandler.sendMessage(mHandler.obtainMessage(-1));
- HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT);
+ HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
}
static class LatchedHandler extends Handler {