Merge "Revert^2 "Refactor ApfFilter constructor"" into main am: c64433c6cd am: 150192a006

Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/3170139

Change-Id: I880b6bcec9004ad62e4b970f6f6cc519d15bd7d7
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java
index 4f81f41..dd55165 100644
--- a/src/android/net/apf/ApfFilter.java
+++ b/src/android/net/apf/ApfFilter.java
@@ -276,7 +276,7 @@
     public final int mApfVersionSupported;
     @VisibleForTesting
     @NonNull
-    public byte[] mHardwareAddress;
+    public final byte[] mHardwareAddress;
     @VisibleForTesting
     public ReceiveThread mReceiveThread;
     @GuardedBy("this")
@@ -446,14 +446,15 @@
         // 3 seconds.
         mTokenBucket = new TokenBucket(3_000 /* deltaMs */, 20 /* capacity */, 20 /* tokens */);
 
+        mHardwareAddress = mInterfaceParams.macAddr.toByteArray();
         // TODO: ApfFilter should not generate programs until IpClient sends provisioning success.
-        maybeStartFilter();
+        startFilter();
 
         // Listen for doze-mode transition changes to enable/disable the IPv6 multicast filter.
         mDependencies.addDeviceIdleReceiver(mDeviceIdleReceiver);
 
         mDependencies.onApfFilterCreated(this);
-        // mReceiveThread is created in maybeStartFilter() and halted in shutdown().
+        // mReceiveThread is created in startFilter() and halted in shutdown().
         mDependencies.onThreadCreated(mReceiveThread);
     }
 
@@ -605,30 +606,29 @@
      * filters to ignore useless RAs.
      */
     @VisibleForTesting
-    public void maybeStartFilter() {
+    public void startFilter() {
+        synchronized (this) {
+            // Clear the APF memory to reset all counters upon connecting to the first AP
+            // in an SSID. This is limited to APFv3 devices because this large write triggers
+            // a crash on some older devices (b/78905546).
+            if (hasDataAccess(mApfVersionSupported)) {
+                byte[] zeroes = new byte[mApfRamSize];
+                if (!mIpClientCallback.installPacketFilter(zeroes)) {
+                    sendNetworkQuirkMetrics(NetworkQuirkEvent.QE_APF_INSTALL_FAILURE);
+                }
+            }
+
+            // Install basic filters
+            installNewProgramLocked();
+        }
         FileDescriptor socket;
         try {
-            mHardwareAddress = mInterfaceParams.macAddr.toByteArray();
-            synchronized(this) {
-                // Clear the APF memory to reset all counters upon connecting to the first AP
-                // in an SSID. This is limited to APFv4 devices because this large write triggers
-                // a crash on some older devices (b/78905546).
-                if (mIsRunning && hasDataAccess(mApfVersionSupported)) {
-                    byte[] zeroes = new byte[mApfRamSize];
-                    if (!mIpClientCallback.installPacketFilter(zeroes)) {
-                        sendNetworkQuirkMetrics(NetworkQuirkEvent.QE_APF_INSTALL_FAILURE);
-                    }
-                }
-
-                // Install basic filters
-                installNewProgramLocked();
-            }
             socket = Os.socket(AF_PACKET, SOCK_RAW | SOCK_CLOEXEC, 0);
             NetworkStackUtils.attachRaFilter(socket);
             SocketAddress addr = makePacketSocketAddress(ETH_P_IPV6, mInterfaceParams.index);
             Os.bind(socket, addr);
         } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error starting filter", e);
+            Log.wtf(TAG, "Error starting filter", e);
             return;
         }
         mReceiveThread = new ReceiveThread(socket);
diff --git a/tests/unit/src/android/net/apf/ApfFilterTest.kt b/tests/unit/src/android/net/apf/ApfFilterTest.kt
index 5e1f6d5..d9bc6ab 100644
--- a/tests/unit/src/android/net/apf/ApfFilterTest.kt
+++ b/tests/unit/src/android/net/apf/ApfFilterTest.kt
@@ -1183,4 +1183,13 @@
         apfFilter.setLinkProperties(lp)
         verify(ipClientCallback, times(5)).installPacketFilter(any())
     }
+
+    @Test
+    fun testApfFilterInitializationCleanUpTheApfMemoryRegion() {
+        val apfFilter = getApfFilter()
+        val programCaptor = ArgumentCaptor.forClass(ByteArray::class.java)
+        verify(ipClientCallback, times(2)).installPacketFilter(programCaptor.capture())
+        val program = programCaptor.allValues.first()
+        assertContentEquals(ByteArray(4096) { 0 }, program)
+    }
 }
diff --git a/tests/unit/src/android/net/apf/ApfTestUtils.java b/tests/unit/src/android/net/apf/ApfTestUtils.java
index 0b3ea65..e2a1b55 100644
--- a/tests/unit/src/android/net/apf/ApfTestUtils.java
+++ b/tests/unit/src/android/net/apf/ApfTestUtils.java
@@ -28,6 +28,7 @@
 import android.content.Context;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
+import android.net.MacAddress;
 import android.net.apf.BaseApfGenerator.IllegalInstructionException;
 import android.net.ip.IIpClientCallbacks;
 import android.net.ip.IpClient;
@@ -294,6 +295,8 @@
         public static final byte[] MOCK_MAC_ADDR = {2, 3, 4, 5, 6, 7};
         private static final byte[] MOCK_IPV4_ADDR = {10, 0, 0, 1};
 
+        private static final InterfaceParams LOCAL_PARAMS = InterfaceParams.getByName("lo");
+
         private FileDescriptor mWriteSocket;
         private long mCurrentTimeMs = SystemClock.elapsedRealtime();
         private final MockIpClientCallback mMockIpClientCb;
@@ -325,7 +328,8 @@
                 MockIpClientCallback ipClientCallback, NetworkQuirkMetrics networkQuirkMetrics,
                 Dependencies dependencies, boolean throwsExceptionWhenGeneratesProgram,
                 ApfFilter.Clock clock) throws Exception {
-            super(context, config, InterfaceParams.getByName("lo"), ipClientCallback,
+            super(context, config, new InterfaceParams("lo", LOCAL_PARAMS.index,
+                            MacAddress.fromBytes(MOCK_MAC_ADDR)), ipClientCallback,
                     networkQuirkMetrics, dependencies, clock);
             mMockIpClientCb = ipClientCallback;
             mThrowsExceptionWhenGeneratesProgram = throwsExceptionWhenGeneratesProgram;
@@ -369,8 +373,7 @@
         }
 
         @Override
-        public synchronized void maybeStartFilter() {
-            mHardwareAddress = MOCK_MAC_ADDR;
+        public synchronized void startFilter() {
             installNewProgramLocked();
 
             // Create two sockets, "readSocket" and "mWriteSocket" and connect them together.