Merge "Add logs for changes in capabilities and score"
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 74ba209..ebc9d26 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -1473,6 +1473,15 @@
             // to Objects.hash() to avoid autoboxing overhead.
             return Objects.hash(upstreamIfindex, downstreamIfindex, address, srcMac, dstMac);
         }
+
+        @Override
+        public String toString() {
+            return "upstreamIfindex: " + upstreamIfindex
+                    + ", downstreamIfindex: " + downstreamIfindex
+                    + ", address: " + address.getHostAddress()
+                    + ", srcMac: " + srcMac
+                    + ", dstMac: " + dstMac;
+        }
     }
 
     /** Tethering client information class. */
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index ac92b43..bbca565 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -2092,4 +2092,11 @@
         assertNull(mBpfUpstream4Map.getValue(upstream4KeyB));
         assertNull(mBpfDownstream4Map.getValue(downstream4KeyB));
     }
+
+    @Test
+    public void testIpv6ForwardingRuleToString() throws Exception {
+        final Ipv6ForwardingRule rule = buildTestForwardingRule(UPSTREAM_IFINDEX, NEIGH_A, MAC_A);
+        assertEquals("upstreamIfindex: 1001, downstreamIfindex: 1003, address: 2001:db8::1, "
+                + "srcMac: 12:34:56:78:90:ab, dstMac: 00:00:00:00:00:0a", rule.toString());
+    }
 }
diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp
index fc76ae5..8f6df21 100644
--- a/service/native/TrafficController.cpp
+++ b/service/native/TrafficController.cpp
@@ -595,7 +595,7 @@
     }
 }
 
-void TrafficController::dump(int fd, bool verbose) {
+void TrafficController::dump(int fd, bool verbose __unused) {
     std::lock_guard guard(mMutex);
     DumpWriter dw(fd);
 
@@ -623,31 +623,6 @@
                getMapStatus(mConfigurationMap.getMap(), CONFIGURATION_MAP_PATH).c_str());
     dw.println("mUidOwnerMap status: %s",
                getMapStatus(mUidOwnerMap.getMap(), UID_OWNER_MAP_PATH).c_str());
-
-    if (!verbose) {
-        return;
-    }
-
-    dw.blankline();
-    dw.println("BPF map content:");
-
-    ScopedIndent indentForMapContent(dw);
-
-    // Print CookieTagMap content.
-    // TagSocketTest in CTS was using the output of mCookieTagMap dump.
-    // So, mCookieTagMap dump can not be removed until the previous CTS support period is over.
-    dumpBpfMap("mCookieTagMap", dw, "");
-    const auto printCookieTagInfo = [&dw](const uint64_t& key, const UidTagValue& value,
-                                          const BpfMap<uint64_t, UidTagValue>&) {
-        dw.println("cookie=%" PRIu64 " tag=0x%x uid=%u", key, value.tag, value.uid);
-        return base::Result<void>();
-    };
-    base::Result<void> res = mCookieTagMap.iterateWithValue(printCookieTagInfo);
-    if (!res.ok()) {
-        dw.println("mCookieTagMap print end with error: %s", res.error().message().c_str());
-    }
-
-    dw.blankline();
 }
 
 }  // namespace net
diff --git a/service/native/TrafficControllerTest.cpp b/service/native/TrafficControllerTest.cpp
index 6cb0940..57f32af 100644
--- a/service/native/TrafficControllerTest.cpp
+++ b/service/native/TrafficControllerTest.cpp
@@ -59,7 +59,6 @@
 constexpr uid_t TEST_UID3 = 98765;
 constexpr uint32_t TEST_TAG = 42;
 constexpr uint32_t TEST_COUNTERSET = 1;
-constexpr int TEST_COOKIE = 1;
 constexpr int TEST_IFINDEX = 999;
 constexpr int RXPACKETS = 1;
 constexpr int RXBYTES = 100;
@@ -769,46 +768,6 @@
     expectPrivilegedUserSetEmpty();
 }
 
-TEST_F(TrafficControllerTest, TestDumpsys) {
-    StatsKey tagStatsMapKey;
-    populateFakeStats(TEST_COOKIE, TEST_UID, TEST_TAG, &tagStatsMapKey);
-    populateFakeCounterSet(TEST_UID3, TEST_COUNTERSET);
-
-    // Expect: (part of this depends on hard-code values in populateFakeStats())
-    //
-    // mCookieTagMap:
-    // cookie=1 tag=0x2a uid=10086
-    //
-    // mUidCounterSetMap:
-    // 98765 1
-    //
-    // mAppUidStatsMap::
-    // uid rxBytes rxPackets txBytes txPackets
-    // 10086 100 1 0 0
-    //
-    // mStatsMapA:
-    // ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
-    // 999 test0 0x2a 10086 1 100 1 0 0
-    std::vector<std::string> expectedLines = {
-        "mCookieTagMap:",
-        fmt::format("cookie={} tag={:#x} uid={}", TEST_COOKIE, TEST_TAG, TEST_UID)};
-
-    EXPECT_TRUE(expectDumpsysContains(expectedLines));
-}
-
-TEST_F(TrafficControllerTest, dumpsysInvalidMaps) {
-    makeTrafficControllerMapsInvalid();
-
-    const std::string kErrIterate = "print end with error: Get firstKey map -1 failed: "
-            "Bad file descriptor";
-    const std::string kErrReadRulesConfig = "read ownerMatch configure failed with error: "
-            "Read value of map -1 failed: Bad file descriptor";
-
-    std::vector<std::string> expectedLines = {
-        fmt::format("mCookieTagMap {}", kErrIterate)};
-    EXPECT_TRUE(expectDumpsysContains(expectedLines));
-}
-
 TEST_F(TrafficControllerTest, getFirewallType) {
     static const struct TestConfig {
         ChildChain childChain;
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index d560747..aea2103 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -1022,11 +1022,25 @@
         }
         mDeps.nativeDump(fd, verbose);
 
+        pw.println();
+        pw.println("sEnableJavaBpfMap: " + sEnableJavaBpfMap);
         if (verbose) {
+            pw.println();
+            pw.println("BPF map content:");
+            pw.increaseIndent();
+
             dumpOwnerMatchConfig(pw);
             dumpCurrentStatsMapConfig(pw);
             pw.println();
 
+            // TODO: Remove CookieTagMap content dump
+            // NetworkStatsService also dumps CookieTagMap and NetworkStatsService is a right place
+            // to dump CookieTagMap. But the TagSocketTest in CTS depends on this dump so the tests
+            // need to be updated before remove the dump from BpfNetMaps.
+            BpfDump.dumpMap(sCookieTagMap, pw, "sCookieTagMap",
+                    (key, value) -> "cookie=" + key.socketCookie
+                            + " tag=0x" + Long.toHexString(value.tag)
+                            + " uid=" + value.uid);
             BpfDump.dumpMap(sUidOwnerMap, pw, "sUidOwnerMap",
                     (uid, match) -> {
                         if ((match.rule & IIF_MATCH) != 0) {
@@ -1038,6 +1052,7 @@
                     });
             BpfDump.dumpMap(sUidPermissionMap, pw, "sUidPermissionMap",
                     (uid, permission) -> uid.val + " " + permissionToString(permission.val));
+            pw.decreaseIndent();
         }
     }
 
diff --git a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
index 8a537be..679427a 100644
--- a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
+++ b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
@@ -16,7 +16,16 @@
 
 package android.app.usage;
 
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
+import static android.net.NetworkStats.METERED_NO;
 import static android.net.NetworkStats.METERED_YES;
+import static android.net.NetworkStats.ROAMING_NO;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStatsHistory.FIELD_ALL;
 import static android.net.NetworkTemplate.MATCH_MOBILE;
 import static android.net.NetworkTemplate.MATCH_WIFI;
 
@@ -34,7 +43,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.net.ConnectivityManager;
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
 import android.net.NetworkStats.Entry;
@@ -86,31 +94,17 @@
         final int uid2 = 10002;
         final int uid3 = 10003;
 
-        Entry uid1Entry1 = new Entry("if1", uid1,
-                android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
-                android.net.NetworkStats.METERED_NO, android.net.NetworkStats.ROAMING_NO,
-                android.net.NetworkStats.DEFAULT_NETWORK_NO,
-                100, 10, 200, 20, 0);
+        Entry uid1Entry1 = new Entry("if1", uid1, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                DEFAULT_NETWORK_NO, 100, 10, 200, 20, 0);
 
-        Entry uid1Entry2 = new Entry(
-                "if2", uid1,
-                android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
-                android.net.NetworkStats.METERED_NO, android.net.NetworkStats.ROAMING_NO,
-                android.net.NetworkStats.DEFAULT_NETWORK_NO,
-                100, 10, 200, 20, 0);
+        Entry uid1Entry2 = new Entry("if2", uid1, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                DEFAULT_NETWORK_NO, 100, 10, 200, 20, 0);
 
-        Entry uid2Entry1 = new Entry("if1", uid2,
-                android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
-                android.net.NetworkStats.METERED_NO, android.net.NetworkStats.ROAMING_NO,
-                android.net.NetworkStats.DEFAULT_NETWORK_NO,
-                150, 10, 250, 20, 0);
+        Entry uid2Entry1 = new Entry("if1", uid2, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                DEFAULT_NETWORK_NO, 150, 10, 250, 20, 0);
 
-        Entry uid2Entry2 = new Entry(
-                "if2", uid2,
-                android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
-                android.net.NetworkStats.METERED_NO, android.net.NetworkStats.ROAMING_NO,
-                android.net.NetworkStats.DEFAULT_NETWORK_NO,
-                150, 10, 250, 20, 0);
+        Entry uid2Entry2 = new Entry("if2", uid2, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                DEFAULT_NETWORK_NO, 150, 10, 250, 20, 0);
 
         NetworkStatsHistory history1 = new NetworkStatsHistory(10, 2);
         history1.recordData(10, 20, uid1Entry1);
@@ -125,9 +119,8 @@
         when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2, uid3 });
 
         when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class),
-                eq(uid1), eq(android.net.NetworkStats.SET_ALL),
-                eq(android.net.NetworkStats.TAG_NONE),
-                eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)))
+                eq(uid1), eq(SET_ALL), eq(TAG_NONE),
+                eq(FIELD_ALL), eq(startTime), eq(endTime)))
                 .then((InvocationOnMock inv) -> {
                     NetworkTemplate template = inv.getArgument(0);
                     assertEquals(MATCH_MOBILE_ALL, template.getMatchRule());
@@ -136,9 +129,8 @@
                 });
 
         when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class),
-                eq(uid2), eq(android.net.NetworkStats.SET_ALL),
-                eq(android.net.NetworkStats.TAG_NONE),
-                eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)))
+                eq(uid2), eq(SET_ALL), eq(TAG_NONE),
+                eq(FIELD_ALL), eq(startTime), eq(endTime)))
                 .then((InvocationOnMock inv) -> {
                     NetworkTemplate template = inv.getArgument(0);
                     assertEquals(MATCH_MOBILE_ALL, template.getMatchRule());
@@ -148,7 +140,7 @@
 
 
         NetworkStats stats = mManager.queryDetails(
-                ConnectivityManager.TYPE_MOBILE, TEST_SUBSCRIBER_ID, startTime, endTime);
+                TYPE_MOBILE, TEST_SUBSCRIBER_ID, startTime, endTime);
 
         NetworkStats.Bucket bucket = new NetworkStats.Bucket();
 
@@ -202,35 +194,34 @@
 
         verify(mStatsSession, times(1)).getHistoryIntervalForUid(
                 eq(expectedTemplate),
-                eq(uid1), eq(android.net.NetworkStats.SET_ALL),
-                eq(android.net.NetworkStats.TAG_NONE),
-                eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+                eq(uid1), eq(SET_ALL),
+                eq(TAG_NONE),
+                eq(FIELD_ALL), eq(startTime), eq(endTime));
 
         verify(mStatsSession, times(1)).getHistoryIntervalForUid(
                 eq(expectedTemplate),
-                eq(uid2), eq(android.net.NetworkStats.SET_ALL),
-                eq(android.net.NetworkStats.TAG_NONE),
-                eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+                eq(uid2), eq(SET_ALL),
+                eq(TAG_NONE),
+                eq(FIELD_ALL), eq(startTime), eq(endTime));
 
         assertFalse(stats.hasNextBucket());
     }
 
     @Test
     public void testNetworkTemplateWhenRunningQueryDetails_NoSubscriberId() throws RemoteException {
-        runQueryDetailsAndCheckTemplate(ConnectivityManager.TYPE_MOBILE,
-                null /* subscriberId */, new NetworkTemplate.Builder(MATCH_MOBILE)
-                        .setMeteredness(METERED_YES).build());
-        runQueryDetailsAndCheckTemplate(ConnectivityManager.TYPE_WIFI,
-                "" /* subscriberId */, new NetworkTemplate.Builder(MATCH_WIFI).build());
-        runQueryDetailsAndCheckTemplate(ConnectivityManager.TYPE_WIFI,
-                null /* subscriberId */, new NetworkTemplate.Builder(MATCH_WIFI).build());
+        runQueryDetailsAndCheckTemplate(TYPE_MOBILE, null /* subscriberId */,
+                new NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES).build());
+        runQueryDetailsAndCheckTemplate(TYPE_WIFI, "" /* subscriberId */,
+                new NetworkTemplate.Builder(MATCH_WIFI).build());
+        runQueryDetailsAndCheckTemplate(TYPE_WIFI, null /* subscriberId */,
+                new NetworkTemplate.Builder(MATCH_WIFI).build());
     }
 
     @Test
     public void testNetworkTemplateWhenRunningQueryDetails_MergedCarrierWifi()
             throws RemoteException {
-        runQueryDetailsAndCheckTemplate(ConnectivityManager.TYPE_WIFI,
-                TEST_SUBSCRIBER_ID, new NetworkTemplate.Builder(MATCH_WIFI)
+        runQueryDetailsAndCheckTemplate(TYPE_WIFI, TEST_SUBSCRIBER_ID,
+                new NetworkTemplate.Builder(MATCH_WIFI)
                         .setSubscriberIds(Set.of(TEST_SUBSCRIBER_ID)).build());
     }
 
@@ -244,7 +235,7 @@
         when(mStatsSession.getTaggedSummaryForAllUid(any(NetworkTemplate.class),
                 anyLong(), anyLong()))
                 .thenReturn(new android.net.NetworkStats(0, 0));
-        final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+        final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_MOBILE)
                 .setMeteredness(NetworkStats.Bucket.METERED_YES).build();
         NetworkStats stats = mManager.queryTaggedSummary(template, startTime, endTime);
 
@@ -265,12 +256,12 @@
         when(mStatsSession.getHistoryIntervalForNetwork(any(NetworkTemplate.class),
                 anyInt(), anyLong(), anyLong()))
                 .thenReturn(new NetworkStatsHistory(10, 0));
-        final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+        final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_MOBILE)
                 .setMeteredness(NetworkStats.Bucket.METERED_YES).build();
         NetworkStats stats = mManager.queryDetailsForDevice(template, startTime, endTime);
 
         verify(mStatsSession, times(1)).getHistoryIntervalForNetwork(
-                eq(template), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+                eq(template), eq(FIELD_ALL), eq(startTime), eq(endTime));
 
         assertFalse(stats.hasNextBucket());
     }
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index 0c00bc0..0e17cd7 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -1070,4 +1070,11 @@
         doTestDumpOwnerMatchConfig(DOZABLE_MATCH | invalid_match,
                 "DOZABLE_MATCH UNKNOWN_MATCH(" + invalid_match + ")");
     }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testDumpCookieTagMap() throws Exception {
+        mCookieTagMap.updateEntry(new CookieTagMapKey(123), new CookieTagMapValue(456, 0x789));
+        assertDumpContains(getDump(), "cookie=123 tag=0x789 uid=456");
+    }
 }