Introduce carrier-aware avoid bad Wi-Fi APIs

This commit introduces new system APIs to manage "avoid bad Wi-Fi" settings,
leveraging both global system settings and carrier configurations. This
enhancement allows for more granular control and visibility into how Wi-Fi
networks are managed, especially in multi-SIM environments.

The new `setNetworkAvoidBadWifi(Context, int subId)` method provides
the ability to programmatically control this setting based on carrier-specific
policies or user preferences. This complements `getNetworkAvoidBadWifi(Context, int subId)`,
which allows querying the setting for a specific subscription ID, ensuring the
system can accurately determine the avoid bad Wi-Fi status.

Additionally, `shouldShowAvoidBadWifiToggle(Context, int subId)` is introduced.
This method determines whether the 'Avoid Bad Wi-Fi' user interface toggle
should be displayed. It considers both global settings and carrier configurations,
allowing for dynamic UI adjustments based on carrier requirements or user preferences.

These changes provide greater flexibility for managing Wi-Fi network selection
and improve the user experience by offering more context-aware control over
cellular behavior.

Deprecated APIs:
- `setNetworkAvoidBadWifi(Context, int value)`
- `getNetworkAvoidBadWifi(Context)`
New APIs:
- `setNetworkAvoidBadWifi(Context, int subId, int value)`
- `getNetworkAvoidBadWifi(Context, int subId)`
- `shouldShowAvoidBadWifiToggle(Context, int subId)`

Flag: com.android.net.flags.carrier_aware_avoid_bad_wifi
Bug: 410976315
Test: atest ConnectivityCoverageTests:android.net.connectivity.android.net.ConnectivitySettingsManagerTest
Change-Id: I79469cfe865a585593219d226c8198206c06b589
This commit is contained in:
Jimi Chen 2025-06-02 13:25:24 +00:00
commit 92e23acebb

View file

@ -28,6 +28,8 @@ import android.net.ConnectivitySettingsManager.DNS_RESOLVER_MIN_SAMPLES
import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS
import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT
import android.net.ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON
import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI
import android.net.ConnectivitySettingsManager.NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI
import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT
import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS
import android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE
@ -42,6 +44,7 @@ import android.net.ConnectivitySettingsManager.getDnsResolverSuccessThresholdPer
import android.net.ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond
import android.net.ConnectivitySettingsManager.getMobileDataActivityTimeout
import android.net.ConnectivitySettingsManager.getMobileDataAlwaysOn
import android.net.ConnectivitySettingsManager.getNetworkAvoidBadWifi
import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationMaximumDailyCount
import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationRateDuration
import android.net.ConnectivitySettingsManager.getPrivateDnsDefaultMode
@ -55,27 +58,42 @@ import android.net.ConnectivitySettingsManager.setDnsResolverSuccessThresholdPer
import android.net.ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond
import android.net.ConnectivitySettingsManager.setMobileDataActivityTimeout
import android.net.ConnectivitySettingsManager.setMobileDataAlwaysOn
import android.net.ConnectivitySettingsManager.setNetworkAvoidBadWifi
import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationMaximumDailyCount
import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationRateDuration
import android.net.ConnectivitySettingsManager.setPrivateDnsDefaultMode
import android.net.ConnectivitySettingsManager.setWifiAlwaysRequested
import android.net.ConnectivitySettingsManager.setWifiDataActivityTimeout
import android.net.ConnectivitySettingsManager.shouldShowAvoidBadWifiToggle
import android.os.Build
import android.os.PersistableBundle
import android.platform.test.annotations.AppModeFull
import android.provider.Settings
import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionManager
import android.util.Range
import androidx.test.InstrumentationRegistry
import androidx.test.filters.SmallTest
import com.android.net.module.util.ConnectivitySettingsUtils.convertCarrierAwareSettingsStringToMap
import com.android.net.module.util.ConnectivitySettingsUtils.getNetworkAvoidBadWifiSetting
import com.android.net.module.util.ConnectivitySettingsUtils.getNetworkLegacyGlobalAvoidBadWifiSetting
import com.android.net.module.util.ConnectivitySettingsUtils.getPrivateDnsModeAsString
import com.android.net.module.util.ConnectivitySettingsUtils.setNetworkAvoidBadWifiSetting
import com.android.net.module.util.ConnectivitySettingsUtils.setNetworkLegacyGlobalAvoidBadWifiSetting
import com.android.testutils.ConnectivityModuleTest
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
import junit.framework.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import com.android.testutils.com.android.testutils.CarrierConfigRule
import java.time.Duration
import java.util.Objects
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import kotlin.test.assertFailsWith
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
/**
* Tests for [ConnectivitySettingsManager].
@ -98,12 +116,15 @@ class ConnectivitySettingsManagerTest {
private val settingsTypeGlobal = "global"
private val settingsTypeSecure = "secure"
private val defaultSubId = SubscriptionManager.getDefaultSubscriptionId()
/*** Reset setting value or delete setting if the setting was not existed before testing. */
private fun resetSettings(names: Array<String>, type: String, values: Array<String?>) {
for (i in names.indices) {
if (Objects.equals(values[i], null)) {
instrumentation.uiAutomation.executeShellCommand(
"settings delete $type ${names[i]}")
"settings delete $type ${names[i]}"
)
} else {
if (settingsTypeSecure.equals(type)) {
Settings.Secure.putString(resolver, names[i], values[i])
@ -114,6 +135,18 @@ class ConnectivitySettingsManagerTest {
}
}
private fun assertAvoidBadWifiSettingEquals(expected: String?, setting: String?) {
// The conversion is necessary because the strings may not be in the same order.
assertEquals(
convertCarrierAwareSettingsStringToMap(
expected
),
convertCarrierAwareSettingsStringToMap(
setting
)
)
}
fun <T> testIntSetting(
names: Array<String>,
type: String,
@ -148,32 +181,67 @@ class ConnectivitySettingsManagerTest {
}
}
fun overrideAvoidBadWifiCarrierConfig(
avoidBadWifi: Boolean? = null,
showAvoidBadWifiToggle: Boolean? = null
) {
// Override carrier config to ignore entitlement check.
val bundle = PersistableBundle()
avoidBadWifi?.let { value ->
bundle.putBoolean(CarrierConfigManager.KEY_AVOID_BAD_WIFI_BOOL, value)
}
showAvoidBadWifiToggle?.let { value ->
bundle.putBoolean(CarrierConfigManager.KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL, value)
}
mCarrierConfigRule.addConfigOverrides(defaultSubId, bundle)
}
@get:Rule
val mCarrierConfigRule: CarrierConfigRule = CarrierConfigRule()
@get:Rule
val ignoreRule = DevSdkIgnoreRule()
@Test
fun testMobileDataActivityTimeout() {
testIntSetting(names = arrayOf(DATA_ACTIVITY_TIMEOUT_MOBILE), type = settingsTypeGlobal,
value1 = Duration.ofSeconds(testTime1), value2 = Duration.ofSeconds(testTime2),
getter = { getMobileDataActivityTimeout(context, defaultDuration) },
setter = { setMobileDataActivityTimeout(context, it) },
testIntValues = intArrayOf(testTime1.toInt()))
testIntSetting(
names = arrayOf(DATA_ACTIVITY_TIMEOUT_MOBILE),
type = settingsTypeGlobal,
value1 = Duration.ofSeconds(testTime1),
value2 = Duration.ofSeconds(testTime2),
getter = { getMobileDataActivityTimeout(context, defaultDuration) },
setter = { setMobileDataActivityTimeout(context, it) },
testIntValues = intArrayOf(testTime1.toInt())
)
}
@Test
fun testWifiDataActivityTimeout() {
testIntSetting(names = arrayOf(DATA_ACTIVITY_TIMEOUT_WIFI), type = settingsTypeGlobal,
value1 = Duration.ofSeconds(testTime1), value2 = Duration.ofSeconds(testTime2),
getter = { getWifiDataActivityTimeout(context, defaultDuration) },
setter = { setWifiDataActivityTimeout(context, it) },
testIntValues = intArrayOf(testTime1.toInt()))
testIntSetting(
names = arrayOf(DATA_ACTIVITY_TIMEOUT_WIFI),
type = settingsTypeGlobal,
value1 = Duration.ofSeconds(testTime1),
value2 = Duration.ofSeconds(testTime2),
getter = { getWifiDataActivityTimeout(context, defaultDuration) },
setter = { setWifiDataActivityTimeout(context, it) },
testIntValues = intArrayOf(testTime1.toInt())
)
}
@Test
fun testDnsResolverSampleValidityDuration() {
testIntSetting(names = arrayOf(DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS),
type = settingsTypeGlobal, value1 = Duration.ofSeconds(testTime1),
value2 = Duration.ofSeconds(testTime2),
getter = { getDnsResolverSampleValidityDuration(context, defaultDuration) },
setter = { setDnsResolverSampleValidityDuration(context, it) },
testIntValues = intArrayOf(testTime1.toInt()))
testIntSetting(
names = arrayOf(DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS),
type = settingsTypeGlobal,
value1 = Duration.ofSeconds(testTime1),
value2 = Duration.ofSeconds(testTime2),
getter = { getDnsResolverSampleValidityDuration(context, defaultDuration) },
setter = { setDnsResolverSampleValidityDuration(context, it) },
testIntValues = intArrayOf(testTime1.toInt())
)
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
setDnsResolverSampleValidityDuration(context, Duration.ofSeconds(-1L)) }
@ -181,11 +249,15 @@ class ConnectivitySettingsManagerTest {
@Test
fun testDnsResolverSuccessThresholdPercent() {
testIntSetting(names = arrayOf(DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT),
type = settingsTypeGlobal, value1 = 5, value2 = 10,
getter = { getDnsResolverSuccessThresholdPercent(context, 0 /* def */) },
setter = { setDnsResolverSuccessThresholdPercent(context, it) },
testIntValues = intArrayOf(5))
testIntSetting(
names = arrayOf(DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT),
type = settingsTypeGlobal,
value1 = 5,
value2 = 10,
getter = { getDnsResolverSuccessThresholdPercent(context, 0 /* def */) },
setter = { setDnsResolverSuccessThresholdPercent(context, it) },
testIntValues = intArrayOf(5)
)
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
setDnsResolverSuccessThresholdPercent(context, -1) }
@ -195,11 +267,15 @@ class ConnectivitySettingsManagerTest {
@Test
fun testDnsResolverSampleRanges() {
testIntSetting(names = arrayOf(DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_MAX_SAMPLES),
type = settingsTypeGlobal, value1 = Range(1, 63), value2 = Range(2, 62),
getter = { getDnsResolverSampleRanges(context) },
setter = { setDnsResolverSampleRanges(context, it) },
testIntValues = intArrayOf(1, 63))
testIntSetting(
names = arrayOf(DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_MAX_SAMPLES),
type = settingsTypeGlobal,
value1 = Range(1, 63),
value2 = Range(2, 62),
getter = { getDnsResolverSampleRanges(context) },
setter = { setDnsResolverSampleRanges(context, it) },
testIntValues = intArrayOf(1, 63)
)
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
setDnsResolverSampleRanges(context, Range(-1, 62)) }
@ -209,11 +285,15 @@ class ConnectivitySettingsManagerTest {
@Test
fun testNetworkSwitchNotificationMaximumDailyCount() {
testIntSetting(names = arrayOf(NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT),
type = settingsTypeGlobal, value1 = 5, value2 = 15,
getter = { getNetworkSwitchNotificationMaximumDailyCount(context, 0 /* def */) },
setter = { setNetworkSwitchNotificationMaximumDailyCount(context, it) },
testIntValues = intArrayOf(5))
testIntSetting(
names = arrayOf(NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT),
type = settingsTypeGlobal,
value1 = 5,
value2 = 15,
getter = { getNetworkSwitchNotificationMaximumDailyCount(context, 0 /* def */) },
setter = { setNetworkSwitchNotificationMaximumDailyCount(context, it) },
testIntValues = intArrayOf(5)
)
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
setNetworkSwitchNotificationMaximumDailyCount(context, -1) }
@ -221,12 +301,15 @@ class ConnectivitySettingsManagerTest {
@Test
fun testNetworkSwitchNotificationRateDuration() {
testIntSetting(names = arrayOf(NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS),
type = settingsTypeGlobal, value1 = Duration.ofMillis(testTime1),
value2 = Duration.ofMillis(testTime2),
getter = { getNetworkSwitchNotificationRateDuration(context, defaultDuration) },
setter = { setNetworkSwitchNotificationRateDuration(context, it) },
testIntValues = intArrayOf(testTime1.toInt()))
testIntSetting(
names = arrayOf(NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS),
type = settingsTypeGlobal,
value1 = Duration.ofMillis(testTime1),
value2 = Duration.ofMillis(testTime2),
getter = { getNetworkSwitchNotificationRateDuration(context, defaultDuration) },
setter = { setNetworkSwitchNotificationRateDuration(context, it) },
testIntValues = intArrayOf(testTime1.toInt())
)
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
setNetworkSwitchNotificationRateDuration(context, Duration.ofMillis(-1L)) }
@ -234,11 +317,15 @@ class ConnectivitySettingsManagerTest {
@Test
fun testCaptivePortalMode() {
testIntSetting(names = arrayOf(CAPTIVE_PORTAL_MODE), type = settingsTypeGlobal,
value1 = CAPTIVE_PORTAL_MODE_AVOID, value2 = CAPTIVE_PORTAL_MODE_PROMPT,
getter = { getCaptivePortalMode(context, CAPTIVE_PORTAL_MODE_IGNORE) },
setter = { setCaptivePortalMode(context, it) },
testIntValues = intArrayOf(CAPTIVE_PORTAL_MODE_AVOID))
testIntSetting(
names = arrayOf(CAPTIVE_PORTAL_MODE),
type = settingsTypeGlobal,
value1 = CAPTIVE_PORTAL_MODE_AVOID,
value2 = CAPTIVE_PORTAL_MODE_PROMPT,
getter = { getCaptivePortalMode(context, CAPTIVE_PORTAL_MODE_IGNORE) },
setter = { setCaptivePortalMode(context, it) },
testIntValues = intArrayOf(CAPTIVE_PORTAL_MODE_AVOID)
)
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
setCaptivePortalMode(context, 5 /* mode */) }
@ -254,11 +341,16 @@ class ConnectivitySettingsManagerTest {
assertEquals(mode, getPrivateDnsDefaultMode(context))
setPrivateDnsDefaultMode(context, PRIVATE_DNS_MODE_OFF)
assertEquals(getPrivateDnsModeAsString(PRIVATE_DNS_MODE_OFF),
getPrivateDnsDefaultMode(context))
assertEquals(
getPrivateDnsModeAsString(PRIVATE_DNS_MODE_OFF),
getPrivateDnsDefaultMode(context)
)
} finally {
resetSettings(names = arrayOf(PRIVATE_DNS_DEFAULT_MODE), type = settingsTypeGlobal,
values = arrayOf(original))
resetSettings(
names = arrayOf(PRIVATE_DNS_DEFAULT_MODE),
type = settingsTypeGlobal,
values = arrayOf(original)
)
}
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
@ -267,12 +359,15 @@ class ConnectivitySettingsManagerTest {
@Test
fun testConnectivityKeepPendingIntentDuration() {
testIntSetting(names = arrayOf(CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS),
type = settingsTypeSecure, value1 = Duration.ofMillis(testTime1),
value2 = Duration.ofMillis(testTime2),
getter = { getConnectivityKeepPendingIntentDuration(context, defaultDuration) },
setter = { setConnectivityKeepPendingIntentDuration(context, it) },
testIntValues = intArrayOf(testTime1.toInt()))
testIntSetting(
names = arrayOf(CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS),
type = settingsTypeSecure,
value1 = Duration.ofMillis(testTime1),
value2 = Duration.ofMillis(testTime2),
getter = { getConnectivityKeepPendingIntentDuration(context, defaultDuration) },
setter = { setConnectivityKeepPendingIntentDuration(context, it) },
testIntValues = intArrayOf(testTime1.toInt())
)
assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
setConnectivityKeepPendingIntentDuration(context, Duration.ofMillis(-1L)) }
@ -280,20 +375,28 @@ class ConnectivitySettingsManagerTest {
@Test
fun testMobileDataAlwaysOn() {
testIntSetting(names = arrayOf(MOBILE_DATA_ALWAYS_ON), type = settingsTypeGlobal,
value1 = false, value2 = true,
getter = { getMobileDataAlwaysOn(context, true /* def */) },
setter = { setMobileDataAlwaysOn(context, it) },
testIntValues = intArrayOf(0))
testIntSetting(
names = arrayOf(MOBILE_DATA_ALWAYS_ON),
type = settingsTypeGlobal,
value1 = false,
value2 = true,
getter = { getMobileDataAlwaysOn(context, true /* def */) },
setter = { setMobileDataAlwaysOn(context, it) },
testIntValues = intArrayOf(0)
)
}
@Test
fun testWifiAlwaysRequested() {
testIntSetting(names = arrayOf(WIFI_ALWAYS_REQUESTED), type = settingsTypeGlobal,
value1 = false, value2 = true,
getter = { getWifiAlwaysRequested(context, true /* def */) },
setter = { setWifiAlwaysRequested(context, it) },
testIntValues = intArrayOf(0))
testIntSetting(
names = arrayOf(WIFI_ALWAYS_REQUESTED),
type = settingsTypeGlobal,
value1 = false,
value2 = true,
getter = { getWifiAlwaysRequested(context, true /* def */) },
setter = { setWifiAlwaysRequested(context, it) },
testIntValues = intArrayOf(0)
)
}
@ConnectivityModuleTest // get/setIngressRateLimitInBytesPerSecond was added via module update
@ -311,4 +414,287 @@ class ConnectivitySettingsManagerTest {
setIngressRateLimitInBytesPerSecond(context, -10)
}
}
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
fun testSetNetworkAvoidBadWifiWithSettings() {
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context)
try {
// initialize NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI and NETWORK_AVOID_BAD_WIFI to null
setNetworkAvoidBadWifiSetting(context, null)
setNetworkLegacyGlobalAvoidBadWifiSetting(context, null)
val testSubId = 1000
// test with if new key NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI is set.
// format: "subId1,value1;subId2,value2;..."
// and if old key NETWORK_AVOID_BAD_WIFI is set as well.
// format: "value"
setNetworkAvoidBadWifi(
context,
defaultSubId,
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_AVOID
)
assertAvoidBadWifiSettingEquals(
"$defaultSubId,1",
getNetworkAvoidBadWifiSetting(context)
)
assertEquals(
"1",
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
)
setNetworkAvoidBadWifi(
context,
defaultSubId,
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_IGNORE
)
assertAvoidBadWifiSettingEquals(
"$defaultSubId,0",
getNetworkAvoidBadWifiSetting(context)
)
assertEquals(
"0",
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
)
setNetworkAvoidBadWifi(
context,
testSubId,
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_AVOID
)
assertAvoidBadWifiSettingEquals(
"$defaultSubId,0;$testSubId,1",
getNetworkAvoidBadWifiSetting(context)
)
assertEquals(
"1",
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
)
setNetworkAvoidBadWifi(
context,
testSubId,
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_IGNORE
)
assertAvoidBadWifiSettingEquals(
"$defaultSubId,0;$testSubId,0",
getNetworkAvoidBadWifiSetting(context)
)
assertEquals(
"0",
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
)
setNetworkAvoidBadWifi(
context,
testSubId,
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_PROMPT
)
assertAvoidBadWifiSettingEquals(
"$defaultSubId,0",
getNetworkAvoidBadWifiSetting(context)
)
assertEquals(
null,
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
)
setNetworkAvoidBadWifi(
context,
defaultSubId,
ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI_PROMPT
)
assertAvoidBadWifiSettingEquals(
null,
getNetworkAvoidBadWifiSetting(context)
)
assertEquals(
null,
getNetworkLegacyGlobalAvoidBadWifiSetting(context)
)
} finally {
resetSettings(
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
type = settingsTypeGlobal,
values = arrayOf(orgCarrierAwareSetting, orgSetting)
)
}
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
fun testGetNetworkAvoidBadWifiWithCarrierAwareSettings() {
val original = getNetworkAvoidBadWifiSetting(context)
try {
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1")
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,0")
assertFalse(getNetworkAvoidBadWifi(context, defaultSubId))
val testSubId = 1000
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,0;$testSubId,1")
assertFalse(getNetworkAvoidBadWifi(context, defaultSubId))
assertTrue(getNetworkAvoidBadWifi(context, testSubId))
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,0;$testSubId,0")
assertFalse(getNetworkAvoidBadWifi(context, defaultSubId))
assertFalse(getNetworkAvoidBadWifi(context, testSubId))
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1;$testSubId,0")
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
assertFalse(getNetworkAvoidBadWifi(context, testSubId))
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1;$testSubId,1")
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
assertTrue(getNetworkAvoidBadWifi(context, testSubId))
} finally {
resetSettings(
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI),
type = settingsTypeGlobal,
values = arrayOf(original)
)
}
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
fun testGetNetworkAvoidBadWifiWithSettings() {
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context)
try {
// test if NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI is not set,
// then it check NETWORK_AVOID_BAD_WIFI for backward compatibility.
setNetworkAvoidBadWifiSetting(context, null)
val testSubId = 1000
setNetworkLegacyGlobalAvoidBadWifiSetting(context, "0")
assertFalse(getNetworkAvoidBadWifi(context, defaultSubId))
assertFalse(getNetworkAvoidBadWifi(context, testSubId))
setNetworkLegacyGlobalAvoidBadWifiSetting(context, "1")
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
assertTrue(getNetworkAvoidBadWifi(context, testSubId))
} finally {
resetSettings(
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
type = settingsTypeGlobal,
values = arrayOf(orgCarrierAwareSetting, orgSetting)
)
}
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
fun testGetNetworkAvoidBadWifiWithCarrierConfig() {
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context)
try {
// unset the global settings, then it depends on the carrier config
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId)
setNetworkAvoidBadWifiSetting(context, null)
setNetworkLegacyGlobalAvoidBadWifiSetting(context, null)
// default should be true if no carrier config key is set
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = true)
assertTrue(getNetworkAvoidBadWifi(context, defaultSubId))
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = false)
assertFalse(getNetworkAvoidBadWifi(context, defaultSubId))
} finally {
resetSettings(
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
type = settingsTypeGlobal,
values = arrayOf(orgCarrierAwareSetting, orgSetting)
)
}
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
fun testShouldShowAvoidBadWifiToggleWithSettings() {
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context)
try {
// unset the NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, and NETWORK_AVOID_BAD_WIFI,
// it should be false since no carrier config is set
setNetworkAvoidBadWifiSetting(context, null)
setNetworkLegacyGlobalAvoidBadWifiSetting(context, null)
assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId))
// if any global settings is set, it should display the toggle.
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,1")
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
setNetworkAvoidBadWifiSetting(context, "$defaultSubId,0")
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
// unset the NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI,
// then it check NETWORK_AVOID_BAD_WIFI for backward compatibility.
setNetworkAvoidBadWifiSetting(context, null)
setNetworkLegacyGlobalAvoidBadWifiSetting(context, "1")
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
setNetworkLegacyGlobalAvoidBadWifiSetting(context, "0")
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
} finally {
resetSettings(
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
type = settingsTypeGlobal,
values = arrayOf(orgCarrierAwareSetting, orgSetting)
)
}
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.BAKLAVA)
fun testShouldShowAvoidBadWifiToggleWithCarrierConfig() {
val orgCarrierAwareSetting = getNetworkAvoidBadWifiSetting(context)
val orgSetting = getNetworkLegacyGlobalAvoidBadWifiSetting(context)
try {
// unset both NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI and KEY_AVOID_BAD_WIFI_BOOL settings,
// then it depends on the carrier config
mCarrierConfigRule.acquireCarrierPrivilege(defaultSubId)
setNetworkAvoidBadWifiSetting(context, null)
setNetworkLegacyGlobalAvoidBadWifiSetting(context, null)
// default should be false if KEY_AVOID_BAD_WIFI_BOOL is not set
assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId))
// if KEY_AVOID_BAD_WIFI_BOOL is true, then check KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL
// default should be false if KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL is not set
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = true)
assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId))
// it should be true if KEY_AVOID_BAD_WIFI_BOOL is false
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = false)
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
// Even if the carrier says not to show the toggle, when the carrier says
// not to avoid bad wifi it should be shown.
// This is because it should not be possible to force a device to be stuck on bad wifi
// and not give the user an option to change this.
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = false, showAvoidBadWifiToggle = false)
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = false, showAvoidBadWifiToggle = true)
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
// if KEY_AVOID_BAD_WIFI_BOOL is true, then check KEY_SHOW_AVOID_BAD_WIFI_TOGGLE_BOOL
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = true, showAvoidBadWifiToggle = false)
assertFalse(shouldShowAvoidBadWifiToggle(context, defaultSubId))
overrideAvoidBadWifiCarrierConfig(avoidBadWifi = true, showAvoidBadWifiToggle = true)
assertTrue(shouldShowAvoidBadWifiToggle(context, defaultSubId))
} finally {
resetSettings(
names = arrayOf(NETWORK_CARRIER_AWARE_AVOID_BAD_WIFI, NETWORK_AVOID_BAD_WIFI),
type = settingsTypeGlobal,
values = arrayOf(orgCarrierAwareSetting, orgSetting)
)
}
}
}