paulhu | 236a992 | 2021-03-29 10:50:36 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2021 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.net |
| 18 | |
| 19 | import android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE |
| 20 | import android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID |
| 21 | import android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_IGNORE |
| 22 | import android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT |
| 23 | import android.net.ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS |
| 24 | import android.net.ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE |
| 25 | import android.net.ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI |
| 26 | import android.net.ConnectivitySettingsManager.DNS_RESOLVER_MAX_SAMPLES |
| 27 | import android.net.ConnectivitySettingsManager.DNS_RESOLVER_MIN_SAMPLES |
| 28 | import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS |
| 29 | import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT |
| 30 | import android.net.ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON |
| 31 | import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT |
| 32 | import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS |
| 33 | import android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE |
| 34 | import android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF |
| 35 | import android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC |
| 36 | import android.net.ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED |
| 37 | import android.net.ConnectivitySettingsManager.getCaptivePortalMode |
| 38 | import android.net.ConnectivitySettingsManager.getConnectivityKeepPendingIntentDuration |
| 39 | import android.net.ConnectivitySettingsManager.getDnsResolverSampleRanges |
| 40 | import android.net.ConnectivitySettingsManager.getDnsResolverSampleValidityDuration |
| 41 | import android.net.ConnectivitySettingsManager.getDnsResolverSuccessThresholdPercent |
Patrick Rohr | a208436 | 2022-01-03 15:55:52 +0100 | [diff] [blame] | 42 | import android.net.ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond |
paulhu | 236a992 | 2021-03-29 10:50:36 +0800 | [diff] [blame] | 43 | import android.net.ConnectivitySettingsManager.getMobileDataActivityTimeout |
| 44 | import android.net.ConnectivitySettingsManager.getMobileDataAlwaysOn |
| 45 | import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationMaximumDailyCount |
| 46 | import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationRateDuration |
| 47 | import android.net.ConnectivitySettingsManager.getPrivateDnsDefaultMode |
| 48 | import android.net.ConnectivitySettingsManager.getWifiAlwaysRequested |
| 49 | import android.net.ConnectivitySettingsManager.getWifiDataActivityTimeout |
| 50 | import android.net.ConnectivitySettingsManager.setCaptivePortalMode |
| 51 | import android.net.ConnectivitySettingsManager.setConnectivityKeepPendingIntentDuration |
| 52 | import android.net.ConnectivitySettingsManager.setDnsResolverSampleRanges |
| 53 | import android.net.ConnectivitySettingsManager.setDnsResolverSampleValidityDuration |
| 54 | import android.net.ConnectivitySettingsManager.setDnsResolverSuccessThresholdPercent |
Patrick Rohr | a208436 | 2022-01-03 15:55:52 +0100 | [diff] [blame] | 55 | import android.net.ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond |
paulhu | 236a992 | 2021-03-29 10:50:36 +0800 | [diff] [blame] | 56 | import android.net.ConnectivitySettingsManager.setMobileDataActivityTimeout |
| 57 | import android.net.ConnectivitySettingsManager.setMobileDataAlwaysOn |
| 58 | import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationMaximumDailyCount |
| 59 | import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationRateDuration |
| 60 | import android.net.ConnectivitySettingsManager.setPrivateDnsDefaultMode |
| 61 | import android.net.ConnectivitySettingsManager.setWifiAlwaysRequested |
| 62 | import android.net.ConnectivitySettingsManager.setWifiDataActivityTimeout |
| 63 | import android.os.Build |
| 64 | import android.platform.test.annotations.AppModeFull |
| 65 | import android.provider.Settings |
| 66 | import android.util.Range |
| 67 | import androidx.test.InstrumentationRegistry |
| 68 | import androidx.test.filters.SmallTest |
| 69 | import com.android.net.module.util.ConnectivitySettingsUtils.getPrivateDnsModeAsString |
Remi NGUYEN VAN | 3b81323 | 2022-02-16 12:15:14 +0900 | [diff] [blame] | 70 | import com.android.testutils.ConnectivityModuleTest |
paulhu | 236a992 | 2021-03-29 10:50:36 +0800 | [diff] [blame] | 71 | import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo |
| 72 | import com.android.testutils.DevSdkIgnoreRunner |
| 73 | import junit.framework.Assert.assertEquals |
| 74 | import org.junit.Test |
| 75 | import org.junit.runner.RunWith |
| 76 | import java.time.Duration |
| 77 | import java.util.Objects |
| 78 | import kotlin.test.assertFailsWith |
| 79 | |
| 80 | /** |
| 81 | * Tests for [ConnectivitySettingsManager]. |
| 82 | * |
| 83 | * Build, install and run with: |
| 84 | * atest android.net.ConnectivitySettingsManagerTest |
| 85 | */ |
| 86 | @RunWith(DevSdkIgnoreRunner::class) |
| 87 | @IgnoreUpTo(Build.VERSION_CODES.R) |
| 88 | @SmallTest |
| 89 | @AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps") |
| 90 | class ConnectivitySettingsManagerTest { |
| 91 | private val instrumentation = InstrumentationRegistry.getInstrumentation() |
| 92 | private val context = instrumentation.context |
| 93 | private val resolver = context.contentResolver |
| 94 | |
| 95 | private val defaultDuration = Duration.ofSeconds(0L) |
| 96 | private val testTime1 = 5L |
| 97 | private val testTime2 = 10L |
| 98 | private val settingsTypeGlobal = "global" |
| 99 | private val settingsTypeSecure = "secure" |
| 100 | |
| 101 | /*** Reset setting value or delete setting if the setting was not existed before testing. */ |
| 102 | private fun resetSettings(names: Array<String>, type: String, values: Array<String?>) { |
| 103 | for (i in names.indices) { |
| 104 | if (Objects.equals(values[i], null)) { |
| 105 | instrumentation.uiAutomation.executeShellCommand( |
| 106 | "settings delete $type ${names[i]}") |
| 107 | } else { |
| 108 | if (settingsTypeSecure.equals(type)) { |
| 109 | Settings.Secure.putString(resolver, names[i], values[i]) |
| 110 | } else { |
| 111 | Settings.Global.putString(resolver, names[i], values[i]) |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | fun <T> testIntSetting( |
| 118 | names: Array<String>, |
| 119 | type: String, |
| 120 | value1: T, |
| 121 | value2: T, |
| 122 | getter: () -> T, |
| 123 | setter: (value: T) -> Unit, |
| 124 | testIntValues: IntArray |
| 125 | ) { |
| 126 | val originals: Array<String?> = Array(names.size) { i -> |
| 127 | if (settingsTypeSecure.equals(type)) { |
| 128 | Settings.Secure.getString(resolver, names[i]) |
| 129 | } else { |
| 130 | Settings.Global.getString(resolver, names[i]) |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | try { |
| 135 | for (i in names.indices) { |
| 136 | if (settingsTypeSecure.equals(type)) { |
| 137 | Settings.Secure.putString(resolver, names[i], testIntValues[i].toString()) |
| 138 | } else { |
| 139 | Settings.Global.putString(resolver, names[i], testIntValues[i].toString()) |
| 140 | } |
| 141 | } |
| 142 | assertEquals(value1, getter()) |
| 143 | |
| 144 | setter(value2) |
| 145 | assertEquals(value2, getter()) |
| 146 | } finally { |
| 147 | resetSettings(names, type, originals) |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | @Test |
| 152 | fun testMobileDataActivityTimeout() { |
| 153 | testIntSetting(names = arrayOf(DATA_ACTIVITY_TIMEOUT_MOBILE), type = settingsTypeGlobal, |
| 154 | value1 = Duration.ofSeconds(testTime1), value2 = Duration.ofSeconds(testTime2), |
| 155 | getter = { getMobileDataActivityTimeout(context, defaultDuration) }, |
| 156 | setter = { setMobileDataActivityTimeout(context, it) }, |
| 157 | testIntValues = intArrayOf(testTime1.toInt())) |
| 158 | } |
| 159 | |
| 160 | @Test |
| 161 | fun testWifiDataActivityTimeout() { |
| 162 | testIntSetting(names = arrayOf(DATA_ACTIVITY_TIMEOUT_WIFI), type = settingsTypeGlobal, |
| 163 | value1 = Duration.ofSeconds(testTime1), value2 = Duration.ofSeconds(testTime2), |
| 164 | getter = { getWifiDataActivityTimeout(context, defaultDuration) }, |
| 165 | setter = { setWifiDataActivityTimeout(context, it) }, |
| 166 | testIntValues = intArrayOf(testTime1.toInt())) |
| 167 | } |
| 168 | |
| 169 | @Test |
| 170 | fun testDnsResolverSampleValidityDuration() { |
| 171 | testIntSetting(names = arrayOf(DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS), |
| 172 | type = settingsTypeGlobal, value1 = Duration.ofSeconds(testTime1), |
| 173 | value2 = Duration.ofSeconds(testTime2), |
| 174 | getter = { getDnsResolverSampleValidityDuration(context, defaultDuration) }, |
| 175 | setter = { setDnsResolverSampleValidityDuration(context, it) }, |
| 176 | testIntValues = intArrayOf(testTime1.toInt())) |
| 177 | |
| 178 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 179 | setDnsResolverSampleValidityDuration(context, Duration.ofSeconds(-1L)) } |
| 180 | } |
| 181 | |
| 182 | @Test |
| 183 | fun testDnsResolverSuccessThresholdPercent() { |
| 184 | testIntSetting(names = arrayOf(DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT), |
| 185 | type = settingsTypeGlobal, value1 = 5, value2 = 10, |
| 186 | getter = { getDnsResolverSuccessThresholdPercent(context, 0 /* def */) }, |
| 187 | setter = { setDnsResolverSuccessThresholdPercent(context, it) }, |
| 188 | testIntValues = intArrayOf(5)) |
| 189 | |
| 190 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 191 | setDnsResolverSuccessThresholdPercent(context, -1) } |
| 192 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 193 | setDnsResolverSuccessThresholdPercent(context, 120) } |
| 194 | } |
| 195 | |
| 196 | @Test |
| 197 | fun testDnsResolverSampleRanges() { |
| 198 | testIntSetting(names = arrayOf(DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_MAX_SAMPLES), |
| 199 | type = settingsTypeGlobal, value1 = Range(1, 63), value2 = Range(2, 62), |
| 200 | getter = { getDnsResolverSampleRanges(context) }, |
| 201 | setter = { setDnsResolverSampleRanges(context, it) }, |
| 202 | testIntValues = intArrayOf(1, 63)) |
| 203 | |
| 204 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 205 | setDnsResolverSampleRanges(context, Range(-1, 62)) } |
| 206 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 207 | setDnsResolverSampleRanges(context, Range(2, 65)) } |
| 208 | } |
| 209 | |
| 210 | @Test |
| 211 | fun testNetworkSwitchNotificationMaximumDailyCount() { |
| 212 | testIntSetting(names = arrayOf(NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT), |
| 213 | type = settingsTypeGlobal, value1 = 5, value2 = 15, |
| 214 | getter = { getNetworkSwitchNotificationMaximumDailyCount(context, 0 /* def */) }, |
| 215 | setter = { setNetworkSwitchNotificationMaximumDailyCount(context, it) }, |
| 216 | testIntValues = intArrayOf(5)) |
| 217 | |
| 218 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 219 | setNetworkSwitchNotificationMaximumDailyCount(context, -1) } |
| 220 | } |
| 221 | |
| 222 | @Test |
| 223 | fun testNetworkSwitchNotificationRateDuration() { |
| 224 | testIntSetting(names = arrayOf(NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS), |
| 225 | type = settingsTypeGlobal, value1 = Duration.ofMillis(testTime1), |
| 226 | value2 = Duration.ofMillis(testTime2), |
| 227 | getter = { getNetworkSwitchNotificationRateDuration(context, defaultDuration) }, |
| 228 | setter = { setNetworkSwitchNotificationRateDuration(context, it) }, |
| 229 | testIntValues = intArrayOf(testTime1.toInt())) |
| 230 | |
| 231 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 232 | setNetworkSwitchNotificationRateDuration(context, Duration.ofMillis(-1L)) } |
| 233 | } |
| 234 | |
| 235 | @Test |
| 236 | fun testCaptivePortalMode() { |
| 237 | testIntSetting(names = arrayOf(CAPTIVE_PORTAL_MODE), type = settingsTypeGlobal, |
| 238 | value1 = CAPTIVE_PORTAL_MODE_AVOID, value2 = CAPTIVE_PORTAL_MODE_PROMPT, |
| 239 | getter = { getCaptivePortalMode(context, CAPTIVE_PORTAL_MODE_IGNORE) }, |
| 240 | setter = { setCaptivePortalMode(context, it) }, |
| 241 | testIntValues = intArrayOf(CAPTIVE_PORTAL_MODE_AVOID)) |
| 242 | |
| 243 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 244 | setCaptivePortalMode(context, 5 /* mode */) } |
| 245 | } |
| 246 | |
| 247 | @Test |
| 248 | fun testPrivateDnsDefaultMode() { |
| 249 | val original = Settings.Global.getString(resolver, PRIVATE_DNS_DEFAULT_MODE) |
| 250 | |
| 251 | try { |
| 252 | val mode = getPrivateDnsModeAsString(PRIVATE_DNS_MODE_OPPORTUNISTIC) |
| 253 | Settings.Global.putString(resolver, PRIVATE_DNS_DEFAULT_MODE, mode) |
| 254 | assertEquals(mode, getPrivateDnsDefaultMode(context)) |
| 255 | |
| 256 | setPrivateDnsDefaultMode(context, PRIVATE_DNS_MODE_OFF) |
| 257 | assertEquals(getPrivateDnsModeAsString(PRIVATE_DNS_MODE_OFF), |
| 258 | getPrivateDnsDefaultMode(context)) |
| 259 | } finally { |
| 260 | resetSettings(names = arrayOf(PRIVATE_DNS_DEFAULT_MODE), type = settingsTypeGlobal, |
| 261 | values = arrayOf(original)) |
| 262 | } |
| 263 | |
| 264 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 265 | setPrivateDnsDefaultMode(context, -1) } |
| 266 | } |
| 267 | |
| 268 | @Test |
| 269 | fun testConnectivityKeepPendingIntentDuration() { |
| 270 | testIntSetting(names = arrayOf(CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS), |
| 271 | type = settingsTypeSecure, value1 = Duration.ofMillis(testTime1), |
| 272 | value2 = Duration.ofMillis(testTime2), |
| 273 | getter = { getConnectivityKeepPendingIntentDuration(context, defaultDuration) }, |
| 274 | setter = { setConnectivityKeepPendingIntentDuration(context, it) }, |
| 275 | testIntValues = intArrayOf(testTime1.toInt())) |
| 276 | |
| 277 | assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") { |
| 278 | setConnectivityKeepPendingIntentDuration(context, Duration.ofMillis(-1L)) } |
| 279 | } |
| 280 | |
| 281 | @Test |
| 282 | fun testMobileDataAlwaysOn() { |
| 283 | testIntSetting(names = arrayOf(MOBILE_DATA_ALWAYS_ON), type = settingsTypeGlobal, |
| 284 | value1 = false, value2 = true, |
| 285 | getter = { getMobileDataAlwaysOn(context, true /* def */) }, |
| 286 | setter = { setMobileDataAlwaysOn(context, it) }, |
| 287 | testIntValues = intArrayOf(0)) |
| 288 | } |
| 289 | |
| 290 | @Test |
| 291 | fun testWifiAlwaysRequested() { |
| 292 | testIntSetting(names = arrayOf(WIFI_ALWAYS_REQUESTED), type = settingsTypeGlobal, |
| 293 | value1 = false, value2 = true, |
| 294 | getter = { getWifiAlwaysRequested(context, true /* def */) }, |
| 295 | setter = { setWifiAlwaysRequested(context, it) }, |
| 296 | testIntValues = intArrayOf(0)) |
| 297 | } |
Patrick Rohr | a208436 | 2022-01-03 15:55:52 +0100 | [diff] [blame] | 298 | |
Remi NGUYEN VAN | 3b81323 | 2022-02-16 12:15:14 +0900 | [diff] [blame] | 299 | @ConnectivityModuleTest // get/setIngressRateLimitInBytesPerSecond was added via module update |
Patrick Rohr | a208436 | 2022-01-03 15:55:52 +0100 | [diff] [blame] | 300 | @Test |
| 301 | fun testInternetNetworkRateLimitInBytesPerSecond() { |
| 302 | val defaultRate = getIngressRateLimitInBytesPerSecond(context) |
| 303 | val testRate = 1000L |
| 304 | setIngressRateLimitInBytesPerSecond(context, testRate) |
| 305 | assertEquals(testRate, getIngressRateLimitInBytesPerSecond(context)) |
| 306 | |
| 307 | setIngressRateLimitInBytesPerSecond(context, defaultRate) |
| 308 | assertEquals(defaultRate, getIngressRateLimitInBytesPerSecond(context)) |
| 309 | |
| 310 | assertFailsWith<IllegalArgumentException>("Expected failure, but setting accepted") { |
| 311 | setIngressRateLimitInBytesPerSecond(context, -10) |
| 312 | } |
| 313 | } |
paulhu | 236a992 | 2021-03-29 10:50:36 +0800 | [diff] [blame] | 314 | } |