blob: ebaa787cc6a72a77135e9f30233640b697dbf3de [file] [log] [blame]
paulhu236a9922021-03-29 10:50:36 +08001/*
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
17package android.net
18
19import android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE
20import android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
21import android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_IGNORE
22import android.net.ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_PROMPT
23import android.net.ConnectivitySettingsManager.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
24import android.net.ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_MOBILE
25import android.net.ConnectivitySettingsManager.DATA_ACTIVITY_TIMEOUT_WIFI
26import android.net.ConnectivitySettingsManager.DNS_RESOLVER_MAX_SAMPLES
27import android.net.ConnectivitySettingsManager.DNS_RESOLVER_MIN_SAMPLES
28import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS
29import android.net.ConnectivitySettingsManager.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT
30import android.net.ConnectivitySettingsManager.MOBILE_DATA_ALWAYS_ON
31import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT
32import android.net.ConnectivitySettingsManager.NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS
33import android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE
34import android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF
35import android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC
36import android.net.ConnectivitySettingsManager.WIFI_ALWAYS_REQUESTED
37import android.net.ConnectivitySettingsManager.getCaptivePortalMode
38import android.net.ConnectivitySettingsManager.getConnectivityKeepPendingIntentDuration
39import android.net.ConnectivitySettingsManager.getDnsResolverSampleRanges
40import android.net.ConnectivitySettingsManager.getDnsResolverSampleValidityDuration
41import android.net.ConnectivitySettingsManager.getDnsResolverSuccessThresholdPercent
42import android.net.ConnectivitySettingsManager.getMobileDataActivityTimeout
43import android.net.ConnectivitySettingsManager.getMobileDataAlwaysOn
44import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationMaximumDailyCount
45import android.net.ConnectivitySettingsManager.getNetworkSwitchNotificationRateDuration
46import android.net.ConnectivitySettingsManager.getPrivateDnsDefaultMode
47import android.net.ConnectivitySettingsManager.getWifiAlwaysRequested
48import android.net.ConnectivitySettingsManager.getWifiDataActivityTimeout
49import android.net.ConnectivitySettingsManager.setCaptivePortalMode
50import android.net.ConnectivitySettingsManager.setConnectivityKeepPendingIntentDuration
51import android.net.ConnectivitySettingsManager.setDnsResolverSampleRanges
52import android.net.ConnectivitySettingsManager.setDnsResolverSampleValidityDuration
53import android.net.ConnectivitySettingsManager.setDnsResolverSuccessThresholdPercent
54import android.net.ConnectivitySettingsManager.setMobileDataActivityTimeout
55import android.net.ConnectivitySettingsManager.setMobileDataAlwaysOn
56import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationMaximumDailyCount
57import android.net.ConnectivitySettingsManager.setNetworkSwitchNotificationRateDuration
58import android.net.ConnectivitySettingsManager.setPrivateDnsDefaultMode
59import android.net.ConnectivitySettingsManager.setWifiAlwaysRequested
60import android.net.ConnectivitySettingsManager.setWifiDataActivityTimeout
61import android.os.Build
62import android.platform.test.annotations.AppModeFull
63import android.provider.Settings
64import android.util.Range
65import androidx.test.InstrumentationRegistry
66import androidx.test.filters.SmallTest
67import com.android.net.module.util.ConnectivitySettingsUtils.getPrivateDnsModeAsString
68import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
69import com.android.testutils.DevSdkIgnoreRunner
70import junit.framework.Assert.assertEquals
71import org.junit.Test
72import org.junit.runner.RunWith
73import java.time.Duration
74import java.util.Objects
75import kotlin.test.assertFailsWith
76
77/**
78 * Tests for [ConnectivitySettingsManager].
79 *
80 * Build, install and run with:
81 * atest android.net.ConnectivitySettingsManagerTest
82 */
83@RunWith(DevSdkIgnoreRunner::class)
84@IgnoreUpTo(Build.VERSION_CODES.R)
85@SmallTest
86@AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
87class ConnectivitySettingsManagerTest {
88 private val instrumentation = InstrumentationRegistry.getInstrumentation()
89 private val context = instrumentation.context
90 private val resolver = context.contentResolver
91
92 private val defaultDuration = Duration.ofSeconds(0L)
93 private val testTime1 = 5L
94 private val testTime2 = 10L
95 private val settingsTypeGlobal = "global"
96 private val settingsTypeSecure = "secure"
97
98 /*** Reset setting value or delete setting if the setting was not existed before testing. */
99 private fun resetSettings(names: Array<String>, type: String, values: Array<String?>) {
100 for (i in names.indices) {
101 if (Objects.equals(values[i], null)) {
102 instrumentation.uiAutomation.executeShellCommand(
103 "settings delete $type ${names[i]}")
104 } else {
105 if (settingsTypeSecure.equals(type)) {
106 Settings.Secure.putString(resolver, names[i], values[i])
107 } else {
108 Settings.Global.putString(resolver, names[i], values[i])
109 }
110 }
111 }
112 }
113
114 fun <T> testIntSetting(
115 names: Array<String>,
116 type: String,
117 value1: T,
118 value2: T,
119 getter: () -> T,
120 setter: (value: T) -> Unit,
121 testIntValues: IntArray
122 ) {
123 val originals: Array<String?> = Array(names.size) { i ->
124 if (settingsTypeSecure.equals(type)) {
125 Settings.Secure.getString(resolver, names[i])
126 } else {
127 Settings.Global.getString(resolver, names[i])
128 }
129 }
130
131 try {
132 for (i in names.indices) {
133 if (settingsTypeSecure.equals(type)) {
134 Settings.Secure.putString(resolver, names[i], testIntValues[i].toString())
135 } else {
136 Settings.Global.putString(resolver, names[i], testIntValues[i].toString())
137 }
138 }
139 assertEquals(value1, getter())
140
141 setter(value2)
142 assertEquals(value2, getter())
143 } finally {
144 resetSettings(names, type, originals)
145 }
146 }
147
148 @Test
149 fun testMobileDataActivityTimeout() {
150 testIntSetting(names = arrayOf(DATA_ACTIVITY_TIMEOUT_MOBILE), type = settingsTypeGlobal,
151 value1 = Duration.ofSeconds(testTime1), value2 = Duration.ofSeconds(testTime2),
152 getter = { getMobileDataActivityTimeout(context, defaultDuration) },
153 setter = { setMobileDataActivityTimeout(context, it) },
154 testIntValues = intArrayOf(testTime1.toInt()))
155 }
156
157 @Test
158 fun testWifiDataActivityTimeout() {
159 testIntSetting(names = arrayOf(DATA_ACTIVITY_TIMEOUT_WIFI), type = settingsTypeGlobal,
160 value1 = Duration.ofSeconds(testTime1), value2 = Duration.ofSeconds(testTime2),
161 getter = { getWifiDataActivityTimeout(context, defaultDuration) },
162 setter = { setWifiDataActivityTimeout(context, it) },
163 testIntValues = intArrayOf(testTime1.toInt()))
164 }
165
166 @Test
167 fun testDnsResolverSampleValidityDuration() {
168 testIntSetting(names = arrayOf(DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS),
169 type = settingsTypeGlobal, value1 = Duration.ofSeconds(testTime1),
170 value2 = Duration.ofSeconds(testTime2),
171 getter = { getDnsResolverSampleValidityDuration(context, defaultDuration) },
172 setter = { setDnsResolverSampleValidityDuration(context, it) },
173 testIntValues = intArrayOf(testTime1.toInt()))
174
175 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
176 setDnsResolverSampleValidityDuration(context, Duration.ofSeconds(-1L)) }
177 }
178
179 @Test
180 fun testDnsResolverSuccessThresholdPercent() {
181 testIntSetting(names = arrayOf(DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT),
182 type = settingsTypeGlobal, value1 = 5, value2 = 10,
183 getter = { getDnsResolverSuccessThresholdPercent(context, 0 /* def */) },
184 setter = { setDnsResolverSuccessThresholdPercent(context, it) },
185 testIntValues = intArrayOf(5))
186
187 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
188 setDnsResolverSuccessThresholdPercent(context, -1) }
189 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
190 setDnsResolverSuccessThresholdPercent(context, 120) }
191 }
192
193 @Test
194 fun testDnsResolverSampleRanges() {
195 testIntSetting(names = arrayOf(DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_MAX_SAMPLES),
196 type = settingsTypeGlobal, value1 = Range(1, 63), value2 = Range(2, 62),
197 getter = { getDnsResolverSampleRanges(context) },
198 setter = { setDnsResolverSampleRanges(context, it) },
199 testIntValues = intArrayOf(1, 63))
200
201 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
202 setDnsResolverSampleRanges(context, Range(-1, 62)) }
203 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
204 setDnsResolverSampleRanges(context, Range(2, 65)) }
205 }
206
207 @Test
208 fun testNetworkSwitchNotificationMaximumDailyCount() {
209 testIntSetting(names = arrayOf(NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT),
210 type = settingsTypeGlobal, value1 = 5, value2 = 15,
211 getter = { getNetworkSwitchNotificationMaximumDailyCount(context, 0 /* def */) },
212 setter = { setNetworkSwitchNotificationMaximumDailyCount(context, it) },
213 testIntValues = intArrayOf(5))
214
215 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
216 setNetworkSwitchNotificationMaximumDailyCount(context, -1) }
217 }
218
219 @Test
220 fun testNetworkSwitchNotificationRateDuration() {
221 testIntSetting(names = arrayOf(NETWORK_SWITCH_NOTIFICATION_RATE_LIMIT_MILLIS),
222 type = settingsTypeGlobal, value1 = Duration.ofMillis(testTime1),
223 value2 = Duration.ofMillis(testTime2),
224 getter = { getNetworkSwitchNotificationRateDuration(context, defaultDuration) },
225 setter = { setNetworkSwitchNotificationRateDuration(context, it) },
226 testIntValues = intArrayOf(testTime1.toInt()))
227
228 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
229 setNetworkSwitchNotificationRateDuration(context, Duration.ofMillis(-1L)) }
230 }
231
232 @Test
233 fun testCaptivePortalMode() {
234 testIntSetting(names = arrayOf(CAPTIVE_PORTAL_MODE), type = settingsTypeGlobal,
235 value1 = CAPTIVE_PORTAL_MODE_AVOID, value2 = CAPTIVE_PORTAL_MODE_PROMPT,
236 getter = { getCaptivePortalMode(context, CAPTIVE_PORTAL_MODE_IGNORE) },
237 setter = { setCaptivePortalMode(context, it) },
238 testIntValues = intArrayOf(CAPTIVE_PORTAL_MODE_AVOID))
239
240 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
241 setCaptivePortalMode(context, 5 /* mode */) }
242 }
243
244 @Test
245 fun testPrivateDnsDefaultMode() {
246 val original = Settings.Global.getString(resolver, PRIVATE_DNS_DEFAULT_MODE)
247
248 try {
249 val mode = getPrivateDnsModeAsString(PRIVATE_DNS_MODE_OPPORTUNISTIC)
250 Settings.Global.putString(resolver, PRIVATE_DNS_DEFAULT_MODE, mode)
251 assertEquals(mode, getPrivateDnsDefaultMode(context))
252
253 setPrivateDnsDefaultMode(context, PRIVATE_DNS_MODE_OFF)
254 assertEquals(getPrivateDnsModeAsString(PRIVATE_DNS_MODE_OFF),
255 getPrivateDnsDefaultMode(context))
256 } finally {
257 resetSettings(names = arrayOf(PRIVATE_DNS_DEFAULT_MODE), type = settingsTypeGlobal,
258 values = arrayOf(original))
259 }
260
261 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
262 setPrivateDnsDefaultMode(context, -1) }
263 }
264
265 @Test
266 fun testConnectivityKeepPendingIntentDuration() {
267 testIntSetting(names = arrayOf(CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS),
268 type = settingsTypeSecure, value1 = Duration.ofMillis(testTime1),
269 value2 = Duration.ofMillis(testTime2),
270 getter = { getConnectivityKeepPendingIntentDuration(context, defaultDuration) },
271 setter = { setConnectivityKeepPendingIntentDuration(context, it) },
272 testIntValues = intArrayOf(testTime1.toInt()))
273
274 assertFailsWith<IllegalArgumentException>("Expect fail but argument accepted.") {
275 setConnectivityKeepPendingIntentDuration(context, Duration.ofMillis(-1L)) }
276 }
277
278 @Test
279 fun testMobileDataAlwaysOn() {
280 testIntSetting(names = arrayOf(MOBILE_DATA_ALWAYS_ON), type = settingsTypeGlobal,
281 value1 = false, value2 = true,
282 getter = { getMobileDataAlwaysOn(context, true /* def */) },
283 setter = { setMobileDataAlwaysOn(context, it) },
284 testIntValues = intArrayOf(0))
285 }
286
287 @Test
288 fun testWifiAlwaysRequested() {
289 testIntSetting(names = arrayOf(WIFI_ALWAYS_REQUESTED), type = settingsTypeGlobal,
290 value1 = false, value2 = true,
291 getter = { getWifiAlwaysRequested(context, true /* def */) },
292 setter = { setWifiAlwaysRequested(context, it) },
293 testIntValues = intArrayOf(0))
294 }
295}