Update error handling in BpfNetMaps

Address review comments from aosp/2117045
Throw AssertionError if bpf map init get error
Update tests to avoid getting AssertionError

Bug: 217624062
Test: atest BpfNetMapsTest
Change-Id: I2194b825aa73b88d5334077d17acb9abbd367c69
diff --git a/service-t/src/com/android/server/net/NetworkStatsFactory.java b/service-t/src/com/android/server/net/NetworkStatsFactory.java
index 3b93f1a..b628251 100644
--- a/service-t/src/com/android/server/net/NetworkStatsFactory.java
+++ b/service-t/src/com/android/server/net/NetworkStatsFactory.java
@@ -164,16 +164,17 @@
     }
 
     public NetworkStatsFactory(@NonNull Context ctx) {
-        this(ctx, new File("/proc/"), true);
+        this(ctx, new File("/proc/"), true, new BpfNetMaps());
     }
 
     @VisibleForTesting
-    public NetworkStatsFactory(@NonNull Context ctx, File procRoot, boolean useBpfStats) {
+    public NetworkStatsFactory(@NonNull Context ctx, File procRoot, boolean useBpfStats,
+            BpfNetMaps bpfNetMaps) {
         mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
         mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
         mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
         mUseBpfStats = useBpfStats;
-        mBpfNetMaps = new BpfNetMaps();
+        mBpfNetMaps = bpfNetMaps;
         synchronized (mPersistentDataLock) {
             mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
             mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 6e107c2..5650e31 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -49,10 +49,16 @@
  * {@hide}
  */
 public class BpfNetMaps {
+    private static final boolean PRE_T = !SdkLevel.isAtLeastT();
+    static {
+        if (!PRE_T) {
+            System.loadLibrary("service-connectivity");
+        }
+    }
+
     private static final String TAG = "BpfNetMaps";
     private final INetd mNetd;
     // Use legacy netd for releases before T.
-    private static final boolean PRE_T = !SdkLevel.isAtLeastT();
     private static boolean sInitialized = false;
 
     // Lock for sConfigurationMap entry for UID_RULES_CONFIGURATION_KEY.
@@ -98,11 +104,26 @@
     }
 
     /**
-     * Only tests or BpfNetMaps#ensureInitialized can call this function.
+     * Set configurationMap for test.
      */
     @VisibleForTesting
-    public static void initialize(final Dependencies deps) {
-        sConfigurationMap = deps.getConfigurationMap();
+    public static void setConfigurationMapForTest(BpfMap<U32, U32> configurationMap) {
+        sConfigurationMap = configurationMap;
+    }
+
+    private static BpfMap<U32, U32> getConfigurationMap() {
+        try {
+            return new BpfMap<>(
+                    CONFIGURATION_MAP_PATH, BpfMap.BPF_F_RDWR, U32.class, U32.class);
+        } catch (ErrnoException e) {
+            throw new IllegalStateException("Cannot open netd configuration map", e);
+        }
+    }
+
+    private static void setBpfMaps() {
+        if (sConfigurationMap == null) {
+            sConfigurationMap = getConfigurationMap();
+        }
     }
 
     /**
@@ -111,33 +132,11 @@
      */
     private static synchronized void ensureInitialized() {
         if (sInitialized) return;
-        if (!PRE_T) {
-            System.loadLibrary("service-connectivity");
-            native_init();
-            initialize(new Dependencies());
-        }
+        setBpfMaps();
+        native_init();
         sInitialized = true;
     }
 
-    /**
-     * Dependencies of BpfNetMaps, for injection in tests.
-     */
-    @VisibleForTesting
-    public static class Dependencies {
-        /**
-         *  Get configuration BPF map.
-         */
-        public BpfMap<U32, U32> getConfigurationMap() {
-            try {
-                return new BpfMap<>(
-                        CONFIGURATION_MAP_PATH, BpfMap.BPF_F_RDWR, U32.class, U32.class);
-            } catch (ErrnoException e) {
-                Log.e(TAG, "Cannot open netd configuration map: " + e);
-                return null;
-            }
-        }
-    }
-
     /** Constructor used after T that doesn't need to use netd anymore. */
     public BpfNetMaps() {
         this(null);
@@ -146,7 +145,9 @@
     }
 
     public BpfNetMaps(final INetd netd) {
-        ensureInitialized();
+        if (!PRE_T) {
+            ensureInitialized();
+        }
         mNetd = netd;
     }
 
diff --git a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 80338aa..efc24d3 100644
--- a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -47,6 +47,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.connectivity.resources.R
+import com.android.server.BpfNetMaps
 import com.android.server.ConnectivityService
 import com.android.server.NetworkAgentWrapper
 import com.android.server.TestNetIdManager
@@ -208,6 +209,7 @@
         doReturn(mock(ProxyTracker::class.java)).`when`(deps).makeProxyTracker(any(), any())
         doReturn(mock(MockableSystemProperties::class.java)).`when`(deps).systemProperties
         doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager()
+        doReturn(mock(BpfNetMaps::class.java)).`when`(deps).getBpfNetMaps(any())
         doAnswer { inv ->
             object : MultinetworkPolicyTracker(inv.getArgument(0), inv.getArgument(1),
                     inv.getArgument(2)) {
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index e9fad9b..689c148 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -85,24 +85,13 @@
     private BpfNetMaps mBpfNetMaps;
 
     @Mock INetd mNetd;
-    private static final TestBpfMap<U32, U32> sConfigurationMap =
-            new TestBpfMap<>(U32.class, U32.class);
+    private final BpfMap<U32, U32> mConfigurationMap = new TestBpfMap<>(U32.class, U32.class);
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        BpfNetMaps.setConfigurationMapForTest(mConfigurationMap);
         mBpfNetMaps = new BpfNetMaps(mNetd);
-        BpfNetMaps.initialize(makeDependencies());
-        sConfigurationMap.clear();
-    }
-
-    private static BpfNetMaps.Dependencies makeDependencies() {
-        return new BpfNetMaps.Dependencies() {
-            @Override
-            public BpfMap<U32, U32> getConfigurationMap() {
-                return sConfigurationMap;
-            }
-        };
     }
 
     @Test
@@ -121,7 +110,7 @@
         for (final int chain: enableChains) {
             match |= mBpfNetMaps.getMatchByFirewallChain(chain);
         }
-        sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(match));
+        mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(match));
 
         for (final int chain: FIREWALL_CHAINS) {
             final String testCase = "EnabledChains: " + enableChains + " CheckedChain: " + chain;
@@ -187,17 +176,17 @@
             expectedMatch |= mBpfNetMaps.getMatchByFirewallChain(chain);
         }
 
-        assertEquals(0, sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
+        assertEquals(0, mConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
 
         for (final int chain: testChains) {
             mBpfNetMaps.setChildChain(chain, true /* enable */);
         }
-        assertEquals(expectedMatch, sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
+        assertEquals(expectedMatch, mConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
 
         for (final int chain: testChains) {
             mBpfNetMaps.setChildChain(chain, false /* enable */);
         }
-        assertEquals(0, sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
+        assertEquals(0, mConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val);
     }
 
     private void doTestSetChildChain(final int testChain) throws Exception {
@@ -207,7 +196,7 @@
     @Test
     @IgnoreUpTo(Build.VERSION_CODES.S_V2)
     public void testSetChildChain() throws Exception {
-        sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
+        mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
         doTestSetChildChain(FIREWALL_CHAIN_DOZABLE);
         doTestSetChildChain(FIREWALL_CHAIN_STANDBY);
         doTestSetChildChain(FIREWALL_CHAIN_POWERSAVE);
@@ -221,7 +210,7 @@
     @Test
     @IgnoreUpTo(Build.VERSION_CODES.S_V2)
     public void testSetChildChainMultipleChain() throws Exception {
-        sConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
+        mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
         doTestSetChildChain(List.of(
                 FIREWALL_CHAIN_DOZABLE,
                 FIREWALL_CHAIN_STANDBY));
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
index 5400a00..f6fb45c 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -44,6 +44,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.frameworks.tests.net.R;
+import com.android.server.BpfNetMaps;
 import com.android.testutils.DevSdkIgnoreRule;
 import com.android.testutils.DevSdkIgnoreRunner;
 
@@ -74,6 +75,7 @@
     private File mTestProc;
     private NetworkStatsFactory mFactory;
     @Mock private Context mContext;
+    @Mock private BpfNetMaps mBpfNetMaps;
 
     @Before
     public void setUp() throws Exception {
@@ -84,7 +86,7 @@
         // applications. So in order to have a test support native library, the native code
         // related to networkStatsFactory is compiled to a minimal native library and loaded here.
         System.loadLibrary("networkstatsfactorytestjni");
-        mFactory = new NetworkStatsFactory(mContext, mTestProc, false);
+        mFactory = new NetworkStatsFactory(mContext, mTestProc, false, mBpfNetMaps);
         mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]);
     }