diff --git a/service-t/src/com/android/server/net/NetworkStatsFactory.java b/service-t/src/com/android/server/net/NetworkStatsFactory.java index b628251037..21d1a005b3 100644 --- a/service-t/src/com/android/server/net/NetworkStatsFactory.java +++ b/service-t/src/com/android/server/net/NetworkStatsFactory.java @@ -164,7 +164,7 @@ public class NetworkStatsFactory { } public NetworkStatsFactory(@NonNull Context ctx) { - this(ctx, new File("/proc/"), true, new BpfNetMaps()); + this(ctx, new File("/proc/"), true, new BpfNetMaps(ctx)); } @VisibleForTesting diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java index 0ff88102ac..3befd86458 100644 --- a/service/src/com/android/server/BpfNetMaps.java +++ b/service/src/com/android/server/BpfNetMaps.java @@ -31,9 +31,11 @@ import static android.system.OsConstants.ENODEV; import static android.system.OsConstants.ENOENT; import static android.system.OsConstants.EOPNOTSUPP; +import android.content.Context; import android.net.INetd; import android.os.RemoteException; import android.os.ServiceSpecificException; +import android.provider.DeviceConfig; import android.system.ErrnoException; import android.system.Os; import android.util.Log; @@ -42,6 +44,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.build.SdkLevel; import com.android.net.module.util.BpfMap; +import com.android.net.module.util.DeviceConfigUtils; import com.android.net.module.util.Struct.U32; import java.io.FileDescriptor; @@ -70,6 +73,10 @@ public class BpfNetMaps { // Use legacy netd for releases before T. private static boolean sInitialized = false; + private static Boolean sEnableJavaBpfMap = null; + private static final String BPF_NET_MAPS_ENABLE_JAVA_BPF_MAP = + "bpf_net_maps_enable_java_bpf_map"; + // Lock for sConfigurationMap entry for UID_RULES_CONFIGURATION_KEY. // This entry is not accessed by others. // BpfNetMaps acquires this lock while sequence of read, modify, and write. @@ -100,6 +107,14 @@ public class BpfNetMaps { @VisibleForTesting public static final long OEM_DENY_3_MATCH = (1 << 11); // LINT.ThenChange(packages/modules/Connectivity/bpf_progs/bpf_shared.h) + /** + * Set sEnableJavaBpfMap for test. + */ + @VisibleForTesting + public static void setEnableJavaBpfMapForTest(boolean enable) { + sEnableJavaBpfMap = enable; + } + /** * Set configurationMap for test. */ @@ -147,8 +162,15 @@ public class BpfNetMaps { * Initializes the class if it is not already initialized. This method will open maps but not * cause any other effects. This method may be called multiple times on any thread. */ - private static synchronized void ensureInitialized() { + private static synchronized void ensureInitialized(final Context context) { if (sInitialized) return; + if (sEnableJavaBpfMap == null) { + sEnableJavaBpfMap = DeviceConfigUtils.isFeatureEnabled(context, + DeviceConfig.NAMESPACE_TETHERING, BPF_NET_MAPS_ENABLE_JAVA_BPF_MAP, + SdkLevel.isAtLeastU() /* defaultValue */); + } + Log.d(TAG, "BpfNetMaps is initialized with sEnableJavaBpfMap=" + sEnableJavaBpfMap); + setBpfMaps(); native_init(); sInitialized = true; @@ -168,20 +190,20 @@ public class BpfNetMaps { } /** Constructor used after T that doesn't need to use netd anymore. */ - public BpfNetMaps() { - this(null); + public BpfNetMaps(final Context context) { + this(context, null); if (PRE_T) throw new IllegalArgumentException("BpfNetMaps need to use netd before T"); } - public BpfNetMaps(final INetd netd) { - this(netd, new Dependencies()); + public BpfNetMaps(final Context context, final INetd netd) { + this(context, netd, new Dependencies()); } @VisibleForTesting - public BpfNetMaps(final INetd netd, final Dependencies deps) { + public BpfNetMaps(final Context context, final INetd netd, final Dependencies deps) { if (!PRE_T) { - ensureInitialized(); + ensureInitialized(context); } mNetd = netd; mDeps = deps; diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index ae1f80854b..66bbea008a 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -1399,8 +1399,8 @@ public class ConnectivityService extends IConnectivityManager.Stub * @param netd * @return BpfNetMaps implementation. */ - public BpfNetMaps getBpfNetMaps(INetd netd) { - return new BpfNetMaps(netd); + public BpfNetMaps getBpfNetMaps(Context context, INetd netd) { + return new BpfNetMaps(context, netd); } /** @@ -1529,7 +1529,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mProxyTracker = mDeps.makeProxyTracker(mContext, mHandler); mNetd = netd; - mBpfNetMaps = mDeps.getBpfNetMaps(netd); + mBpfNetMaps = mDeps.getBpfNetMaps(mContext, netd); mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); mLocationPermissionChecker = mDeps.makeLocationPermissionChecker(mContext); 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 efc24d32dc..73e4c0ebd9 100644 --- a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt +++ b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt @@ -209,7 +209,7 @@ class ConnectivityServiceIntegrationTest { 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()) + doReturn(mock(BpfNetMaps::class.java)).`when`(deps).getBpfNetMaps(any(), 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 61d9eea23d..2d09bf2471 100644 --- a/tests/unit/java/com/android/server/BpfNetMapsTest.java +++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java @@ -46,6 +46,7 @@ import static org.junit.Assume.assumeFalse; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; +import android.content.Context; import android.net.INetd; import android.os.Build; import android.os.ServiceSpecificException; @@ -102,6 +103,7 @@ public final class BpfNetMapsTest { @Mock INetd mNetd; @Mock BpfNetMaps.Dependencies mDeps; + @Mock Context mContext; private final BpfMap mConfigurationMap = new TestBpfMap<>(U32.class, U32.class); private final BpfMap mUidOwnerMap = new TestBpfMap<>(U32.class, UidOwnerValue.class); @@ -110,9 +112,10 @@ public final class BpfNetMapsTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); doReturn(TEST_IF_INDEX).when(mDeps).getIfIndex(TEST_IF_NAME); + BpfNetMaps.setEnableJavaBpfMapForTest(true /* enable */); BpfNetMaps.setConfigurationMapForTest(mConfigurationMap); BpfNetMaps.setUidOwnerMapForTest(mUidOwnerMap); - mBpfNetMaps = new BpfNetMaps(mNetd, mDeps); + mBpfNetMaps = new BpfNetMaps(mContext, mNetd, mDeps); } @Test diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index 3264a366fd..62073cd4fc 100644 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -2061,7 +2061,7 @@ public class ConnectivityServiceTest { } @Override - public BpfNetMaps getBpfNetMaps(INetd netd) { + public BpfNetMaps getBpfNetMaps(Context context, INetd netd) { return mBpfNetMaps; }