Use java BpfMap in BpfNetMaps#addNaughtyApp

Bug: 217624062
Test: atest BpfNetMapsTest HostsideRestrictBackgroundNetworkTests
Change-Id: I69a2970d20be41431b774273bc0902bd325421f4
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index c3302cd..be0eb5f 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -228,6 +228,40 @@
         }
     }
 
+    private void addRule(final int uid, final long match, final long iif, final String caller) {
+        if (match != IIF_MATCH && iif != 0) {
+            throw new ServiceSpecificException(EINVAL,
+                    "Non-interface match must have zero interface index");
+        }
+
+        try {
+            synchronized (sUidOwnerMap) {
+                final UidOwnerValue oldMatch = sUidOwnerMap.getValue(new U32(uid));
+
+                final UidOwnerValue newMatch;
+                if (oldMatch != null) {
+                    newMatch = new UidOwnerValue(
+                            (match == IIF_MATCH) ? iif : oldMatch.iif,
+                            oldMatch.rule | match
+                    );
+                } else {
+                    newMatch = new UidOwnerValue(
+                            iif,
+                            match
+                    );
+                }
+                sUidOwnerMap.updateEntry(new U32(uid), newMatch);
+            }
+        } catch (ErrnoException e) {
+            throw new ServiceSpecificException(e.errno,
+                    caller + " failed to add rule: " + Os.strerror(e.errno));
+        }
+    }
+
+    private void addRule(final int uid, final long match, final String caller) {
+        addRule(uid, match, 0 /* iif */, caller);
+    }
+
     /**
      * Add naughty app bandwidth rule for specific app
      *
@@ -236,10 +270,8 @@
      *                                  cause of the failure.
      */
     public void addNaughtyApp(final int uid) {
-        synchronized (sUidOwnerMap) {
-            final int err = native_addNaughtyApp(uid);
-            maybeThrow(err, "Unable to add naughty app");
-        }
+        throwIfPreT("addNaughtyApp is not available on pre-T devices");
+        addRule(uid, PENALTY_BOX_MATCH, "addNaughtyApp");
     }
 
     /**
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index 79bf66e..e59fbc2 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -28,6 +28,7 @@
 
 import static com.android.server.BpfNetMaps.DOZABLE_MATCH;
 import static com.android.server.BpfNetMaps.IIF_MATCH;
+import static com.android.server.BpfNetMaps.NO_MATCH;
 import static com.android.server.BpfNetMaps.PENALTY_BOX_MATCH;
 import static com.android.server.BpfNetMaps.POWERSAVE_MATCH;
 import static com.android.server.BpfNetMaps.RESTRICTED_MATCH;
@@ -299,4 +300,36 @@
         assertThrows(UnsupportedOperationException.class,
                 () -> mBpfNetMaps.removeNaughtyApp(TEST_UID));
     }
+
+    private void doTestAddNaughtyApp(final long iif, final long match) throws Exception {
+        if (match != NO_MATCH) {
+            mUidOwnerMap.updateEntry(new U32(TEST_UID), new UidOwnerValue(iif, match));
+        }
+
+        mBpfNetMaps.addNaughtyApp(TEST_UID);
+
+        checkUidOwnerValue(TEST_UID, iif, match | PENALTY_BOX_MATCH);
+    }
+
+    @Test
+    @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+    public void testAddNaughtyApp() throws Exception {
+        doTestAddNaughtyApp(NO_IIF, NO_MATCH);
+
+        // Other matches are enabled
+        doTestAddNaughtyApp(NO_IIF, DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH);
+
+        // IIF_MATCH is enabled
+        doTestAddNaughtyApp(TEST_IF_INDEX, IIF_MATCH);
+
+        // PENALTY_BOX_MATCH is already enabled
+        doTestAddNaughtyApp(NO_IIF, PENALTY_BOX_MATCH | DOZABLE_MATCH);
+    }
+
+    @Test
+    @IgnoreAfter(Build.VERSION_CODES.S_V2)
+    public void testAddNaughtyAppBeforeT() {
+        assertThrows(UnsupportedOperationException.class,
+                () -> mBpfNetMaps.addNaughtyApp(TEST_UID));
+    }
 }