Merge "Add fall back to createTunInterface when running on R" am: 80ce99810c am: 682f69146a

Original change: https://android-review.googlesource.com/c/platform/frameworks/libs/net/+/1742033

Change-Id: I845db2f17d53fa6827224d4ffee2548dfce4fec5
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index f3b2faa..1371c8c 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -34,9 +34,9 @@
 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",
   ],
@@ -117,13 +117,15 @@
         "//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",
@@ -138,6 +140,9 @@
     ],
     sdk_version: "system_current",
     min_sdk_version: "30",
+    static_libs: [
+        "modules-utils-build_system",
+    ],
     visibility: [
         "//frameworks/base/services/net",
     ],
@@ -150,6 +155,9 @@
     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: [
@@ -178,6 +186,9 @@
     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/staticlibs/device/android/net/NetworkFactory.java b/staticlibs/device/android/net/NetworkFactory.java
index 50cecde..87f6dee 100644
--- a/staticlibs/device/android/net/NetworkFactory.java
+++ b/staticlibs/device/android/net/NetworkFactory.java
@@ -16,11 +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.net.NetworkProvider.NetworkOfferCallback;
-import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.util.Log;
@@ -29,9 +29,6 @@
 
 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.
@@ -46,109 +43,54 @@
  * 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;
+public class NetworkFactory {
+    static final boolean DBG = true;
+    static final boolean VDBG = false;
 
-    // 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();
+    final NetworkFactoryShim mImpl;
 
-    /**
-     * 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.
-    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.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 Context mContext;
     private final String LOG_TAG;
 
-    private final Map<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
-            new LinkedHashMap<>();
-
-    @NonNull private NetworkScore mScore = new NetworkScore.Builder().setLegacyInt(0).build();
-    @NonNull private NetworkCapabilities mCapabilityFilter;
-
-    private int mRefCount = 0;
-    private NetworkProvider mProvider = null;
-
-    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.
     public NetworkFactory(Looper looper, Context context, String logTag,
             @Nullable final NetworkCapabilities filter) {
-        super(looper);
         LOG_TAG = logTag;
-        mContext = context;
-        if (null != filter) {
-            mCapabilityFilter = filter;
+        if (isAtLeastS()) {
+            mImpl = new NetworkFactoryImpl(this, looper, context, filter);
         } else {
-            mCapabilityFilter = new NetworkCapabilities.Builder()
-                    .withoutDefaultCapabilities().build();
+            mImpl = new NetworkFactoryLegacyImpl(this, looper, context, filter);
         }
     }
 
+    // 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);
+    }
+
+    // Called by BluetoothNetworkFactory
+    public final Looper getLooper() {
+        return mImpl.getLooper();
+    }
+
+    // Refcount for simple mode requests
+    private int mRefCount = 0;
+
     /* Registers this NetworkFactory with the system. May only be called once per factory. */
     public void register() {
-        register(false);
+        mImpl.register(LOG_TAG);
     }
 
     /**
@@ -157,152 +99,16 @@
      * May only be called once per factory.
      */
     public void registerIgnoringScore() {
-        register(true);
-    }
-
-    private void register(final boolean listenToAllRequests) {
-        if (mProvider != null) {
-            throw new IllegalStateException("A NetworkFactory must only be registered once");
-        }
-        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);
-            }
-
-            @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);
+        mImpl.registerIgnoringScore(LOG_TAG);
     }
 
     /** 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);
-    }
-
-    @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) log("got request " + request);
-            n = new NetworkRequestInfo(request);
-            mNetworkRequests.put(n.request, n);
-        } else {
-            if (VDBG) {
-                log("handle existing request " + request);
-            }
-        }
-        if (VDBG) log("  my score=" + mScore + ", my filter=" + mCapabilityFilter);
-
-        if (acceptRequest(request)) {
-            n.requested = true;
-            needNetworkFor(request);
-        }
-    }
-
-    private void handleRemoveRequest(NetworkRequest request) {
-        NetworkRequestInfo n = mNetworkRequests.get(request);
-        if (n != null) {
-            mNetworkRequests.remove(request);
-            if (n.requested) releaseNetworkFor(n.request);
-        }
-    }
-
-    private void handleSetScore(@NonNull final NetworkScore score) {
-        if (mScore.equals(score)) return;
-        mScore = score;
-        reevaluateAllRequests();
-    }
-
-    private void handleSetFilter(@NonNull final NetworkCapabilities netCap) {
-        if (netCap.equals(mCapabilityFilter)) return;
-        mCapabilityFilter = netCap;
-        reevaluateAllRequests();
+        mImpl.terminate();
     }
 
     protected final void reevaluateAllRequests() {
-        if (mProvider == null) return;
-        mProvider.registerNetworkOffer(mScore, mCapabilityFilter, mExecutor, mRequestCallback);
+        mImpl.reevaluateAllRequests();
     }
 
     /**
@@ -327,6 +133,7 @@
     public boolean acceptRequest(@NonNull final NetworkRequest request) {
         return true;
     }
+
     /**
      * Can be called by a factory to release a request as unfulfillable: the request will be
      * removed, and the caller will get a
@@ -337,15 +144,7 @@
      * 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)
@@ -363,11 +162,11 @@
 
     /**
      * @deprecated this method was never part of the API (system or public) and is only added
-     *   for migration of existing clients. It will be removed before S ships.
+     *   for migration of existing clients.
      */
     @Deprecated
     public void setScoreFilter(final int score) {
-        setScoreFilter(new NetworkScore.Builder().setLegacyInt(score).build());
+        mImpl.setScoreFilter(score);
     }
 
     /**
@@ -381,25 +180,24 @@
      * @param score the filter
      */
     public void setScoreFilter(@NonNull final NetworkScore score) {
-        sendMessage(obtainMessage(CMD_SET_SCORE, 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) {
@@ -407,18 +205,11 @@
     }
 
     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/staticlibs/device/android/net/NetworkFactoryImpl.java b/staticlibs/device/android/net/NetworkFactoryImpl.java
new file mode 100644
index 0000000..439ea14
--- /dev/null
+++ b/staticlibs/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/staticlibs/device/android/net/NetworkFactoryLegacyImpl.java b/staticlibs/device/android/net/NetworkFactoryLegacyImpl.java
new file mode 100644
index 0000000..6dd0adb
--- /dev/null
+++ b/staticlibs/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/staticlibs/device/android/net/NetworkFactoryShim.java b/staticlibs/device/android/net/NetworkFactoryShim.java
new file mode 100644
index 0000000..dfbb5ec
--- /dev/null
+++ b/staticlibs/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/staticlibs/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java b/staticlibs/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
index 382ed9f..d4b1c9e 100644
--- a/staticlibs/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/NetworkCapabilitiesUtils.java
@@ -47,6 +47,12 @@
  * @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
@@ -64,7 +70,8 @@
         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
diff --git a/staticlibs/jarjar-rules-shared.txt b/staticlibs/jarjar-rules-shared.txt
index a7fda7c..e26999d 100644
--- a/staticlibs/jarjar-rules-shared.txt
+++ b/staticlibs/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/staticlibs/lint-baseline.xml b/staticlibs/lint-baseline.xml
deleted file mode 100644
index 4c54e9f..0000000
--- a/staticlibs/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/staticlibs/tests/unit/Android.bp b/staticlibs/tests/unit/Android.bp
index 5c5a431..23835fe 100644
--- a/staticlibs/tests/unit/Android.bp
+++ b/staticlibs/tests/unit/Android.bp
@@ -10,6 +10,7 @@
     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",
diff --git a/staticlibs/tests/unit/lint-baseline.xml b/staticlibs/tests/unit/lint-baseline.xml
index 0990916..e3a6c1e 100644
--- a/staticlibs/tests/unit/lint-baseline.xml
+++ b/staticlibs/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/staticlibs/testutils/Android.bp b/staticlibs/testutils/Android.bp
index 6d9414f..d29c1cd 100644
--- a/staticlibs/testutils/Android.bp
+++ b/staticlibs/testutils/Android.bp
@@ -22,7 +22,10 @@
         "devicetests/**/*.java",
         "devicetests/**/*.kt",
     ],
-    defaults: ["lib_mockito_extended"],
+    defaults: [
+        "framework-connectivity-test-defaults",
+        "lib_mockito_extended"
+    ],
     libs: [
         "androidx.annotation_annotation",
     ],