summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 02:04:28 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 02:04:28 +0000
commit2ce8a3b5559e2a42fc7a1781a31e47907f5511c0 (patch)
tree6898c5db5b09380dc5609b4b5f10b60416224eb7
parent6e49820609b28b111f6489f15bf77c541999181f (diff)
parent98d8f7698e936d1a09ebcfa21d0f22b9cae5aa1e (diff)
downloadnet-android12-mainline-captiveportallogin-release.tar.gz
Snap for 7550930 from 98d8f7698e936d1a09ebcfa21d0f22b9cae5aa1e to mainline-captiveportallogin-releaseandroid-mainline-12.0.0_r6android-mainline-12.0.0_r23android12-mainline-captiveportallogin-release
Change-Id: I46531c2664219b22733544f994ee1cf0e6a2e711
-rw-r--r--client-libs/Android.bp2
-rw-r--r--client-libs/tests/unit/Android.bp3
-rw-r--r--client-libs/tests/unit/lint-baseline.xml26
-rw-r--r--common/Android.bp30
-rw-r--r--common/device/android/net/NetworkFactory.java359
-rw-r--r--common/device/android/net/NetworkFactoryImpl.java323
-rw-r--r--common/device/android/net/NetworkFactoryLegacyImpl.java398
-rw-r--r--common/device/android/net/NetworkFactoryShim.java71
-rw-r--r--common/device/com/android/net/module/util/structs/NsHeader.java8
-rw-r--r--common/framework/com/android/net/module/util/CollectionUtils.java1
-rw-r--r--common/framework/com/android/net/module/util/ConnectivitySettingsUtils.java127
-rw-r--r--common/framework/com/android/net/module/util/ConnectivityUtils.java1
-rw-r--r--common/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java13
-rw-r--r--common/framework/com/android/net/module/util/NetworkIdentityUtils.java1
-rw-r--r--common/framework/com/android/net/module/util/NetworkStackConstants.java3
-rw-r--r--common/jarjar-rules-shared.txt1
-rw-r--r--common/lint-baseline.xml26
-rw-r--r--common/native/bpf_syscall_wrappers/Android.bp1
-rw-r--r--common/tests/unit/Android.bp4
-rw-r--r--common/tests/unit/lint-baseline.xml594
-rw-r--r--common/tests/unit/src/com/android/net/module/util/StructTest.java1
-rw-r--r--common/testutils/Android.bp6
-rw-r--r--common/testutils/devicetests/com/android/testutils/TestHttpServer.kt10
-rw-r--r--common/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt7
-rw-r--r--common/testutils/devicetests/com/android/testutils/TestableNetworkOfferCallback.kt75
-rw-r--r--common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProvider.kt21
-rw-r--r--common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderCbBinder.kt9
27 files changed, 1166 insertions, 955 deletions
diff --git a/client-libs/Android.bp b/client-libs/Android.bp
index 9cedd29f..8c79d2a1 100644
--- a/client-libs/Android.bp
+++ b/client-libs/Android.bp
@@ -12,7 +12,7 @@ java_library {
"com.android.tethering"
],
visibility: [
- "//packages/modules/Connectivity/Tethering",
+ "//packages/modules/Connectivity:__subpackages__",
"//frameworks/base/services:__subpackages__",
"//frameworks/base/packages:__subpackages__",
"//frameworks/libs/net/client-libs/tests:__subpackages__",
diff --git a/client-libs/tests/unit/Android.bp b/client-libs/tests/unit/Android.bp
index 2cd39bdc..220a6c19 100644
--- a/client-libs/tests/unit/Android.bp
+++ b/client-libs/tests/unit/Android.bp
@@ -23,7 +23,8 @@ android_library {
// Visible for Tethering and NetworkStack integration test and link NetdStaticLibTestsLib
// there, so that the tests under client-libs can also be run when running tethering and
// NetworkStack MTS.
- "//packages/modules/Connectivity/Tethering/tests/integration",
+ "//packages/modules/Connectivity/tests:__subpackages__",
+ "//packages/modules/Connectivity/Tethering/tests:__subpackages__",
"//packages/modules/NetworkStack/tests/integration",
]
}
diff --git a/client-libs/tests/unit/lint-baseline.xml b/client-libs/tests/unit/lint-baseline.xml
deleted file mode 100644
index 713e3003..00000000
--- a/client-libs/tests/unit/lint-baseline.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" CollectionUtils.all(Arrays.asList(expectedFinalFlags),"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/client-libs/tests/unit/src/com/android/net/module/util/NetdUtilsTest.java"
- line="79"
- column="41"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" &amp;&amp; CollectionUtils.all(Arrays.asList(config.flags),"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/client-libs/tests/unit/src/com/android/net/module/util/NetdUtilsTest.java"
- line="81"
- column="44"/>
- </issue>
-
-</issues>
diff --git a/common/Android.bp b/common/Android.bp
index 74aafd30..1371c8cc 100644
--- a/common/Android.bp
+++ b/common/Android.bp
@@ -34,9 +34,9 @@ package {
java_library {
name: "net-utils-device-common",
srcs: [
- "device/**/*.java",
+ "device/com/android/net/module/util/**/*.java",
// This library is used by system modules, for which the system health impact of Kotlin
- // has not yet been evaluated.
+ // has not yet been evaluated. Annotations may need jarjar'ing.
// "src_devicecommon/**/*.kt",
":framework-annotations",
],
@@ -49,13 +49,12 @@ java_library {
],
visibility: [
"//frameworks/base/packages/Tethering",
- "//packages/modules/Connectivity/Tethering",
+ "//packages/modules/Connectivity:__subpackages__",
+ "//packages/modules/Connectivity/framework:__subpackages__",
"//frameworks/opt/net/ike",
"//frameworks/opt/net/wifi/service",
"//packages/modules/Wifi/service",
"//frameworks/opt/net/telephony",
- "//frameworks/base/packages/Connectivity:__subpackages__",
- "//packages/modules/Connectivity:__subpackages__",
"//packages/modules/NetworkStack:__subpackages__",
"//packages/modules/CaptivePortalLogin",
"//frameworks/libs/net/common/tests:__subpackages__",
@@ -84,7 +83,11 @@ filegroup {
name: "net-utils-framework-common-srcs",
srcs: ["framework/**/*.java"],
path: "framework",
- visibility: ["//frameworks/base"],
+ visibility: [
+ "//frameworks/base",
+ "//packages/modules/Connectivity:__subpackages__",
+ "//frameworks/base/packages/Connectivity/framework",
+ ],
}
java_library {
@@ -114,13 +117,15 @@ java_library {
"//frameworks/libs/net/common/tests:__subpackages__",
"//frameworks/libs/net/common/device",
"//packages/modules/Wifi/framework/tests:__subpackages__",
- ]
+ ],
}
-
filegroup {
name: "net-utils-services-common-srcs",
srcs: [
"device/android/net/NetworkFactory.java",
+ "device/android/net/NetworkFactoryImpl.java",
+ "device/android/net/NetworkFactoryLegacyImpl.java",
+ "device/android/net/NetworkFactoryShim.java",
],
visibility: [
"//frameworks/base/services/net",
@@ -135,6 +140,9 @@ java_library {
],
sdk_version: "system_current",
min_sdk_version: "30",
+ static_libs: [
+ "modules-utils-build_system",
+ ],
visibility: [
"//frameworks/base/services/net",
],
@@ -147,6 +155,9 @@ filegroup {
srcs: [
// Any class here *must* have a corresponding jarjar rule in the telephony build rules.
"device/android/net/NetworkFactory.java",
+ "device/android/net/NetworkFactoryImpl.java",
+ "device/android/net/NetworkFactoryLegacyImpl.java",
+ "device/android/net/NetworkFactoryShim.java",
],
path: "device",
visibility: [
@@ -175,6 +186,9 @@ filegroup {
name: "net-utils-wifi-service-common-srcs",
srcs: [
"device/android/net/NetworkFactory.java",
+ "device/android/net/NetworkFactoryImpl.java",
+ "device/android/net/NetworkFactoryLegacyImpl.java",
+ "device/android/net/NetworkFactoryShim.java",
"framework/com/android/net/module/util/NetUtils.java",
],
visibility: [
diff --git a/common/device/android/net/NetworkFactory.java b/common/device/android/net/NetworkFactory.java
index bcc60897..87f6dee6 100644
--- a/common/device/android/net/NetworkFactory.java
+++ b/common/device/android/net/NetworkFactory.java
@@ -16,9 +16,11 @@
package android.net;
+import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
+
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
-import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
@@ -27,8 +29,6 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.LinkedHashMap;
-import java.util.Map;
/**
* A NetworkFactory is an entity that creates NetworkAgent objects.
@@ -43,211 +43,72 @@ import java.util.Map;
* 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.
+ *
+ * This class is mostly a shim which delegates to one of two implementations depending
+ * on the SDK level of the device it's running on.
+ *
* @hide
**/
-public class NetworkFactory extends Handler {
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
- /**
- * 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 = 1;
-
- /**
- * Cancel a network request
- * msg.obj = NetworkRequest
- */
- public static final int CMD_CANCEL_REQUEST = 2;
-
- /**
- * Internally used to set our best-guess score.
- * msg.arg1 = new score
- */
- private static final int CMD_SET_SCORE = 3;
+public class NetworkFactory {
+ static final boolean DBG = true;
+ static final boolean VDBG = false;
- /**
- * 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 = 4;
+ final NetworkFactoryShim mImpl;
- private final Context mContext;
private final String LOG_TAG;
- private final Map<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
- new LinkedHashMap<>();
-
- private int mScore;
- private NetworkCapabilities mCapabilityFilter;
-
- private int mRefCount = 0;
- private NetworkProvider mProvider = null;
-
+ // Ideally the filter argument would be non-null, but null has historically meant to see
+ // no requests and telephony passes null.
public NetworkFactory(Looper looper, Context context, String logTag,
- NetworkCapabilities filter) {
- super(looper);
+ @Nullable final NetworkCapabilities filter) {
LOG_TAG = logTag;
- mContext = context;
- mCapabilityFilter = filter;
- }
-
- /* Registers this NetworkFactory with the system. May only be called once per factory. */
- public void register() {
- if (mProvider != null) {
- throw new IllegalStateException("A NetworkFactory must only be registered once");
+ if (isAtLeastS()) {
+ mImpl = new NetworkFactoryImpl(this, looper, context, filter);
+ } else {
+ mImpl = new NetworkFactoryLegacyImpl(this, looper, context, filter);
}
- 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(request, score, servingProviderId);
- }
-
- @Override
- public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
- handleRemoveRequest(request);
- }
- };
-
- ((ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);
}
- /** Unregisters this NetworkFactory. After this call, the object can no longer be used. */
- public void terminate() {
- if (mProvider == null) {
- throw new IllegalStateException("This NetworkFactory was never registered");
- }
- if (DBG) log("Unregistering NetworkFactory");
-
- ((ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
- .unregisterNetworkProvider(mProvider);
-
- // Remove all pending messages, since this object cannot be reused. Any message currently
- // being processed will continue to run.
- removeCallbacksAndMessages(null);
+ // TODO : these two constants and the method are only used by telephony tests. Replace it in
+ // the tests and remove them and the associated code.
+ public static final int CMD_REQUEST_NETWORK = 1;
+ public static final int CMD_CANCEL_REQUEST = 2;
+ /** Like Handler#obtainMessage */
+ @VisibleForTesting
+ public Message obtainMessage(final int what, final int arg1, final int arg2,
+ final @Nullable Object obj) {
+ return mImpl.obtainMessage(what, arg1, arg2, obj);
}
- @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;
- }
- }
+ // Called by BluetoothNetworkFactory
+ public final Looper getLooper() {
+ return mImpl.getLooper();
}
- private static 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;
- }
+ // Refcount for simple mode requests
+ private int mRefCount = 0;
- @Override
- public String toString() {
- return "{" + request + ", score=" + score + ", requested=" + requested + "}";
- }
+ /* Registers this NetworkFactory with the system. May only be called once per factory. */
+ public void register() {
+ mImpl.register(LOG_TAG);
}
/**
- * 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.
+ * Registers this NetworkFactory with the system ignoring the score filter. This will let
+ * the factory always see all network requests matching its capabilities filter.
+ * May only be called once per factory.
*/
- @VisibleForTesting
- protected void handleAddRequest(NetworkRequest request, int score, int servingProviderId) {
- NetworkRequestInfo n = mNetworkRequests.get(request);
- 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, n);
- } else {
- if (VDBG) {
- log("new score " + score + " for existing 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);
- if (n != null) {
- mNetworkRequests.remove(request);
- if (n.requested) releaseNetworkFor(n.request);
- }
- }
-
- private void handleSetScore(int score) {
- mScore = score;
- evalRequests();
+ public void registerIgnoringScore() {
+ mImpl.registerIgnoringScore(LOG_TAG);
}
- private void handleSetFilter(NetworkCapabilities netCap) {
- mCapabilityFilter = netCap;
- evalRequests();
+ /** Unregisters this NetworkFactory. After this call, the object can no longer be used. */
+ public void terminate() {
+ mImpl.terminate();
}
- /** @deprecated None of the implementors use the score, remove this method */
- @Deprecated
- public boolean acceptRequest(NetworkRequest request, int score) {
- return acceptRequest(request);
+ protected final void reevaluateAllRequests() {
+ mImpl.reevaluateAllRequests();
}
/**
@@ -269,75 +130,10 @@ public class NetworkFactory extends Handler {
*
* @return {@code true} to accept the request.
*/
- public boolean acceptRequest(NetworkRequest request) {
+ public boolean acceptRequest(@NonNull final NetworkRequest request) {
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(" request.providerId = " + n.providerId);
- log(" mProvider.id = " + mProvider.getProviderId());
- }
- 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 == mProvider.getProviderId())
- // If this factory can't satisfy the capability needs of this request, then it
- // should not be tracked.
- && n.request.canBeSatisfiedBy(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 != mProvider.getProviderId())
- || !n.request.canBeSatisfiedBy(mCapabilityFilter)
- || !acceptRequest(n.request, n.score));
- }
-
- private void evalRequests() {
- for (NetworkRequestInfo n : mNetworkRequests.values()) {
- evalRequest(n);
- }
- }
-
- /**
- * Post a command, on this NetworkFactory Handler, to re-evaluate all
- * outstanding requests. Can be called from a factory implementation.
- */
- protected void reevaluateAllRequests() {
- post(this::evalRequests);
- }
-
/**
* Can be called by a factory to release a request as unfulfillable: the request will be
* removed, and the caller will get a
@@ -348,56 +144,60 @@ public class NetworkFactory extends Handler {
* is able to fulfill this request!
*/
protected void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) {
- post(() -> {
- if (DBG) log("releaseRequestAsUnfulfillableByAnyFactory: " + r);
- final NetworkProvider provider = mProvider;
- if (provider == null) {
- Log.e(LOG_TAG, "Ignoring attempt to release unregistered request as unfulfillable");
- return;
- }
- provider.declareNetworkRequestUnfulfillable(r);
- });
+ mImpl.releaseRequestAsUnfulfillableByAnyFactory(r);
}
// override to do simple mode (request independent)
protected void startNetwork() { }
protected void stopNetwork() { }
- /** @deprecated none of the implementors use the score : migrate them */
- @Deprecated
- protected void needNetworkFor(NetworkRequest networkRequest, int score) {
- needNetworkFor(networkRequest);
- }
-
// override to do fancier stuff
- protected void needNetworkFor(NetworkRequest networkRequest) {
+ protected void needNetworkFor(@NonNull final NetworkRequest networkRequest) {
if (++mRefCount == 1) startNetwork();
}
- protected void releaseNetworkFor(NetworkRequest networkRequest) {
+ protected void releaseNetworkFor(@NonNull final NetworkRequest networkRequest) {
if (--mRefCount == 0) stopNetwork();
}
- public void setScoreFilter(int score) {
- sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
+ /**
+ * @deprecated this method was never part of the API (system or public) and is only added
+ * for migration of existing clients.
+ */
+ @Deprecated
+ public void setScoreFilter(final int score) {
+ mImpl.setScoreFilter(score);
+ }
+
+ /**
+ * Set a score filter for this factory.
+ *
+ * This should include the transports the factory knows its networks will have, and
+ * an optimistic view of the attributes it may have. This does not commit the factory
+ * to being able to bring up such a network ; it only lets it avoid hearing about
+ * requests that it has no chance of fulfilling.
+ *
+ * @param score the filter
+ */
+ public void setScoreFilter(@NonNull final NetworkScore score) {
+ mImpl.setScoreFilter(score);
}
public void setCapabilityFilter(NetworkCapabilities netCap) {
- sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
+ mImpl.setCapabilityFilter(netCap);
}
@VisibleForTesting
protected int getRequestCount() {
- return mNetworkRequests.size();
+ return mImpl.getRequestCount();
}
- /* TODO: delete when all callers have migrated to NetworkProvider IDs. */
public int getSerialNumber() {
- return mProvider.getProviderId();
+ return mImpl.getSerialNumber();
}
public NetworkProvider getProvider() {
- return mProvider;
+ return mImpl.getProvider();
}
protected void log(String s) {
@@ -405,18 +205,11 @@ public class NetworkFactory extends Handler {
}
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- writer.println(toString());
- for (NetworkRequestInfo n : mNetworkRequests.values()) {
- writer.println(" " + n);
- }
+ mImpl.dump(fd, writer, args);
}
@Override
public String toString() {
- return "{" + LOG_TAG + " - providerId="
- + mProvider.getProviderId() + ", ScoreFilter="
- + mScore + ", Filter=" + mCapabilityFilter + ", requests="
- + mNetworkRequests.size() + ", refCount=" + mRefCount
- + "}";
+ return "{" + LOG_TAG + " " + mImpl.toString() + "}";
}
}
diff --git a/common/device/android/net/NetworkFactoryImpl.java b/common/device/android/net/NetworkFactoryImpl.java
new file mode 100644
index 00000000..439ea142
--- /dev/null
+++ b/common/device/android/net/NetworkFactoryImpl.java
@@ -0,0 +1,323 @@
+/*
+ * 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.annotation.Nullable;
+import android.content.Context;
+import android.net.NetworkProvider.NetworkOfferCallback;
+import android.os.Looper;
+import android.os.Message;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * 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
+ **/
+// TODO(b/187083878): factor out common code between this and NetworkFactoryLegacyImpl
+class NetworkFactoryImpl extends NetworkFactoryLegacyImpl {
+ private static final boolean DBG = NetworkFactory.DBG;
+ private static final boolean VDBG = NetworkFactory.VDBG;
+
+ // A score that will win against everything, so that score filtering will let all requests
+ // through
+ // TODO : remove this and replace with an API to listen to all requests.
+ @NonNull
+ private static final NetworkScore INVINCIBLE_SCORE =
+ new NetworkScore.Builder().setLegacyInt(1000).build();
+
+ // TODO(b/187082970): Replace CMD_* with Handler.post(() -> { ... }) since all the CMDs do is to
+ // run the tasks asynchronously on the Handler thread.
+
+ /**
+ * 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
+ */
+ // TODO : this and CANCEL_REQUEST are only used by telephony tests. Replace it in the tests
+ // and remove them and the associated code.
+ private static final int CMD_REQUEST_NETWORK = NetworkFactory.CMD_REQUEST_NETWORK;
+
+ /**
+ * Cancel a network request
+ * msg.obj = NetworkRequest
+ */
+ private static final int CMD_CANCEL_REQUEST = NetworkFactory.CMD_CANCEL_REQUEST;
+
+ /**
+ * Internally used to set our best-guess score.
+ * msg.obj = new score
+ */
+ private static final int CMD_SET_SCORE = 3;
+
+ /**
+ * 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 = 4;
+
+ /**
+ * Internally used to send the network offer associated with this factory.
+ * No arguments, will read from members
+ */
+ private static final int CMD_OFFER_NETWORK = 5;
+
+ /**
+ * Internally used to send the request to listen to all requests.
+ * No arguments, will read from members
+ */
+ private static final int CMD_LISTEN_TO_ALL_REQUESTS = 6;
+
+ private final Map<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
+ new LinkedHashMap<>();
+
+ @NonNull private NetworkScore mScore = new NetworkScore.Builder().setLegacyInt(0).build();
+
+ private final NetworkOfferCallback mRequestCallback = new NetworkOfferCallback() {
+ @Override
+ public void onNetworkNeeded(@NonNull final NetworkRequest request) {
+ handleAddRequest(request);
+ }
+
+ @Override
+ public void onNetworkUnneeded(@NonNull final NetworkRequest request) {
+ handleRemoveRequest(request);
+ }
+ };
+ @NonNull private final Executor mExecutor = command -> post(command);
+
+
+ // Ideally the filter argument would be non-null, but null has historically meant to see
+ // no requests and telephony passes null.
+ NetworkFactoryImpl(NetworkFactory parent, Looper looper, Context context,
+ @Nullable final NetworkCapabilities filter) {
+ super(parent, looper, context,
+ null != filter ? filter :
+ NetworkCapabilities.Builder.withoutDefaultCapabilities().build());
+ }
+
+ /* Registers this NetworkFactory with the system. May only be called once per factory. */
+ @Override public void register(final String logTag) {
+ register(logTag, false);
+ }
+
+ /**
+ * Registers this NetworkFactory with the system ignoring the score filter. This will let
+ * the factory always see all network requests matching its capabilities filter.
+ * May only be called once per factory.
+ */
+ @Override public void registerIgnoringScore(final String logTag) {
+ register(logTag, true);
+ }
+
+ private void register(final String logTag, final boolean listenToAllRequests) {
+ if (mProvider != null) {
+ throw new IllegalStateException("A NetworkFactory must only be registered once");
+ }
+ if (DBG) mParent.log("Registering NetworkFactory");
+
+ mProvider = new NetworkProvider(mContext, NetworkFactoryImpl.this.getLooper(), logTag) {
+ @Override
+ public void onNetworkRequested(@NonNull NetworkRequest request, int score,
+ int servingProviderId) {
+ handleAddRequest(request);
+ }
+
+ @Override
+ public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
+ handleRemoveRequest(request);
+ }
+ };
+
+ ((ConnectivityManager) mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);
+
+ // The mScore and mCapabilityFilter members can only be accessed on the handler thread.
+ // TODO : offer a separate API to listen to all requests instead
+ if (listenToAllRequests) {
+ sendMessage(obtainMessage(CMD_LISTEN_TO_ALL_REQUESTS));
+ } else {
+ sendMessage(obtainMessage(CMD_OFFER_NETWORK));
+ }
+ }
+
+ private void handleOfferNetwork(@NonNull final NetworkScore score) {
+ mProvider.registerNetworkOffer(score, mCapabilityFilter, mExecutor, mRequestCallback);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case CMD_REQUEST_NETWORK: {
+ handleAddRequest((NetworkRequest) msg.obj);
+ break;
+ }
+ case CMD_CANCEL_REQUEST: {
+ handleRemoveRequest((NetworkRequest) msg.obj);
+ break;
+ }
+ case CMD_SET_SCORE: {
+ handleSetScore((NetworkScore) msg.obj);
+ break;
+ }
+ case CMD_SET_FILTER: {
+ handleSetFilter((NetworkCapabilities) msg.obj);
+ break;
+ }
+ case CMD_OFFER_NETWORK: {
+ handleOfferNetwork(mScore);
+ break;
+ }
+ case CMD_LISTEN_TO_ALL_REQUESTS: {
+ handleOfferNetwork(INVINCIBLE_SCORE);
+ break;
+ }
+ }
+ }
+
+ private static class NetworkRequestInfo {
+ @NonNull public final NetworkRequest request;
+ public boolean requested; // do we have a request outstanding, limited by score
+
+ NetworkRequestInfo(@NonNull final NetworkRequest request) {
+ this.request = request;
+ this.requested = false;
+ }
+
+ @Override
+ public String toString() {
+ return "{" + request + ", requested=" + requested + "}";
+ }
+ }
+
+ /**
+ * Add a NetworkRequest that the bearer may want to attempt to satisfy.
+ * @see #CMD_REQUEST_NETWORK
+ *
+ * @param request the request to handle.
+ */
+ private void handleAddRequest(@NonNull final NetworkRequest request) {
+ NetworkRequestInfo n = mNetworkRequests.get(request);
+ if (n == null) {
+ if (DBG) mParent.log("got request " + request);
+ n = new NetworkRequestInfo(request);
+ mNetworkRequests.put(n.request, n);
+ } else {
+ if (VDBG) mParent.log("handle existing request " + request);
+ }
+ if (VDBG) mParent.log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
+
+ if (mParent.acceptRequest(request)) {
+ n.requested = true;
+ mParent.needNetworkFor(request);
+ }
+ }
+
+ private void handleRemoveRequest(NetworkRequest request) {
+ NetworkRequestInfo n = mNetworkRequests.get(request);
+ if (n != null) {
+ mNetworkRequests.remove(request);
+ if (n.requested) mParent.releaseNetworkFor(n.request);
+ }
+ }
+
+ private void handleSetScore(@NonNull final NetworkScore score) {
+ if (mScore.equals(score)) return;
+ mScore = score;
+ mParent.reevaluateAllRequests();
+ }
+
+ private void handleSetFilter(@NonNull final NetworkCapabilities netCap) {
+ if (netCap.equals(mCapabilityFilter)) return;
+ mCapabilityFilter = netCap;
+ mParent.reevaluateAllRequests();
+ }
+
+ @Override public final void reevaluateAllRequests() {
+ if (mProvider == null) return;
+ mProvider.registerNetworkOffer(mScore, mCapabilityFilter, mExecutor, mRequestCallback);
+ }
+
+ /**
+ * @deprecated this method was never part of the API (system or public) and is only added
+ * for migration of existing clients.
+ */
+ @Deprecated
+ public void setScoreFilter(final int score) {
+ setScoreFilter(new NetworkScore.Builder().setLegacyInt(score).build());
+ }
+
+ /**
+ * Set a score filter for this factory.
+ *
+ * This should include the transports the factory knows its networks will have, and
+ * an optimistic view of the attributes it may have. This does not commit the factory
+ * to being able to bring up such a network ; it only lets it avoid hearing about
+ * requests that it has no chance of fulfilling.
+ *
+ * @param score the filter
+ */
+ @Override public void setScoreFilter(@NonNull final NetworkScore score) {
+ sendMessage(obtainMessage(CMD_SET_SCORE, score));
+ }
+
+ @Override public void setCapabilityFilter(NetworkCapabilities netCap) {
+ sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
+ }
+
+ @Override public int getRequestCount() {
+ return mNetworkRequests.size();
+ }
+
+ @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ writer.println(toString());
+ for (NetworkRequestInfo n : mNetworkRequests.values()) {
+ writer.println(" " + n);
+ }
+ }
+
+ @Override public String toString() {
+ return "providerId="
+ + mProvider.getProviderId() + ", ScoreFilter="
+ + mScore + ", Filter=" + mCapabilityFilter + ", requests="
+ + mNetworkRequests.size();
+ }
+}
diff --git a/common/device/android/net/NetworkFactoryLegacyImpl.java b/common/device/android/net/NetworkFactoryLegacyImpl.java
new file mode 100644
index 00000000..6dd0adb0
--- /dev/null
+++ b/common/device/android/net/NetworkFactoryLegacyImpl.java
@@ -0,0 +1,398 @@
+/*
+ * 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.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 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
+ **/
+// TODO(b/187083878): factor out common code between this and NetworkFactoryImpl
+class NetworkFactoryLegacyImpl extends Handler
+ implements NetworkFactoryShim {
+ private static final boolean DBG = NetworkFactory.DBG;
+ private static final boolean VDBG = NetworkFactory.VDBG;
+
+ // TODO(b/187082970): Replace CMD_* with Handler.post(() -> { ... }) since all the CMDs do is to
+ // run the tasks asynchronously on the Handler thread.
+
+ /**
+ * 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 = 1;
+
+ /**
+ * Cancel a network request
+ * msg.obj = NetworkRequest
+ */
+ public static final int CMD_CANCEL_REQUEST = 2;
+
+ /**
+ * Internally used to set our best-guess score.
+ * msg.arg1 = new score
+ */
+ private static final int CMD_SET_SCORE = 3;
+
+ /**
+ * 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 = 4;
+
+ final Context mContext;
+ final NetworkFactory mParent;
+
+ private final Map<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
+ new LinkedHashMap<>();
+
+ private int mScore;
+ NetworkCapabilities mCapabilityFilter;
+
+ NetworkProvider mProvider = null;
+
+ NetworkFactoryLegacyImpl(NetworkFactory parent, Looper looper, Context context,
+ NetworkCapabilities filter) {
+ super(looper);
+ mParent = parent;
+ mContext = context;
+ mCapabilityFilter = filter;
+ }
+
+ /* Registers this NetworkFactory with the system. May only be called once per factory. */
+ @Override public void register(final String logTag) {
+ if (mProvider != null) {
+ throw new IllegalStateException("A NetworkFactory must only be registered once");
+ }
+ if (DBG) mParent.log("Registering NetworkFactory");
+
+ mProvider = new NetworkProvider(mContext, NetworkFactoryLegacyImpl.this.getLooper(),
+ logTag) {
+ @Override
+ public void onNetworkRequested(@NonNull NetworkRequest request, int score,
+ int servingProviderId) {
+ handleAddRequest(request, score, servingProviderId);
+ }
+
+ @Override
+ public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
+ handleRemoveRequest(request);
+ }
+ };
+
+ ((ConnectivityManager) mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE)).registerNetworkProvider(mProvider);
+ }
+
+ /** Unregisters this NetworkFactory. After this call, the object can no longer be used. */
+ @Override public void terminate() {
+ if (mProvider == null) {
+ throw new IllegalStateException("This NetworkFactory was never registered");
+ }
+ if (DBG) mParent.log("Unregistering NetworkFactory");
+
+ ((ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
+ .unregisterNetworkProvider(mProvider);
+
+ // Remove all pending messages, since this object cannot be reused. Any message currently
+ // being processed will continue to run.
+ removeCallbacksAndMessages(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 static 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.
+ * @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);
+ if (n == null) {
+ if (DBG) {
+ mParent.log("got request " + request + " with score " + score
+ + " and providerId " + servingProviderId);
+ }
+ n = new NetworkRequestInfo(request, score, servingProviderId);
+ mNetworkRequests.put(n.request, n);
+ } else {
+ if (VDBG) {
+ mParent.log("new score " + score + " for existing request " + request
+ + " and providerId " + servingProviderId);
+ }
+ n.score = score;
+ n.providerId = servingProviderId;
+ }
+ if (VDBG) mParent.log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
+
+ evalRequest(n);
+ }
+
+ private void handleRemoveRequest(NetworkRequest request) {
+ NetworkRequestInfo n = mNetworkRequests.get(request);
+ if (n != null) {
+ mNetworkRequests.remove(request);
+ if (n.requested) mParent.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 NetworkFactory#needNetworkFor} and
+ * {@link NetworkFactory#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 NetworkFactory#startNetwork} and {@link NetworkFactory#stopNetwork}.
+ *
+ * If you want to see every score fluctuation on every request, set
+ * your score filter to a very high number and watch {@link NetworkFactory#needNetworkFor}.
+ *
+ * @return {@code true} to accept the request.
+ */
+ public boolean acceptRequest(NetworkRequest request) {
+ return mParent.acceptRequest(request);
+ }
+
+ private void evalRequest(NetworkRequestInfo n) {
+ if (VDBG) {
+ mParent.log("evalRequest");
+ mParent.log(" n.requests = " + n.requested);
+ mParent.log(" n.score = " + n.score);
+ mParent.log(" mScore = " + mScore);
+ mParent.log(" request.providerId = " + n.providerId);
+ mParent.log(" mProvider.id = " + mProvider.getProviderId());
+ }
+ if (shouldNeedNetworkFor(n)) {
+ if (VDBG) mParent.log(" needNetworkFor");
+ mParent.needNetworkFor(n.request);
+ n.requested = true;
+ } else if (shouldReleaseNetworkFor(n)) {
+ if (VDBG) mParent.log(" releaseNetworkFor");
+ mParent.releaseNetworkFor(n.request);
+ n.requested = false;
+ } else {
+ if (VDBG) mParent.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 == mProvider.getProviderId())
+ // If this factory can't satisfy the capability needs of this request, then it
+ // should not be tracked.
+ && n.request.canBeSatisfiedBy(mCapabilityFilter)
+ // Finally if the concrete implementation of the factory rejects the request, then
+ // don't track it.
+ && acceptRequest(n.request);
+ }
+
+ 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 != mProvider.getProviderId())
+ || !n.request.canBeSatisfiedBy(mCapabilityFilter)
+ || !acceptRequest(n.request));
+ }
+
+ private void evalRequests() {
+ for (NetworkRequestInfo n : mNetworkRequests.values()) {
+ evalRequest(n);
+ }
+ }
+
+ /**
+ * Post a command, on this NetworkFactory Handler, to re-evaluate all
+ * outstanding requests. Can be called from a factory implementation.
+ */
+ @Override public void reevaluateAllRequests() {
+ post(this::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!
+ */
+ @Override public void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r) {
+ post(() -> {
+ if (DBG) mParent.log("releaseRequestAsUnfulfillableByAnyFactory: " + r);
+ final NetworkProvider provider = mProvider;
+ if (provider == null) {
+ mParent.log("Ignoring attempt to release unregistered request as unfulfillable");
+ return;
+ }
+ provider.declareNetworkRequestUnfulfillable(r);
+ });
+ }
+
+ @Override public void setScoreFilter(int score) {
+ sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
+ }
+
+ @Override public void setScoreFilter(@NonNull final NetworkScore score) {
+ setScoreFilter(score.getLegacyInt());
+ }
+
+ @Override public void setCapabilityFilter(NetworkCapabilities netCap) {
+ sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
+ }
+
+ @Override public int getRequestCount() {
+ return mNetworkRequests.size();
+ }
+
+ /* TODO: delete when all callers have migrated to NetworkProvider IDs. */
+ @Override public int getSerialNumber() {
+ return mProvider.getProviderId();
+ }
+
+ @Override public NetworkProvider getProvider() {
+ return mProvider;
+ }
+
+ @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ writer.println(toString());
+ for (NetworkRequestInfo n : mNetworkRequests.values()) {
+ writer.println(" " + n);
+ }
+ }
+
+ @Override public String toString() {
+ return "providerId="
+ + mProvider.getProviderId() + ", ScoreFilter="
+ + mScore + ", Filter=" + mCapabilityFilter + ", requests="
+ + mNetworkRequests.size();
+ }
+}
diff --git a/common/device/android/net/NetworkFactoryShim.java b/common/device/android/net/NetworkFactoryShim.java
new file mode 100644
index 00000000..dfbb5ec1
--- /dev/null
+++ b/common/device/android/net/NetworkFactoryShim.java
@@ -0,0 +1,71 @@
+/*
+ * 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.annotation.Nullable;
+import android.os.Looper;
+import android.os.Message;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Extract an interface for multiple implementation of {@link NetworkFactory}, depending on the SDK
+ * version.
+ *
+ * Known implementations:
+ * - {@link NetworkFactoryImpl}: For Android S+
+ * - {@link NetworkFactoryLegacyImpl}: For Android R-
+ *
+ * @hide
+ */
+interface NetworkFactoryShim {
+ void register(String logTag);
+
+ default void registerIgnoringScore(String logTag) {
+ throw new UnsupportedOperationException();
+ }
+
+ void terminate();
+
+ void releaseRequestAsUnfulfillableByAnyFactory(NetworkRequest r);
+
+ void reevaluateAllRequests();
+
+ void setScoreFilter(int score);
+
+ void setScoreFilter(@NonNull NetworkScore score);
+
+ void setCapabilityFilter(NetworkCapabilities netCap);
+
+ int getRequestCount();
+
+ int getSerialNumber();
+
+ NetworkProvider getProvider();
+
+ void dump(FileDescriptor fd, PrintWriter writer, String[] args);
+
+ // All impls inherit Handler
+ @VisibleForTesting
+ Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj);
+
+ Looper getLooper();
+}
diff --git a/common/device/com/android/net/module/util/structs/NsHeader.java b/common/device/com/android/net/module/util/structs/NsHeader.java
index 6e0aa508..2e8b77ba 100644
--- a/common/device/com/android/net/module/util/structs/NsHeader.java
+++ b/common/device/com/android/net/module/util/structs/NsHeader.java
@@ -50,8 +50,12 @@ public class NsHeader extends Struct {
@Field(order = 1, type = Type.Ipv6Address)
public Inet6Address target;
- public NsHeader(final Inet6Address target) {
- this.reserved = 0;
+ NsHeader(int reserved, final Inet6Address target) {
+ this.reserved = reserved;
this.target = target;
}
+
+ public NsHeader(final Inet6Address target) {
+ this(0, target);
+ }
}
diff --git a/common/framework/com/android/net/module/util/CollectionUtils.java b/common/framework/com/android/net/module/util/CollectionUtils.java
index 4fce8f50..0696cca8 100644
--- a/common/framework/com/android/net/module/util/CollectionUtils.java
+++ b/common/framework/com/android/net/module/util/CollectionUtils.java
@@ -27,6 +27,7 @@ import java.util.function.Predicate;
/**
* Utilities for {@link Collection} and arrays.
+ * @hide
*/
public final class CollectionUtils {
private CollectionUtils() {}
diff --git a/common/framework/com/android/net/module/util/ConnectivitySettingsUtils.java b/common/framework/com/android/net/module/util/ConnectivitySettingsUtils.java
new file mode 100644
index 00000000..b7eb70b0
--- /dev/null
+++ b/common/framework/com/android/net/module/util/ConnectivitySettingsUtils.java
@@ -0,0 +1,127 @@
+/*
+ * 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 com.android.net.module.util;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+/**
+ * Collection of connectivity settings utilities.
+ *
+ * @hide
+ */
+public class ConnectivitySettingsUtils {
+ public static final int PRIVATE_DNS_MODE_OFF = 1;
+ public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2;
+ public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;
+
+ public static final String PRIVATE_DNS_DEFAULT_MODE = "private_dns_default_mode";
+ public static final String PRIVATE_DNS_MODE = "private_dns_mode";
+ public static final String PRIVATE_DNS_MODE_OFF_STRING = "off";
+ public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING = "opportunistic";
+ public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname";
+ public static final String PRIVATE_DNS_SPECIFIER = "private_dns_specifier";
+
+ /**
+ * Get private DNS mode as string.
+ *
+ * @param mode One of the private DNS values.
+ * @return A string of private DNS mode.
+ */
+ public static String getPrivateDnsModeAsString(int mode) {
+ switch (mode) {
+ case PRIVATE_DNS_MODE_OFF:
+ return PRIVATE_DNS_MODE_OFF_STRING;
+ case PRIVATE_DNS_MODE_OPPORTUNISTIC:
+ return PRIVATE_DNS_MODE_OPPORTUNISTIC_STRING;
+ case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
+ return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING;
+ default:
+ throw new IllegalArgumentException("Invalid private dns mode: " + mode);
+ }
+ }
+
+ private static int getPrivateDnsModeAsInt(String mode) {
+ switch (mode) {
+ case "off":
+ return PRIVATE_DNS_MODE_OFF;
+ case "hostname":
+ return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+ case "opportunistic":
+ return PRIVATE_DNS_MODE_OPPORTUNISTIC;
+ default:
+ throw new IllegalArgumentException("Invalid private dns mode: " + mode);
+ }
+ }
+
+ /**
+ * Get private DNS mode from settings.
+ *
+ * @param context The Context to query the private DNS mode from settings.
+ * @return An integer of private DNS mode.
+ */
+ public static int getPrivateDnsMode(@NonNull Context context) {
+ final ContentResolver cr = context.getContentResolver();
+ String mode = Settings.Global.getString(cr, PRIVATE_DNS_MODE);
+ if (TextUtils.isEmpty(mode)) mode = Settings.Global.getString(cr, PRIVATE_DNS_DEFAULT_MODE);
+ // If both PRIVATE_DNS_MODE and PRIVATE_DNS_DEFAULT_MODE are not set, choose
+ // PRIVATE_DNS_MODE_OPPORTUNISTIC as default mode.
+ if (TextUtils.isEmpty(mode)) return PRIVATE_DNS_MODE_OPPORTUNISTIC;
+ return getPrivateDnsModeAsInt(mode);
+ }
+
+ /**
+ * Set private DNS mode to settings.
+ *
+ * @param context The {@link Context} to set the private DNS mode.
+ * @param mode The private dns mode. This should be one of the PRIVATE_DNS_MODE_* constants.
+ */
+ public static void setPrivateDnsMode(@NonNull Context context, int mode) {
+ if (!(mode == PRIVATE_DNS_MODE_OFF
+ || mode == PRIVATE_DNS_MODE_OPPORTUNISTIC
+ || mode == PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
+ throw new IllegalArgumentException("Invalid private dns mode: " + mode);
+ }
+ Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_MODE,
+ getPrivateDnsModeAsString(mode));
+ }
+
+ /**
+ * Get specific private dns provider name from {@link Settings}.
+ *
+ * @param context The {@link Context} to query the setting.
+ * @return The specific private dns provider name, or null if no setting value.
+ */
+ @Nullable
+ public static String getPrivateDnsHostname(@NonNull Context context) {
+ return Settings.Global.getString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER);
+ }
+
+ /**
+ * Set specific private dns provider name to {@link Settings}.
+ *
+ * @param context The {@link Context} to set the setting.
+ * @param specifier The specific private dns provider name.
+ */
+ public static void setPrivateDnsHostname(@NonNull Context context, @Nullable String specifier) {
+ Settings.Global.putString(context.getContentResolver(), PRIVATE_DNS_SPECIFIER, specifier);
+ }
+}
diff --git a/common/framework/com/android/net/module/util/ConnectivityUtils.java b/common/framework/com/android/net/module/util/ConnectivityUtils.java
index 382912bf..c135e466 100644
--- a/common/framework/com/android/net/module/util/ConnectivityUtils.java
+++ b/common/framework/com/android/net/module/util/ConnectivityUtils.java
@@ -24,6 +24,7 @@ import java.net.InetAddress;
/**
* Various utilities used in connectivity code.
+ * @hide
*/
public final class ConnectivityUtils {
private ConnectivityUtils() {}
diff --git a/common/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java b/common/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
index 4c7d675e..d4b1c9e0 100644
--- a/common/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
+++ b/common/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
@@ -44,8 +44,15 @@ import com.android.internal.annotations.VisibleForTesting;
/**
* Utilities to examine {@link android.net.NetworkCapabilities}.
+ * @hide
*/
public final class NetworkCapabilitiesUtils {
+ /**
+ * See android.net.NetworkCapabilities.TRANSPORT_USB
+ * TODO: Use API constant when all downstream branches are S-based
+ */
+ public static final int TRANSPORT_USB = 8;
+
// Transports considered to classify networks in UI, in order of which transport should be
// surfaced when there are multiple transports. Transports not in this list do not have
// an ordering preference (in practice they will have a deterministic order based on the
@@ -63,7 +70,8 @@ public final class NetworkCapabilitiesUtils {
TRANSPORT_WIFI_AWARE,
TRANSPORT_BLUETOOTH,
TRANSPORT_WIFI,
- TRANSPORT_ETHERNET
+ TRANSPORT_ETHERNET,
+ TRANSPORT_USB
// Notably, TRANSPORT_TEST is not in this list as any network that has TRANSPORT_TEST and
// one of the above transports should be counted as that transport, to keep tests as
@@ -133,7 +141,8 @@ public final class NetworkCapabilitiesUtils {
* See {@code NetworkCapabilities#maybeMarkCapabilitiesRestricted}.
*/
private static final long FORCE_RESTRICTED_CAPABILITIES =
- (1 << NET_CAPABILITY_OEM_PAID)
+ (1 << NET_CAPABILITY_ENTERPRISE)
+ | (1 << NET_CAPABILITY_OEM_PAID)
| (1 << NET_CAPABILITY_OEM_PRIVATE);
/**
diff --git a/common/framework/com/android/net/module/util/NetworkIdentityUtils.java b/common/framework/com/android/net/module/util/NetworkIdentityUtils.java
index 94e60178..b641753c 100644
--- a/common/framework/com/android/net/module/util/NetworkIdentityUtils.java
+++ b/common/framework/com/android/net/module/util/NetworkIdentityUtils.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
/**
* Utilities to examine {@link android.net.NetworkIdentity}.
+ * @hide
*/
public class NetworkIdentityUtils {
/**
diff --git a/common/framework/com/android/net/module/util/NetworkStackConstants.java b/common/framework/com/android/net/module/util/NetworkStackConstants.java
index b7062e76..f7151d7b 100644
--- a/common/framework/com/android/net/module/util/NetworkStackConstants.java
+++ b/common/framework/com/android/net/module/util/NetworkStackConstants.java
@@ -148,7 +148,10 @@ public final class NetworkStackConstants {
public static final int ICMPV6_ND_OPTION_RDNSS = 25;
public static final int ICMPV6_ND_OPTION_PREF64 = 38;
+ public static final int ICMPV6_RS_HEADER_LEN = 8;
public static final int ICMPV6_RA_HEADER_LEN = 16;
+ public static final int ICMPV6_NS_HEADER_LEN = 24;
+ public static final int ICMPV6_NA_HEADER_LEN = 24;
public static final int NEIGHBOR_ADVERTISEMENT_FLAG_ROUTER = 1 << 31;
public static final int NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED = 1 << 30;
diff --git a/common/jarjar-rules-shared.txt b/common/jarjar-rules-shared.txt
index a7fda7c0..e26999dd 100644
--- a/common/jarjar-rules-shared.txt
+++ b/common/jarjar-rules-shared.txt
@@ -1,2 +1,3 @@
rule android.annotation.** com.android.net.module.annotation.@1
rule com.android.internal.annotations.** com.android.net.module.annotation.@1
+rule com.android.modules.utils.build.** com.android.net.module.util.build.$1
diff --git a/common/lint-baseline.xml b/common/lint-baseline.xml
deleted file mode 100644
index 4c54e9fc..00000000
--- a/common/lint-baseline.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.net.NetworkRequest#canBeSatisfiedBy`"
- errorLine1=" &amp;&amp; n.request.canBeSatisfiedBy(mCapabilityFilter)"
- errorLine2=" ~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/device/android/net/NetworkFactory.java"
- line="307"
- column="26"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.net.NetworkRequest#canBeSatisfiedBy`"
- errorLine1=" || !n.request.canBeSatisfiedBy(mCapabilityFilter)"
- errorLine2=" ~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/device/android/net/NetworkFactory.java"
- line="323"
- column="35"/>
- </issue>
-
-</issues>
diff --git a/common/native/bpf_syscall_wrappers/Android.bp b/common/native/bpf_syscall_wrappers/Android.bp
index fa906554..befb9f8f 100644
--- a/common/native/bpf_syscall_wrappers/Android.bp
+++ b/common/native/bpf_syscall_wrappers/Android.bp
@@ -35,5 +35,6 @@ cc_library_headers {
visibility: [
"//packages/modules/Connectivity/Tethering",
"//system/bpf/libbpf_android",
+ "//system/memory/lmkd",
],
}
diff --git a/common/tests/unit/Android.bp b/common/tests/unit/Android.bp
index 45a89b0b..23835fe9 100644
--- a/common/tests/unit/Android.bp
+++ b/common/tests/unit/Android.bp
@@ -10,6 +10,7 @@ android_library {
name: "NetworkStaticLibTestsLib",
srcs: ["src/**/*.java","src/**/*.kt"],
min_sdk_version: "29",
+ defaults: ["framework-connectivity-test-defaults"],
static_libs: [
"net-utils-framework-common",
"androidx.test.rules",
@@ -23,7 +24,8 @@ android_library {
],
visibility: [
"//frameworks/base/packages/Tethering/tests/integration",
- "//packages/modules/Connectivity/Tethering/tests/integration",
+ "//packages/modules/Connectivity/tests:__subpackages__",
+ "//packages/modules/Connectivity/Tethering/tests:__subpackages__",
"//packages/modules/NetworkStack/tests/integration",
]
}
diff --git a/common/tests/unit/lint-baseline.xml b/common/tests/unit/lint-baseline.xml
index 0990916f..e3a6c1e1 100644
--- a/common/tests/unit/lint-baseline.xml
+++ b/common/tests/unit/lint-baseline.xml
@@ -3,325 +3,6 @@
<issue
id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertTrue(CollectionUtils.any(listOf(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;)) { it == &quot;E&quot; })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="32"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertFalse(CollectionUtils.any(listOf(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;)) { it == &quot;F&quot; })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="33"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertTrue(CollectionUtils.any(listOf(&quot;AA&quot;, &quot;BBB&quot;)) { it.length >= 3 })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="34"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertFalse(CollectionUtils.any(listOf(&quot;A&quot;, &quot;BB&quot;, &quot;CCC&quot;)) { it.length >= 4 })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="35"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertFalse(CollectionUtils.any(listOf(&quot;A&quot;, &quot;BB&quot;, &quot;CCC&quot;)) { it.length &lt; 0 })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="36"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertFalse(CollectionUtils.any(listOf&lt;String>()) { true })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="37"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertFalse(CollectionUtils.any(listOf&lt;String>()) { false })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="38"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertTrue(CollectionUtils.any(listOf(&quot;A&quot;)) { true })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="39"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#any`"
- errorLine1=" assertFalse(CollectionUtils.any(listOf(&quot;A&quot;)) { false })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="40"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#indexOf`"
- errorLine1=" assertEquals(4, CollectionUtils.indexOf(listOf(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;)) { it == &quot;E&quot; })"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="45"
- column="41"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#indexOf`"
- errorLine1=" assertEquals(0, CollectionUtils.indexOf(listOf(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;)) { it == &quot;A&quot; })"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="46"
- column="41"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#indexOf`"
- errorLine1=" assertEquals(1, CollectionUtils.indexOf(listOf(&quot;AA&quot;, &quot;BBB&quot;, &quot;CCCC&quot;)) { it.length >= 3 })"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="47"
- column="41"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#indexOf`"
- errorLine1=" assertEquals(1, CollectionUtils.indexOf(listOf(&quot;AA&quot;, null, &quot;CCCC&quot;)) { it == null })"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="48"
- column="41"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#indexOf`"
- errorLine1=" assertEquals(1, CollectionUtils.indexOf(listOf(null, &quot;CCCC&quot;)) { it != null })"
- errorLine2=" ~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="49"
- column="41"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertFalse(CollectionUtils.all(listOf(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;)) { it != &quot;E&quot; })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="54"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertTrue(CollectionUtils.all(listOf(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;)) { it != &quot;F&quot; })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="55"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertFalse(CollectionUtils.all(listOf(&quot;A&quot;, &quot;BB&quot;, &quot;CCC&quot;)) { it.length > 2 })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="56"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertTrue(CollectionUtils.all(listOf(&quot;A&quot;, &quot;BB&quot;, &quot;CCC&quot;)) { it.length >= 1 })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="57"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertTrue(CollectionUtils.all(listOf(&quot;A&quot;, &quot;BB&quot;, &quot;CCC&quot;)) { it.length &lt; 4 })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="58"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertTrue(CollectionUtils.all(listOf&lt;String>()) { true })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="59"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertTrue(CollectionUtils.all(listOf&lt;String>()) { false })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="60"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertTrue(CollectionUtils.all(listOf(1)) { true })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="61"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.CollectionUtils#all`"
- errorLine1=" assertFalse(CollectionUtils.all(listOf(1)) { false })"
- errorLine2=" ~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/CollectionUtilsTest.kt"
- line="62"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.ConnectivityUtils#isIPv6ULA`"
- errorLine1=" assertTrue(isIPv6ULA(parseNumericAddress(&quot;fc00::&quot;)));"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java"
- line="38"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.ConnectivityUtils#isIPv6ULA`"
- errorLine1=" assertTrue(isIPv6ULA(parseNumericAddress(&quot;fc00::1&quot;)));"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java"
- line="39"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.ConnectivityUtils#isIPv6ULA`"
- errorLine1=" assertTrue(isIPv6ULA(parseNumericAddress(&quot;fc00:1234::5678&quot;)));"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java"
- line="40"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.ConnectivityUtils#isIPv6ULA`"
- errorLine1=" assertTrue(isIPv6ULA(parseNumericAddress(&quot;fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff&quot;)));"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java"
- line="41"
- column="20"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.ConnectivityUtils#isIPv6ULA`"
- errorLine1=" assertFalse(isIPv6ULA(parseNumericAddress(&quot;fe00::&quot;)));"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java"
- line="43"
- column="21"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.ConnectivityUtils#isIPv6ULA`"
- errorLine1=" assertFalse(isIPv6ULA(parseNumericAddress(&quot;2480:1248::123:456&quot;)));"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/ConnectivityUtilsTest.java"
- line="44"
- column="21"/>
- </issue>
-
- <issue
- id="NewApi"
message="Call requires API level R (current min is 29): `android.app.AppOpsManager#noteOp`"
errorLine1=" when(mMockAppOps.noteOp(AppOpsManager.OPSTR_WIFI_SCAN, mUid, TEST_PKG_NAME,"
errorLine2=" ~~~~~~">
@@ -355,138 +36,6 @@
<issue
id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_WIFI, getDisplayTransport(intArrayOf(TRANSPORT_WIFI)))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="53"
- column="38"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_CELLULAR, getDisplayTransport(intArrayOf(TRANSPORT_CELLULAR)))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="54"
- column="42"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_BLUETOOTH, getDisplayTransport(intArrayOf(TRANSPORT_BLUETOOTH)))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="55"
- column="43"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_ETHERNET, getDisplayTransport(intArrayOf(TRANSPORT_ETHERNET)))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="56"
- column="42"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_WIFI_AWARE, getDisplayTransport(intArrayOf(TRANSPORT_WIFI_AWARE)))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="57"
- column="44"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_VPN, getDisplayTransport("
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="59"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_VPN, getDisplayTransport("
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="61"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_WIFI, getDisplayTransport("
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="64"
- column="38"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" assertEquals(TRANSPORT_ETHERNET, getDisplayTransport("
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="66"
- column="42"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#getDisplayTransport`"
- errorLine1=" getDisplayTransport(intArrayOf())"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="70"
- column="13"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#packBits`"
- errorLine1=" assertEquals(packedBits, packBits(bits))"
- errorLine2=" ~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="87"
- column="34"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#unpackBits`"
- errorLine1=" assertTrue(bits contentEquals unpackBits(packedBits))"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="88"
- column="39"/>
- </issue>
-
- <issue
- id="NewApi"
message="Call requires API level R (current min is 29): `android.net.NetworkCapabilities()`"
errorLine1=" val nc = NetworkCapabilities()"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
@@ -496,147 +45,4 @@
column="18"/>
</issue>
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#inferRestrictedCapability`"
- errorLine1=" assertFalse(NetworkCapabilitiesUtils.inferRestrictedCapability(nc))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="95"
- column="46"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#inferRestrictedCapability`"
- errorLine1=" assertTrue(NetworkCapabilitiesUtils.inferRestrictedCapability(nc))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="99"
- column="45"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#inferRestrictedCapability`"
- errorLine1=" assertFalse(NetworkCapabilitiesUtils.inferRestrictedCapability(nc))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="104"
- column="46"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkCapabilitiesUtils#inferRestrictedCapability`"
- errorLine1=" assertTrue(NetworkCapabilitiesUtils.inferRestrictedCapability(nc))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="108"
- column="45"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberId`"
- errorLine1=" assertEquals(&quot;123456...&quot;, scrubSubscriberId(&quot;1234567890123&quot;))"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="34"
- column="35"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberId`"
- errorLine1=" assertEquals(&quot;123456...&quot;, scrubSubscriberId(&quot;1234567&quot;))"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="35"
- column="35"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberId`"
- errorLine1=" assertEquals(&quot;123...&quot;, scrubSubscriberId(&quot;123&quot;))"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="36"
- column="32"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberId`"
- errorLine1=" assertEquals(&quot;...&quot;, scrubSubscriberId(&quot;&quot;))"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="37"
- column="29"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberId`"
- errorLine1=" assertEquals(&quot;null&quot;, scrubSubscriberId(null))"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="38"
- column="30"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberIds`"
- errorLine1=" assertContainsStringsExactly(scrubSubscriberIds(arrayOf(&quot;1234567&quot;, &quot;&quot;, null))!!,"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="43"
- column="38"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberIds`"
- errorLine1=" assertContainsStringsExactly(scrubSubscriberIds(arrayOf(&quot;12345&quot;))!!, &quot;12345...&quot;)"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="45"
- column="38"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberIds`"
- errorLine1=" assertContainsStringsExactly(scrubSubscriberIds(arrayOf())!!)"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="46"
- column="38"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `com.android.net.module.util.NetworkIdentityUtils#scrubSubscriberIds`"
- errorLine1=" assertNull(scrubSubscriberIds(null))"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkIdentityUtilsTest.kt"
- line="47"
- column="20"/>
- </issue>
-
</issues>
diff --git a/common/tests/unit/src/com/android/net/module/util/StructTest.java b/common/tests/unit/src/com/android/net/module/util/StructTest.java
index df74398f..eabc14b4 100644
--- a/common/tests/unit/src/com/android/net/module/util/StructTest.java
+++ b/common/tests/unit/src/com/android/net/module/util/StructTest.java
@@ -31,7 +31,6 @@ import android.net.MacAddress;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.util.HexDump;
import com.android.net.module.util.Struct.Field;
import com.android.net.module.util.Struct.Type;
diff --git a/common/testutils/Android.bp b/common/testutils/Android.bp
index d4465dd7..d29c1cd9 100644
--- a/common/testutils/Android.bp
+++ b/common/testutils/Android.bp
@@ -22,7 +22,10 @@ java_library {
"devicetests/**/*.java",
"devicetests/**/*.kt",
],
- defaults: ["lib_mockito_extended"],
+ defaults: [
+ "framework-connectivity-test-defaults",
+ "lib_mockito_extended"
+ ],
libs: [
"androidx.annotation_annotation",
],
@@ -32,6 +35,7 @@ java_library {
"libnanohttpd",
"net-tests-utils-host-device-common",
"net-utils-device-common",
+ "modules-utils-build_system",
],
}
diff --git a/common/testutils/devicetests/com/android/testutils/TestHttpServer.kt b/common/testutils/devicetests/com/android/testutils/TestHttpServer.kt
index 7aae8e3b..39ce4872 100644
--- a/common/testutils/devicetests/com/android/testutils/TestHttpServer.kt
+++ b/common/testutils/devicetests/com/android/testutils/TestHttpServer.kt
@@ -54,12 +54,12 @@ class TestHttpServer(host: String? = null) : NanoHTTPD(host, 0 /* auto-select th
fun addResponse(
uri: Uri,
statusCode: Response.IStatus,
- locationHeader: String? = null,
+ headers: Map<String, String>? = null,
content: String = ""
) {
addResponse(Request(uri.path
?: "", Method.GET, uri.query ?: ""),
- statusCode, locationHeader, content)
+ statusCode, headers, content)
}
/**
@@ -68,11 +68,13 @@ class TestHttpServer(host: String? = null) : NanoHTTPD(host, 0 /* auto-select th
fun addResponse(
request: Request,
statusCode: Response.IStatus,
- locationHeader: String? = null,
+ headers: Map<String, String>? = null,
content: String = ""
) {
val response = newFixedLengthResponse(statusCode, "text/plain", content)
- locationHeader?.let { response.addHeader("Location", it) }
+ headers?.forEach {
+ (key, value) -> response.addHeader(key, value)
+ }
responses[request] = response
}
diff --git a/common/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt b/common/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt
index 5b978617..36c09ce6 100644
--- a/common/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt
+++ b/common/testutils/devicetests/com/android/testutils/TestNetworkTracker.kt
@@ -26,6 +26,7 @@ import android.net.NetworkRequest
import android.net.TestNetworkInterface
import android.net.TestNetworkManager
import android.os.Binder
+import com.android.modules.utils.build.SdkLevel.isAtLeastS
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
@@ -39,7 +40,8 @@ import java.util.concurrent.TimeUnit
fun initTestNetwork(context: Context, interfaceAddr: LinkAddress, setupTimeoutMs: Long = 10_000L):
TestNetworkTracker {
val tnm = context.getSystemService(TestNetworkManager::class.java)
- val iface = tnm.createTunInterface(arrayOf(interfaceAddr))
+ val iface = if (isAtLeastS()) tnm.createTunInterface(listOf(interfaceAddr))
+ else tnm.createTunInterface(arrayOf(interfaceAddr))
return TestNetworkTracker(context, iface, tnm, setupTimeoutMs)
}
@@ -51,7 +53,7 @@ fun initTestNetwork(context: Context, interfaceAddr: LinkAddress, setupTimeoutMs
class TestNetworkTracker internal constructor(
val context: Context,
val iface: TestNetworkInterface,
- tnm: TestNetworkManager,
+ val tnm: TestNetworkManager,
setupTimeoutMs: Long
) {
private val cm = context.getSystemService(ConnectivityManager::class.java)
@@ -87,5 +89,6 @@ class TestNetworkTracker internal constructor(
fun teardown() {
cm.unregisterNetworkCallback(networkCallback)
+ tnm.teardownTestNetwork(network)
}
} \ No newline at end of file
diff --git a/common/testutils/devicetests/com/android/testutils/TestableNetworkOfferCallback.kt b/common/testutils/devicetests/com/android/testutils/TestableNetworkOfferCallback.kt
new file mode 100644
index 00000000..21bd60c9
--- /dev/null
+++ b/common/testutils/devicetests/com/android/testutils/TestableNetworkOfferCallback.kt
@@ -0,0 +1,75 @@
+/*
+ * 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 com.android.testutils
+
+import android.net.NetworkCapabilities
+import android.net.NetworkProvider
+import android.net.NetworkRequest
+import android.util.Log
+import com.android.net.module.util.ArrayTrackRecord
+import kotlin.test.fail
+
+class TestableNetworkOfferCallback(val timeoutMs: Long, private val noCallbackTimeoutMs: Long)
+ : NetworkProvider.NetworkOfferCallback {
+ private val TAG = this::class.simpleName
+ val history = ArrayTrackRecord<CallbackEntry>().newReadHead()
+
+ sealed class CallbackEntry {
+ data class OnNetworkNeeded(val request: NetworkRequest) : CallbackEntry()
+ data class OnNetworkUnneeded(val request: NetworkRequest) : CallbackEntry()
+ }
+
+ /**
+ * Called by the system when a network for this offer is needed to satisfy some
+ * networking request.
+ */
+ override fun onNetworkNeeded(request: NetworkRequest) {
+ Log.d(TAG, "onNetworkNeeded $request")
+ history.add(CallbackEntry.OnNetworkNeeded(request))
+ }
+
+ /**
+ * Called by the system when this offer is no longer valuable for this request.
+ */
+ override fun onNetworkUnneeded(request: NetworkRequest) {
+ Log.d(TAG, "onNetworkUnneeded $request")
+ history.add(CallbackEntry.OnNetworkUnneeded(request))
+ }
+
+ inline fun <reified T : CallbackEntry> expectCallbackThat(
+ crossinline predicate: (T) -> Boolean
+ ) {
+ val event = history.poll(timeoutMs)
+ ?: fail("Did not receive callback after ${timeoutMs}ms")
+ if (event !is T || !predicate(event)) fail("Received unexpected callback $event")
+ }
+
+ fun expectOnNetworkNeeded(capabilities: NetworkCapabilities) =
+ expectCallbackThat<CallbackEntry.OnNetworkNeeded> {
+ it.request.canBeSatisfiedBy(capabilities)
+ }
+
+ fun expectOnNetworkUnneeded(capabilities: NetworkCapabilities) =
+ expectCallbackThat<CallbackEntry.OnNetworkUnneeded> {
+ it.request.canBeSatisfiedBy(capabilities)
+ }
+
+ fun assertNoCallback() {
+ val cb = history.poll(noCallbackTimeoutMs)
+ if (null != cb) fail("Expected no callback but got $cb")
+ }
+} \ No newline at end of file
diff --git a/common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProvider.kt b/common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProvider.kt
index d5c3a2a0..8477151b 100644
--- a/common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProvider.kt
+++ b/common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProvider.kt
@@ -23,13 +23,19 @@ import kotlin.test.assertTrue
import kotlin.test.fail
private const val DEFAULT_TIMEOUT_MS = 200L
+const val TOKEN_ANY = -1
open class TestableNetworkStatsProvider(
val defaultTimeoutMs: Long = DEFAULT_TIMEOUT_MS
) : NetworkStatsProvider() {
sealed class CallbackType {
data class OnRequestStatsUpdate(val token: Int) : CallbackType()
- data class OnSetLimit(val iface: String?, val quotaBytes: Long) : CallbackType()
+ data class OnSetWarningAndLimit(
+ val iface: String?,
+ val warningBytes: Long,
+ val limitBytes: Long
+ ) : CallbackType()
+ data class OnSetLimit(val iface: String?, val limitBytes: Long) : CallbackType()
data class OnSetAlert(val quotaBytes: Long) : CallbackType()
}
@@ -41,6 +47,10 @@ open class TestableNetworkStatsProvider(
history.add(CallbackType.OnRequestStatsUpdate(token))
}
+ override fun onSetWarningAndLimit(iface: String, warningBytes: Long, limitBytes: Long) {
+ history.add(CallbackType.OnSetWarningAndLimit(iface, warningBytes, limitBytes))
+ }
+
override fun onSetLimit(iface: String, quotaBytes: Long) {
history.add(CallbackType.OnSetLimit(iface, quotaBytes))
}
@@ -49,8 +59,13 @@ open class TestableNetworkStatsProvider(
history.add(CallbackType.OnSetAlert(quotaBytes))
}
- fun expectOnRequestStatsUpdate(token: Int, timeout: Long = defaultTimeoutMs) {
- assertEquals(CallbackType.OnRequestStatsUpdate(token), history.poll(timeout))
+ fun expectOnRequestStatsUpdate(token: Int, timeout: Long = defaultTimeoutMs): Int {
+ val event = history.poll(timeout)
+ assertTrue(event is CallbackType.OnRequestStatsUpdate)
+ if (token != TOKEN_ANY) {
+ assertEquals(token, event.token)
+ }
+ return event.token
}
fun expectOnSetLimit(iface: String?, quotaBytes: Long, timeout: Long = defaultTimeoutMs) {
diff --git a/common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderCbBinder.kt b/common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderCbBinder.kt
index f15f610b..c039cad1 100644
--- a/common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderCbBinder.kt
+++ b/common/testutils/devicetests/com/android/testutils/TestableNetworkStatsProviderCbBinder.kt
@@ -32,6 +32,7 @@ open class TestableNetworkStatsProviderCbBinder : NetworkStatsProviderCbStubComp
val uidStats: NetworkStats
) : CallbackType()
object NotifyWarningOrLimitReached : CallbackType()
+ object LegacyNotifyLimitReached : CallbackType()
object NotifyAlertReached : CallbackType()
object Unregister : CallbackType()
}
@@ -46,6 +47,11 @@ open class TestableNetworkStatsProviderCbBinder : NetworkStatsProviderCbStubComp
history.add(CallbackType.NotifyWarningOrLimitReached)
}
+ override fun notifyLimitReached() {
+ // Older callback renamed to notifyWarningOrLimitReached in S
+ history.add(CallbackType.LegacyNotifyLimitReached)
+ }
+
override fun notifyAlertReached() {
history.add(CallbackType.NotifyAlertReached)
}
@@ -72,6 +78,9 @@ open class TestableNetworkStatsProviderCbBinder : NetworkStatsProviderCbStubComp
fun expectNotifyWarningOrLimitReached() =
assertEquals(CallbackType.NotifyWarningOrLimitReached, history.poll(DEFAULT_TIMEOUT_MS))
+ fun expectLegacyNotifyLimitReached() =
+ assertEquals(CallbackType.LegacyNotifyLimitReached, history.poll(DEFAULT_TIMEOUT_MS))
+
fun expectNotifyAlertReached() =
assertEquals(CallbackType.NotifyAlertReached, history.poll(DEFAULT_TIMEOUT_MS))