1 /* <lambda>null2 * 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 42 import android.net.ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond 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 55 import android.net.ConnectivitySettingsManager.setIngressRateLimitInBytesPerSecond 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 70 import com.android.testutils.ConnectivityModuleTest 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 } 298 299 @ConnectivityModuleTest // get/setIngressRateLimitInBytesPerSecond was added via module update 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 } 314 }