Merge "Address warnings in TestableNetworkCallback" into main
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index 13a7a22..d1cc79d 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -16,7 +16,7 @@
package com.android.networkstack.tethering;
-import static com.android.net.module.util.netlink.NetlinkUtils.SOCKET_RECV_BUFSIZE;
+import static com.android.net.module.util.netlink.NetlinkUtils.SOCKET_DUMP_RECV_BUFSIZE;
import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_DUMP;
import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
@@ -200,7 +200,7 @@
final FileDescriptor fd;
try {
fd = NetlinkUtils.netlinkSocketForProto(OsConstants.NETLINK_NETFILTER,
- SOCKET_RECV_BUFSIZE);
+ SOCKET_DUMP_RECV_BUFSIZE);
} catch (ErrnoException e) {
mLog.e("Unable to create conntrack socket " + e);
return null;
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 4bbe130..771a9ff 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -149,6 +149,7 @@
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.FrameworkConnectivityStatsLog;
import com.android.net.module.util.HandlerUtils;
import com.android.net.module.util.NetdUtils;
import com.android.net.module.util.RoutingCoordinatorManager;
@@ -1718,6 +1719,12 @@
// After T, tethering always trust the iface pass by state change intent. This allow
// tethering to deprecate tetherable p2p regexs after T.
final int type = SdkLevel.isAtLeastT() ? TETHERING_WIFI_P2P : ifaceNameToType(ifname);
+ if (type != TETHERING_WIFI_P2P) {
+ FrameworkConnectivityStatsLog.write(
+ FrameworkConnectivityStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
+ FrameworkConnectivityStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_TETHER_WIFIP2P_TYPE_MISMATCH);
+ }
+
if (!checkTetherableType(type)) {
mLog.e(ifname + " is not a tetherable iface, ignoring");
return;
@@ -1768,6 +1775,11 @@
mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode);
return;
}
+ if (type != TETHERING_WIFI) {
+ FrameworkConnectivityStatsLog.write(
+ FrameworkConnectivityStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED,
+ FrameworkConnectivityStatsLog.CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED__ERROR_TYPE__TYPE_TETHER_WIFI_TYPE_MISMATCH);
+ }
// After T, tethering always trust the iface pass by state change intent. This allow
// tethering to deprecate tetherable wifi regexs after T.
diff --git a/bpf/headers/include/bpf_helpers.h b/bpf/headers/include/bpf_helpers.h
index fe64538..8526745 100644
--- a/bpf/headers/include/bpf_helpers.h
+++ b/bpf/headers/include/bpf_helpers.h
@@ -155,22 +155,45 @@
// Helpers for writing sdk level specific bpf programs
//
-// Note: we choose to follow sdk api level values, but there is no real need for this:
-// These just need to be monotonically increasing. We could also use values ten or even
-// a hundred times larger to leave room for quarters or months. We may also just use
-// dates or something (2502 or 202506 for 25Q2) or even the mainline bpfloader version...
+// Note: we choose to follow 'ro.build.version.sdk_full'
+// (or just 'sdk' if 'sdk_full' is not available) values,
+// multiplied by 100, with 1 added per QPR.
+// This will (eventually) match our bpfloader versioning scheme.
+//
+// This is just for ease of use, really these are only
+// ever compared to each other, so they only need to be
+// monotonically increasing.
+//
// For now this easily suffices for our use case.
+//
+// Note: 24Q1 is the first trunk stable release,
+// and thus where quarters start possibly mattering.
+//
+// We leave most of these as commented out documentation,
+// as it's probably a bad idea to actually use them.
struct sdk_level_uint { unsigned int sdk_level; };
#define SDK_LEVEL_(v) ((struct sdk_level_uint){ .sdk_level = (v) })
-#define SDK_LEVEL_NONE SDK_LEVEL_(0)
-#define SDK_LEVEL_S SDK_LEVEL_(31) // Android 12
-#define SDK_LEVEL_Sv2 SDK_LEVEL_(32) // Android 12L
-#define SDK_LEVEL_T SDK_LEVEL_(33) // Android 13
-#define SDK_LEVEL_U SDK_LEVEL_(34) // Android 14
-#define SDK_LEVEL_V SDK_LEVEL_(35) // Android 15
-#define SDK_LEVEL_24Q3 SDK_LEVEL_V
-#define SDK_LEVEL_25Q2 SDK_LEVEL_(36) // Android 16
+// SDK_LEVEL_NONE SDK_LEVEL_(0) // mainline implies S+
+#define SDK_LEVEL_S SDK_LEVEL_(3100) // Android 12 [31]
+// SDK_LEVEL_Sv2 SDK_LEVEL_(3200) // Android 12L [32]
+#define SDK_LEVEL_T SDK_LEVEL_(3300) // Android 13 [33]
+#define SDK_LEVEL_U SDK_LEVEL_(3400) // Android 14/U [34]
+// SDK_LEVEL_U_QPR1 SDK_LEVEL_(3401) // Android 14/U QPR1
+// SDK_LEVEL_24Q1 SDK_LEVEL_(3402) // Android 14/U QPR2
+// SDK_LEVEL_24Q2 SDK_LEVEL_(3403) // Android 14/U QPR3
+#define SDK_LEVEL_24Q3 SDK_LEVEL_(3500) // Android 15/V [35]
+// SDK_LEVEL_24Q4 SDK_LEVEL_(3501) // Android 15/V QPR1
+// SDK_LEVEL_25Q1 SDK_LEVEL_(3502) // Android 15/V QPR2
+#define SDK_LEVEL_25Q2 SDK_LEVEL_(3600) // Android 16 (B) [36.0]
+// SDK_LEVEL_25Q3 SDK_LEVEL_(3601) // Android 16 QPR
+#define SDK_LEVEL_25Q4 SDK_LEVEL_(3610) // Android 16.1 [36.1]
+// SDK_LEVEL_26Q1 SDK_LEVEL_(3611) // Android 16.1 QPR
+#define SDK_LEVEL_26Q2 SDK_LEVEL_(3700) // Android 17 (C) [37.0]
+// SDK_LEVEL_26Q3 SDK_LEVEL_(3701) // Android 17 QPR
+#define SDK_LEVEL_26Q4 SDK_LEVEL_(3710) // Android 17.1 [37.1]
+// SDK_LEVEL_27Q1 SDK_LEVEL_(3711) // Android 17.1 QPR
+#define SDK_LEVEL_27Q2 SDK_LEVEL_(3800) // Android 18 [38.0]
#define SDK_LEVEL_IS_AT_LEAST(lvl, v) ((lvl).sdk_level >= (SDK_LEVEL_##v).sdk_level)
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 07375c7..0a74857 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -4175,27 +4175,27 @@
// Since mApps in PermissionMonitor needs to be populated first to ensure that
// listening network request which is sent by MultipathPolicyTracker won't be added
// NET_CAPABILITY_FOREGROUND capability. Thus, MultipathPolicyTracker.start() must
- // be called after PermissionMonitor#startMonitoring().
- // Calling PermissionMonitor#startMonitoring() in systemReadyInternal() and the
+ // be called after PermissionMonitor#initialize().
+ // Calling PermissionMonitor#initialize() in systemReadyInternal() and the
// MultipathPolicyTracker.start() is called in NetworkPolicyManagerService#systemReady()
// to ensure the tracking will be initialized correctly.
- final ConditionVariable startMonitoringDone = new ConditionVariable();
+ final ConditionVariable permissionMonitorInitializeDone = new ConditionVariable();
mHandler.post(() -> {
mPermissionMonitor.initialize();
// Calling mBroadcastReceiveHelper.callCallbackForInitialUsers() after
- // PermissionMonitor.startMonitoring() ensures that the internal lists
+ // PermissionMonitor#initialize() ensures that the internal lists
// (mUidsAllowedOnRestrictedNetworks and mUsersTrafficPermissions) in
// PermissionMonitor are prepared before processing initial users.
// While technically the onUserAdded callback (triggered by
// callCallbackForInitialUsers) handles sending network and traffic
// permissions to netd and bpf, which depend on these lists, moving
- // this call before startMonitoring would necessitate performing these
- // actions again within startMonitoring, leading to redundant work.
+ // this call before initialize would necessitate performing these
+ // actions again within initialize, leading to redundant work.
// Therefore, keeping callCallbackForInitialUsers() in this order is the
// safest approach to avoid duplicated operations and ensure the
// permission lists are ready when the initial user callbacks are invoked.
mBroadcastReceiveHelper.callOnUserAddedForExistingUsers();
- startMonitoringDone.open();
+ permissionMonitorInitializeDone.open();
});
mProxyTracker.loadGlobalProxy();
registerDnsResolverUnsolicitedEventListener();
@@ -4239,9 +4239,9 @@
CONNECTIVITY_STATE_SAMPLE, this::sampleConnectivityStateToStatsEvent);
// Wait PermissionMonitor to finish the permission update. Then MultipathPolicyTracker won't
// have permission problem. While CV#block() is unbounded in time and can in principle block
- // forever, this replaces a synchronous call to PermissionMonitor#startMonitoring, which
+ // forever, this replaces a synchronous call to PermissionMonitor#initialize, which
// could have blocked forever too.
- startMonitoringDone.block();
+ permissionMonitorInitializeDone.block();
}
/**
diff --git a/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java b/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java
index 60d27c3..9b15728 100644
--- a/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java
+++ b/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java
@@ -20,6 +20,7 @@
import static android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI;
import static android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TargetApi;
@@ -52,6 +53,8 @@
import com.android.net.module.util.DeviceConfigUtils;
import com.android.net.module.util.HandlerUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
@@ -87,10 +90,23 @@
}
}
- private enum AvoidBadWifiSource {
- FROM_RESOURCE,
- FROM_CARRIER_CONFIG,
- }
+ /**
+ * Indicates that the "Avoid Bad Wi-Fi" setting originates from a resource.
+ */
+ private static final int FROM_RESOURCE = 0;
+
+ /**
+ * Indicates that the "Avoid Bad Wi-Fi" setting originates from carrier configuration.
+ */
+ private static final int FROM_CARRIER_CONFIG = 1;
+
+ /**
+ * Defines the set of possible integer constants for AvoidBadWifiSource.
+ * This annotation provides compile-time type safety.
+ */
+ @IntDef({FROM_RESOURCE, FROM_CARRIER_CONFIG})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AvoidBadWifiSource {}
private static String TAG = MultinetworkPolicyTracker.class.getSimpleName();
@@ -105,8 +121,7 @@
private final ContentResolver mResolver;
private final SettingObserver mSettingObserver;
private final BroadcastReceiver mBroadcastReceiver;
- private final boolean mAvoidBadWifiFromCarrierConfigFeature;
- private final boolean mHasTelephonySubscription;
+ private final @AvoidBadWifiSource int mAvoidBadWifiSource;
// This will be null if the FLAG_AVOID_BAD_WIFI_FROM_CARRIER_CONFIG is off
private final @Nullable CarrierConfigManager mCarrierConfigManager;
private final @Nullable CarrierConfigChangeListener mCarrierConfigChangeListener;
@@ -162,15 +177,19 @@
@VisibleForTesting
protected boolean readAvoidBadWifiFromCarrierConfig(
- @NonNull final Context context, final int subId) {
+ @Nullable final CarrierConfigManager ccm, final int subId) {
// Defaults to true to avoid potentially poor Wi-Fi and improve user experience.
final boolean defaultConfig = true;
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return defaultConfig;
}
+ // It implies the FEATURE_TELEPHONY_SUBSCRIPTION is not supported, return default config
+ if (ccm == null) {
+ return defaultConfig;
+ }
+
PersistableBundle config = null;
- final CarrierConfigManager ccm = context.getSystemService(CarrierConfigManager.class);
try {
config = ccm.getConfigForSubId(subId,
@@ -271,18 +290,17 @@
}
};
- mHasTelephonySubscription =
- mContext.getPackageManager().hasSystemFeature(FEATURE_TELEPHONY_SUBSCRIPTION);
- mAvoidBadWifiFromCarrierConfigFeature = mDeps.getAvoidBadWifiFromCarrierConfigFeature();
- mCarrierConfigManager = mAvoidBadWifiFromCarrierConfigFeature
- ? mContext.getSystemService(CarrierConfigManager.class)
- : null;
-
- mCarrierConfigChangeListener = mAvoidBadWifiFromCarrierConfigFeature
- ? new CarrierConfigChangeListener()
- : null;
-
- if (!mAvoidBadWifiFromCarrierConfigFeature) {
+ if (mDeps.getAvoidBadWifiFromCarrierConfigFeature()) {
+ mAvoidBadWifiSource = FROM_CARRIER_CONFIG;
+ mCarrierConfigManager =
+ mContext.getPackageManager().hasSystemFeature(FEATURE_TELEPHONY_SUBSCRIPTION)
+ ? mContext.getSystemService(CarrierConfigManager.class)
+ : null;
+ mCarrierConfigChangeListener = new CarrierConfigChangeListener();
+ } else {
+ mAvoidBadWifiSource = FROM_RESOURCE;
+ mCarrierConfigManager = null;
+ mCarrierConfigChangeListener = null;
updateAvoidBadWifi();
updateMeteredMultipathPreference();
}
@@ -304,7 +322,7 @@
mContext.getSystemService(TelephonyManager.class).registerTelephonyCallback(
handlerExecutor, new ActiveDataSubscriptionIdListener());
- if (mAvoidBadWifiFromCarrierConfigFeature) {
+ if (mCarrierConfigManager != null) {
mCarrierConfigManager.registerCarrierConfigChangeListener(
BackgroundThread.getExecutor(), mCarrierConfigChangeListener
);
@@ -325,7 +343,7 @@
mResolver.unregisterContentObserver(mSettingObserver);
mContext.unregisterReceiver(mBroadcastReceiver);
- if (mAvoidBadWifiFromCarrierConfigFeature) {
+ if (mCarrierConfigManager != null) {
mCarrierConfigManager.unregisterCarrierConfigChangeListener(
mCarrierConfigChangeListener
);
@@ -463,18 +481,6 @@
}
/**
- * Determines the source of the avoid bad Wi-Fi setting.
- * It returns FROM_CARRIER_CONFIG if the carrier config feature is enabled,
- * otherwise it returns FROM_RESOURCE.
- *
- */
- private AvoidBadWifiSource getAvoidBadWifiSource() {
- return mAvoidBadWifiFromCarrierConfigFeature
- ? AvoidBadWifiSource.FROM_CARRIER_CONFIG
- : AvoidBadWifiSource.FROM_RESOURCE;
- }
-
- /**
* Updates the local cache of the "avoid bad Wi-Fi" setting from the carrier config
* for a specific subscription ID.
* Must be called on the handler thread.
@@ -502,8 +508,8 @@
// CarrierConfigManager#getConfigForSubId() is supported
// only when system has FEATURE_TELEPHONY_SUBSCRIPTION
- final boolean config = !mHasTelephonySubscription
- || mDeps.readAvoidBadWifiFromCarrierConfig(mContext, subId);
+ final boolean config =
+ mDeps.readAvoidBadWifiFromCarrierConfig(mCarrierConfigManager, subId);
mHandler.post(() -> updateAvoidBadWifiFromCarrierConfig(subId, config));
}
@@ -528,33 +534,35 @@
*/
public boolean updateAvoidBadWifi() {
final boolean prevAvoid = mAvoidBadWifi;
- if (getAvoidBadWifiSource() == AvoidBadWifiSource.FROM_CARRIER_CONFIG) {
- // Force update activelyPreferBadWifi since it will always be true in Android U+,
- // and mAvoidBadWifiFromCarrierConfigFeature is a trunk stable flag
- // that only exists in 25Q4+
- mActivelyPreferBadWifi = true;
-
- final String settingAvoidBadWifiStr = readAvoidBadWifiFromSettings();
- if (settingAvoidBadWifiStr != null) {
- mAvoidBadWifi = "1".equals(settingAvoidBadWifiStr);
- } else {
- // Retrieve the avoid bad Wi-Fi setting from the local cache to avoid potential
- // issues or blocking from the IPC call getAvoidBadWifiCarrierConfigForSubId().
- mAvoidBadWifi = readAvoidBadWifiFromCache(mActiveSubId);
- }
- return mAvoidBadWifi != prevAvoid;
- } else {
- final boolean settingAvoidBadWifi = "1".equals(readAvoidBadWifiFromSettings());
- mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi();
- final boolean prevActive = mActivelyPreferBadWifi;
- final Boolean deviceConfigPreferBadWifi = deviceConfigActivelyPreferBadWifi();
- if (null == deviceConfigPreferBadWifi) {
- mActivelyPreferBadWifi = configActivelyPrefersBadWifi();
- } else {
- mActivelyPreferBadWifi = deviceConfigPreferBadWifi;
- }
-
- return mAvoidBadWifi != prevAvoid || mActivelyPreferBadWifi != prevActive;
+ switch (mAvoidBadWifiSource) {
+ case FROM_CARRIER_CONFIG:
+ // Force update activelyPreferBadWifi since it will always be true in Android U+,
+ // and mAvoidBadWifiFromCarrierConfigFeature is a trunk stable flag
+ // that only exists in 25Q4+
+ mActivelyPreferBadWifi = true;
+ final String settingAvoidBadWifiStr = readAvoidBadWifiFromSettings();
+ if (settingAvoidBadWifiStr != null) {
+ mAvoidBadWifi = "1".equals(settingAvoidBadWifiStr);
+ } else {
+ // Retrieve the avoid bad Wi-Fi setting from the local cache to avoid potential
+ // issues or blocking from the IPC call getAvoidBadWifiCarrierConfigForSubId().
+ mAvoidBadWifi = readAvoidBadWifiFromCache(mActiveSubId);
+ }
+ return mAvoidBadWifi != prevAvoid;
+ case FROM_RESOURCE:
+ final boolean settingAvoidBadWifi = "1".equals(readAvoidBadWifiFromSettings());
+ mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi();
+ final boolean prevActive = mActivelyPreferBadWifi;
+ final Boolean deviceConfigPreferBadWifi = deviceConfigActivelyPreferBadWifi();
+ if (null == deviceConfigPreferBadWifi) {
+ mActivelyPreferBadWifi = configActivelyPrefersBadWifi();
+ } else {
+ mActivelyPreferBadWifi = deviceConfigPreferBadWifi;
+ }
+ return mAvoidBadWifi != prevAvoid || mActivelyPreferBadWifi != prevActive;
+ default:
+ Log.wtf(TAG, "Unexpected avoid bad Wi-Fi source: " + mAvoidBadWifiSource);
+ return false;
}
}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java b/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
index a999306..1c642ae 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/NetlinkUtils.java
@@ -87,7 +87,7 @@
public static final int DEFAULT_RECV_BUFSIZE = 8 * 1024;
public static final int SOCKET_RECV_BUFSIZE = 64 * 1024;
- public static final int SOCKET_DUMP_RECV_BUFSIZE = 128 * 1024;
+ public static final int SOCKET_DUMP_RECV_BUFSIZE = 1024 * 1024;
/**
* Return whether the input ByteBuffer contains enough remaining bytes for
diff --git a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
index 95a6d8c..ca0a136 100644
--- a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
@@ -49,16 +49,19 @@
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
+import org.junit.Assume.assumeNotNull
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.any
import org.mockito.Mockito.doCallRealMethod
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
+import org.mockito.Mockito.reset
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
@@ -74,6 +77,17 @@
@SmallTest
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class MultinetworkPolicyTrackerTest {
+ companion object {
+ @Parameterized.Parameters
+ @JvmStatic
+ fun data(): Iterable<Any?> {
+ return mutableListOf(
+ null,
+ mock(CarrierConfigManager::class.java)
+ )
+ }
+ }
+
// This wrapper class prevents JUnit from attempting to load unsupported system classes
// that are present in the System Test (S/T) image, which would otherwise cause test failures.
private class CarrierConfigChangeRunner(
@@ -97,6 +111,11 @@
private val featureFlags = HashSet<String>()
+ // Indicates where carrierConfigManager is supported.
+ @Parameterized.Parameter(0)
+ @JvmField
+ var carrierConfigManager: CarrierConfigManager? = null
+
// This will set feature flags from @FeatureFlag annotations
// into the map before setUp() runs.
@get:Rule
@@ -115,7 +134,6 @@
}
private val telephonyManager = mock(TelephonyManager::class.java)
- private val carrierConfigManager = mock(CarrierConfigManager::class.java)
private val subscriptionManager = mock(SubscriptionManager::class.java).also {
doReturn(null).`when`(it).getActiveSubscriptionInfo(anyInt())
}
@@ -135,8 +153,6 @@
}
doReturn(subscriptionManager).`when`(it)
.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
- doReturn(carrierConfigManager).`when`(it)
- .getSystemService(CarrierConfigManager::class.java)
doReturn(resolver).`when`(it).contentResolver
doReturn(resources).`when`(it).resources
doReturn(it).`when`(it).createConfigurationContext(any())
@@ -206,6 +222,8 @@
featureFlags.contains(FLAG_AVOID_BAD_WIFI_FROM_CARRIER_CONFIG)
)
+ doReturn(carrierConfigManager).`when`(context)
+ .getSystemService(CarrierConfigManager::class.java)
trackerDependencies.setBackgroundThreadHandler(bgHandler)
tracker = MultinetworkPolicyTracker(
context,
@@ -219,6 +237,9 @@
@After
fun tearDown() {
ConnectivityResources.setResourcesContextForTest(null)
+ carrierConfigManager?.let { ccm ->
+ reset(ccm)
+ }
trackerDependencies.resetAvoidBadWifiCarrierConfigForSubIdMap()
}
@@ -326,6 +347,8 @@
@FeatureFlag(name = FLAG_AVOID_BAD_WIFI_FROM_CARRIER_CONFIG, true)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
fun testUpdateAvoidBadWifiOnCarrierConfigChange() {
+ assumeNotNull("skip test if carrierConfigManager is not supported", carrierConfigManager)
+
// Mock the initial global setting to null
Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, null)
@@ -346,7 +369,7 @@
// Mock the initial carrier configuration to return false
trackerDependencies.setAvoidBadWifiCarrierConfigForSubId(activeSubId, false)
verify(carrierConfigManager, times(1))
- .registerCarrierConfigChangeListener(any(), carrierConfiglistenCaptor.capture())
+ ?.registerCarrierConfigChangeListener(any(), carrierConfiglistenCaptor.capture())
val carrierConfiglistener = carrierConfiglistenCaptor.value
// dispatch for the first carrier config initialization on the handler thread
diff --git a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt
index 7285cbe..dc2ace4 100644
--- a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt
+++ b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt
@@ -1,11 +1,11 @@
package com.android.server.connectivity
-import android.content.Context
import android.content.res.Resources
import android.os.Handler
import android.provider.DeviceConfig
import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY
import android.provider.DeviceConfig.OnPropertiesChangedListener
+import android.telephony.CarrierConfigManager
import com.android.internal.annotations.GuardedBy
import com.android.internal.os.BackgroundThread
import com.android.server.connectivity.MultinetworkPolicyTracker.CONFIG_ACTIVELY_PREFER_BAD_WIFI
@@ -72,7 +72,7 @@
resources
override fun readAvoidBadWifiFromCarrierConfig(
- context: Context,
+ ccm: CarrierConfigManager?,
subId: Int
): Boolean =
avoidBadWifiCarrierConfigForSubIdMap.getOrDefault(subId, true)