Merge changes Ic490fee6,If78047c3 into main

* changes:
  Add hidden constants for communicating about local network agents
  Use isAtLeast* from deps
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
index 81d4fbe..60f2d17 100644
--- a/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
@@ -44,6 +44,7 @@
 import com.android.net.module.util.netlink.NetlinkUtils;
 import com.android.net.module.util.netlink.StructNlMsgHdr;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -84,6 +85,14 @@
         mOffloadHw = new OffloadHardwareInterface(mHandler, mLog, mDeps);
     }
 
+    @After
+    public void tearDown() throws Exception {
+        if (mHandlerThread != null) {
+            mHandlerThread.quitSafely();
+            mHandlerThread.join();
+        }
+    }
+
     void findConnectionOrThrow(FileDescriptor fd, InetSocketAddress local, InetSocketAddress remote)
             throws Exception {
         Log.d(TAG, "Looking for socket " + local + " -> " + remote);
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index ea4d82a..986d58b 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -11468,7 +11468,8 @@
         // If there is no default network, default network is considered active to keep the existing
         // behavior. Initial value is used until first connect to the default network.
         private volatile boolean mIsDefaultNetworkActive = true;
-        private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap<>();
+        // Key is netId. Value is configured idle timer information.
+        private final SparseArray<IdleTimerParams> mActiveIdleTimers = new SparseArray<>();
 
         private static class IdleTimerParams {
             public final int timeout;
@@ -11496,7 +11497,7 @@
 
         public void handleReportNetworkActivity(NetworkActivityParams activityParams) {
             ensureRunningOnConnectivityServiceThread();
-            if (mActiveIdleTimers.isEmpty()) {
+            if (mActiveIdleTimers.size() == 0) {
                 // This activity change is not for the current default network.
                 // This can happen if netd callback post activity change event message but
                 // the default network is lost before processing this message.
@@ -11572,6 +11573,7 @@
          */
         private boolean setupDataActivityTracking(NetworkAgentInfo networkAgent) {
             final String iface = networkAgent.linkProperties.getInterfaceName();
+            final int netId = networkAgent.network().netId;
 
             final int timeout;
             final int type;
@@ -11596,7 +11598,7 @@
 
             if (timeout > 0 && iface != null) {
                 try {
-                    mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
+                    mActiveIdleTimers.put(netId, new IdleTimerParams(timeout, type));
                     mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type));
                     return true;
                 } catch (Exception e) {
@@ -11612,6 +11614,7 @@
          */
         private void removeDataActivityTracking(NetworkAgentInfo networkAgent) {
             final String iface = networkAgent.linkProperties.getInterfaceName();
+            final int netId = networkAgent.network().netId;
             final NetworkCapabilities caps = networkAgent.networkCapabilities;
 
             if (iface == null) return;
@@ -11627,11 +11630,12 @@
 
             try {
                 updateRadioPowerState(false /* isActive */, type);
-                final IdleTimerParams params = mActiveIdleTimers.remove(iface);
+                final IdleTimerParams params = mActiveIdleTimers.get(netId);
                 if (params == null) {
                     // IdleTimer is not added if the configured timeout is 0 or negative value
                     return;
                 }
+                mActiveIdleTimers.remove(netId);
                 // The call fails silently if no idle timer setup for this interface
                 mNetd.idletimerRemoveInterface(iface, params.timeout,
                         Integer.toString(params.transportType));
@@ -11702,9 +11706,9 @@
             pw.print("mIsDefaultNetworkActive="); pw.println(mIsDefaultNetworkActive);
             pw.println("Idle timers:");
             try {
-                for (Map.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
-                    pw.print("  "); pw.print(ent.getKey()); pw.println(":");
-                    final IdleTimerParams params = ent.getValue();
+                for (int i = 0; i < mActiveIdleTimers.size(); i++) {
+                    pw.print("  "); pw.print(mActiveIdleTimers.keyAt(i)); pw.println(":");
+                    final IdleTimerParams params = mActiveIdleTimers.valueAt(i);
                     pw.print("    timeout="); pw.print(params.timeout);
                     pw.print(" type="); pw.println(params.transportType);
                 }
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClientTest.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClientTest.java
index 3701b0c..8917ed3 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClientTest.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsMultinetworkSocketClientTest.java
@@ -42,6 +42,7 @@
 import com.android.testutils.DevSdkIgnoreRunner;
 import com.android.testutils.HandlerUtils;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -69,6 +70,7 @@
     @Mock private SocketCreationCallback mSocketCreationCallback;
     @Mock private SharedLog mSharedLog;
     private MdnsMultinetworkSocketClient mSocketClient;
+    private HandlerThread mHandlerThread;
     private Handler mHandler;
     private SocketKey mSocketKey;
 
@@ -76,14 +78,23 @@
     public void setUp() throws SocketException {
         MockitoAnnotations.initMocks(this);
 
-        final HandlerThread thread = new HandlerThread("MdnsMultinetworkSocketClientTest");
-        thread.start();
-        mHandler = new Handler(thread.getLooper());
+        mHandlerThread = new HandlerThread("MdnsMultinetworkSocketClientTest");
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
         mSocketKey = new SocketKey(1000 /* interfaceIndex */);
-        mSocketClient = new MdnsMultinetworkSocketClient(thread.getLooper(), mProvider, mSharedLog);
+        mSocketClient = new MdnsMultinetworkSocketClient(
+                mHandlerThread.getLooper(), mProvider, mSharedLog);
         mHandler.post(() -> mSocketClient.setCallback(mCallback));
     }
 
+    @After
+    public void tearDown() throws Exception {
+        if (mHandlerThread != null) {
+            mHandlerThread.quitSafely();
+            mHandlerThread.join();
+        }
+    }
+
     private SocketCallback expectSocketCallback() {
         return expectSocketCallback(mListener, mNetwork);
     }
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
index 292f77e..c477b2c 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -59,6 +59,7 @@
 import com.android.testutils.DevSdkIgnoreRunner;
 import com.android.testutils.HandlerUtils;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -139,6 +140,14 @@
         mUsageCallback = new TestableUsageCallback(mUsageCallbackBinder);
     }
 
+    @After
+    public void tearDown() throws Exception {
+        if (mObserverHandlerThread != null) {
+            mObserverHandlerThread.quitSafely();
+            mObserverHandlerThread.join();
+        }
+    }
+
     @Test
     public void testRegister_thresholdTooLow_setsDefaultThreshold() throws Exception {
         final long thresholdTooLowBytes = 1L;