• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.app.usage.NetworkStatsManager.NETWORK_TYPE_5G_NSA
20 import android.content.Context
21 import android.net.ConnectivityManager.TYPE_MOBILE
22 import android.net.ConnectivityManager.TYPE_TEST
23 import android.net.ConnectivityManager.TYPE_WIFI
24 import android.net.NetworkCapabilities.TRANSPORT_TEST
25 import android.net.NetworkCapabilities.TRANSPORT_WIFI
26 import android.net.NetworkIdentity.OEM_NONE
27 import android.net.NetworkIdentity.OEM_PAID
28 import android.net.NetworkIdentity.OEM_PRIVATE
29 import android.net.NetworkIdentity.buildNetworkIdentity
30 import android.net.NetworkStats.DEFAULT_NETWORK_ALL
31 import android.net.NetworkStats.METERED_ALL
32 import android.net.NetworkStats.METERED_NO
33 import android.net.NetworkStats.METERED_YES
34 import android.net.NetworkStats.ROAMING_ALL
35 import android.net.NetworkTemplate.MATCH_CARRIER
36 import android.net.NetworkTemplate.MATCH_MOBILE
37 import android.net.NetworkTemplate.MATCH_TEST
38 import android.net.NetworkTemplate.MATCH_WIFI
39 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
40 import android.net.NetworkTemplate.OEM_MANAGED_ALL
41 import android.net.NetworkTemplate.OEM_MANAGED_NO
42 import android.net.NetworkTemplate.OEM_MANAGED_YES
43 import android.net.NetworkTemplate.buildTemplateMobileAll
44 import android.net.NetworkTemplate.buildTemplateMobileWildcard
45 import android.net.NetworkTemplate.buildTemplateWifiWildcard
46 import android.net.NetworkTemplate.normalize
47 import android.net.wifi.WifiInfo
48 import android.os.Build
49 import android.telephony.TelephonyManager
50 import com.android.testutils.DevSdkIgnoreRule
51 import com.android.testutils.DevSdkIgnoreRunner
52 import com.android.testutils.NonNullTestUtils
53 import com.android.testutils.assertParcelSane
54 import kotlin.test.assertEquals
55 import kotlin.test.assertFalse
56 import kotlin.test.assertNotEquals
57 import kotlin.test.assertTrue
58 import org.junit.Before
59 import org.junit.Rule
60 import org.junit.Test
61 import org.junit.runner.RunWith
62 import org.mockito.Mockito.mock
63 import org.mockito.Mockito.`when`
64 import org.mockito.MockitoAnnotations
65 
66 private const val TEST_IMSI1 = "imsi1"
67 private const val TEST_IMSI2 = "imsi2"
68 private const val TEST_IMSI3 = "imsi3"
69 private const val TEST_WIFI_KEY1 = "wifiKey1"
70 private const val TEST_WIFI_KEY2 = "wifiKey2"
71 
72 @RunWith(DevSdkIgnoreRunner::class)
73 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
74 class NetworkTemplateTest {
75     @get:Rule
76     val ignoreRule = DevSdkIgnoreRule()
77     private val mockContext = mock(Context::class.java)
78     private val mockWifiInfo = mock(WifiInfo::class.java)
79 
buildMobileNetworkStatenull80     private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot =
81             buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
82     private fun buildWifiNetworkState(subscriberId: String?, wifiKey: String?):
83             NetworkStateSnapshot = buildNetworkState(TYPE_WIFI,
84             subscriberId = subscriberId, wifiKey = wifiKey)
85 
86     private fun buildNetworkState(
87         type: Int,
88         subscriberId: String? = null,
89         wifiKey: String? = null,
90         oemManaged: Int = OEM_NONE,
91         metered: Boolean = true
92     ): NetworkStateSnapshot {
93         `when`(mockWifiInfo.getNetworkKey()).thenReturn(wifiKey)
94         val lp = LinkProperties()
95         val caps = NetworkCapabilities().apply {
96             setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !metered)
97             setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
98             setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID,
99                     (oemManaged and OEM_PAID) == OEM_PAID)
100             setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
101                     (oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
102             if (type == TYPE_TEST) {
103                 wifiKey?.let { TestNetworkSpecifier(it) }?.let {
104                     // Must have a single non-test transport specified to use setNetworkSpecifier.
105                     // Put an arbitrary transport type which is not used in this test.
106                     addTransportType(TRANSPORT_TEST)
107                     addTransportType(TRANSPORT_WIFI)
108                     setNetworkSpecifier(it) }
109             }
110             setTransportInfo(mockWifiInfo)
111         }
112         return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
113     }
114 
NetworkTemplatenull115     private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) =
116             assertTrue(matches(ident), "$this does not match $ident")
117 
118     private fun NetworkTemplate.assertDoesNotMatch(ident: NetworkIdentity) =
119             assertFalse(matches(ident), "$this should match $ident")
120 
121     @Before
122     fun setup() {
123         MockitoAnnotations.initMocks(this)
124     }
125 
126     @Test
testWifiWildcardMatchesnull127     fun testWifiWildcardMatches() {
128         val templateWifiWildcard = buildTemplateWifiWildcard()
129 
130         val identMobileImsi1 = buildNetworkIdentity(mockContext,
131                 buildMobileNetworkState(TEST_IMSI1),
132                 false, TelephonyManager.NETWORK_TYPE_UMTS)
133         val identWifiImsiNullKey1 = buildNetworkIdentity(
134                 mockContext, buildWifiNetworkState(null, TEST_WIFI_KEY1), true, 0)
135         val identWifiImsi1Key1 = buildNetworkIdentity(
136                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
137         // This identity with a null wifiNetworkKey is to test matchesWifiNetworkKey won't crash
138         // the system when a null wifiNetworkKey is provided, which happens because of a bug in wifi
139         // and it should still match the wifi wildcard template. See b/266598304.
140         val identWifiNullKey = buildNetworkIdentity(
141                 mockContext, buildWifiNetworkState(null /* subscriberId */,
142                 null /* wifiNetworkKey */), true, 0)
143 
144         templateWifiWildcard.assertDoesNotMatch(identMobileImsi1)
145         templateWifiWildcard.assertMatches(identWifiImsiNullKey1)
146         templateWifiWildcard.assertMatches(identWifiImsi1Key1)
147         templateWifiWildcard.assertMatches(identWifiNullKey)
148     }
149 
150     @Test
testWifiMatchesnull151     fun testWifiMatches() {
152         val templateWifiKey1 = NetworkTemplate.Builder(MATCH_WIFI)
153                 .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
154         val templateWifiKey1ImsiNull = NetworkTemplate.Builder(MATCH_WIFI)
155                 .setSubscriberIds(setOf(null))
156                 .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
157         val templateWifiKey1Imsi1 = NetworkTemplate.Builder(MATCH_WIFI)
158                 .setSubscriberIds(setOf(TEST_IMSI1))
159                 .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
160         val templateWifiKeyAllImsi1 = NetworkTemplate.Builder(MATCH_WIFI)
161                 .setSubscriberIds(setOf(TEST_IMSI1)).build()
162         val templateNullWifiKey = NetworkTemplate(MATCH_WIFI,
163                 emptyArray<String>() /* subscriberIds */, arrayOf(null) /* wifiNetworkKeys */,
164                 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
165 
166         val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
167                 false, TelephonyManager.NETWORK_TYPE_UMTS)
168         val identWifiImsiNullKey1 = buildNetworkIdentity(
169                 mockContext, buildWifiNetworkState(null, TEST_WIFI_KEY1), true, 0)
170         val identWifiImsi1Key1 = buildNetworkIdentity(
171                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
172         val identWifiImsi2Key1 = buildNetworkIdentity(
173                 mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_WIFI_KEY1), true, 0)
174         val identWifiImsi1Key2 = buildNetworkIdentity(
175                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY2), true, 0)
176         // This identity with a null wifiNetworkKey is to test the matchesWifiNetworkKey won't crash
177         // the system when a null wifiNetworkKey is provided, which would happen in some unknown
178         // cases, see b/266598304.
179         val identWifiNullKey = buildNetworkIdentity(
180                 mockContext, buildWifiNetworkState(null /* subscriberId */,
181                 null /* wifiNetworkKey */), true, 0)
182 
183         // Verify that template with WiFi Network Key only matches any subscriberId and
184         // specific WiFi Network Key.
185         templateWifiKey1.assertDoesNotMatch(identMobile1)
186         templateWifiKey1.assertMatches(identWifiImsiNullKey1)
187         templateWifiKey1.assertMatches(identWifiImsi1Key1)
188         templateWifiKey1.assertMatches(identWifiImsi2Key1)
189         templateWifiKey1.assertDoesNotMatch(identWifiImsi1Key2)
190 
191         // Verify that template with WiFi Network Key1 and null imsi matches any network with
192         // WiFi Network Key1 and null imsi.
193         templateWifiKey1ImsiNull.assertDoesNotMatch(identMobile1)
194         templateWifiKey1ImsiNull.assertMatches(identWifiImsiNullKey1)
195         templateWifiKey1ImsiNull.assertDoesNotMatch(identWifiImsi1Key1)
196         templateWifiKey1ImsiNull.assertDoesNotMatch(identWifiImsi2Key1)
197         templateWifiKey1ImsiNull.assertDoesNotMatch(identWifiImsi1Key2)
198 
199         // Verify that template with WiFi Network Key1 and imsi1 matches any network with
200         // WiFi Network Key1 and imsi1.
201         templateWifiKey1Imsi1.assertDoesNotMatch(identMobile1)
202         templateWifiKey1Imsi1.assertDoesNotMatch(identWifiImsiNullKey1)
203         templateWifiKey1Imsi1.assertMatches(identWifiImsi1Key1)
204         templateWifiKey1Imsi1.assertDoesNotMatch(identWifiImsi2Key1)
205         templateWifiKey1Imsi1.assertDoesNotMatch(identWifiImsi1Key2)
206 
207         // Verify that template with WiFi Network Key all and imsi1 matches any network with
208         // any WiFi Network Key and imsi1.
209         templateWifiKeyAllImsi1.assertDoesNotMatch(identMobile1)
210         templateWifiKeyAllImsi1.assertDoesNotMatch(identWifiImsiNullKey1)
211         templateWifiKeyAllImsi1.assertMatches(identWifiImsi1Key1)
212         templateWifiKeyAllImsi1.assertDoesNotMatch(identWifiImsi2Key1)
213         templateWifiKeyAllImsi1.assertMatches(identWifiImsi1Key2)
214 
215         // Test a network identity with null wifiNetworkKey won't crash.
216         // It should not match a template with wifiNetworkKeys is non-null.
217         // Also, it should not match a template with wifiNetworkKeys that contains null.
218         templateWifiKey1.assertDoesNotMatch(identWifiNullKey)
219         templateNullWifiKey.assertDoesNotMatch(identWifiNullKey)
220     }
221 
222     @DevSdkIgnoreRule.IgnoreAfter(Build.VERSION_CODES.TIRAMISU)
223     @Test
testBuildTemplateMobileAll_nullSubscriberIdnull224     fun testBuildTemplateMobileAll_nullSubscriberId() {
225         val templateMobileAllWithNullImsi =
226                 buildTemplateMobileAll(NonNullTestUtils.nullUnsafe<String>(null))
227         val setWithNull = HashSet<String?>().apply {
228             add(null)
229         }
230         val templateFromBuilder = NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES)
231                 .setSubscriberIds(setWithNull).build()
232         assertEquals(templateFromBuilder, templateMobileAllWithNullImsi)
233     }
234 
235     @Test
testMobileMatchesnull236     fun testMobileMatches() {
237         val templateMobileImsi1 = buildTemplateMobileAll(TEST_IMSI1)
238         val templateMobileImsi2WithRatType = NetworkTemplate.Builder(MATCH_MOBILE)
239                 .setMeteredness(METERED_YES)
240                 .setSubscriberIds(setOf(TEST_IMSI2))
241                 .setRatType(TelephonyManager.NETWORK_TYPE_UMTS).build()
242 
243         val mobileImsi1 = buildNetworkState(TYPE_MOBILE, TEST_IMSI1, null /* wifiKey */,
244                 OEM_NONE, true /* metered */)
245         val identMobile1 = buildNetworkIdentity(mockContext, mobileImsi1,
246                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
247         val mobileImsi2 = buildMobileNetworkState(TEST_IMSI2)
248         val identMobile2Umts = buildNetworkIdentity(mockContext, mobileImsi2,
249                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
250 
251         val identWifiImsi1Key1 = buildNetworkIdentity(
252                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
253 
254         // Verify that the template matches type and the subscriberId.
255         templateMobileImsi1.assertMatches(identMobile1)
256         templateMobileImsi2WithRatType.assertMatches(identMobile2Umts)
257 
258         // Verify that the template does not match the different subscriberId.
259         templateMobileImsi1.assertDoesNotMatch(identMobile2Umts)
260         templateMobileImsi2WithRatType.assertDoesNotMatch(identMobile1)
261 
262         // Verify that the different type does not match.
263         templateMobileImsi1.assertDoesNotMatch(identWifiImsi1Key1)
264     }
265 
266     @Test
testMobileWildcardMatchesnull267     fun testMobileWildcardMatches() {
268         val templateMobileWildcard = buildTemplateMobileWildcard()
269         val templateMobileNullImsiWithRatType = NetworkTemplate.Builder(MATCH_MOBILE)
270                 .setRatType(TelephonyManager.NETWORK_TYPE_UMTS).build()
271         val mobileImsi1 = buildMobileNetworkState(TEST_IMSI1)
272         val identMobile1 = buildNetworkIdentity(mockContext, mobileImsi1,
273                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
274         val mobileImsi2 = buildMobileNetworkState(TEST_IMSI2)
275         val identMobile2 = buildNetworkIdentity(mockContext, mobileImsi2,
276                 false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_LTE)
277 
278         // Verify that the template matches any subscriberId.
279         templateMobileWildcard.assertMatches(identMobile1)
280         templateMobileNullImsiWithRatType.assertMatches(identMobile1)
281         templateMobileWildcard.assertMatches(identMobile2)
282         templateMobileNullImsiWithRatType.assertDoesNotMatch(identMobile2)
283 
284         val identWifiImsi1Key1 = buildNetworkIdentity(
285                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
286 
287         // Verify that the different type does not match.
288         templateMobileWildcard.assertDoesNotMatch(identWifiImsi1Key1)
289         templateMobileNullImsiWithRatType.assertDoesNotMatch(identWifiImsi1Key1)
290     }
291 
292     @Test
testTestNetworkTemplateMatchesnull293     fun testTestNetworkTemplateMatches() {
294         val templateTestKey1 = NetworkTemplate.Builder(MATCH_TEST)
295             .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
296         val templateTestKey2 = NetworkTemplate.Builder(MATCH_TEST)
297             .setWifiNetworkKeys(setOf(TEST_WIFI_KEY2)).build()
298         val templateTestAll = NetworkTemplate.Builder(MATCH_TEST).build()
299 
300         val stateWifiKey1 = buildNetworkState(TYPE_WIFI, null /* subscriberId */, TEST_WIFI_KEY1,
301             OEM_NONE, true /* metered */)
302         val stateTestKey1 = buildNetworkState(TYPE_TEST, null /* subscriberId */, TEST_WIFI_KEY1,
303             OEM_NONE, true /* metered */)
304         val identWifi1 = buildNetworkIdentity(mockContext, stateWifiKey1,
305             false /* defaultNetwork */, NetworkTemplate.NETWORK_TYPE_ALL)
306         val identTest1 = buildNetworkIdentity(mockContext, stateTestKey1,
307             false /* defaultNetwork */, NETWORK_TYPE_ALL)
308 
309         // Verify that the template matches corresponding type and the subscriberId.
310         templateTestKey1.assertDoesNotMatch(identWifi1)
311         templateTestKey1.assertMatches(identTest1)
312         templateTestKey2.assertDoesNotMatch(identWifi1)
313         templateTestKey2.assertDoesNotMatch(identTest1)
314         templateTestAll.assertDoesNotMatch(identWifi1)
315         templateTestAll.assertMatches(identTest1)
316     }
317 
318     @Test
testCarrierMeteredMatchesnull319     fun testCarrierMeteredMatches() {
320         val templateCarrierImsi1Metered = NetworkTemplate.Builder(MATCH_CARRIER)
321                 .setMeteredness(METERED_YES)
322                 .setSubscriberIds(setOf(TEST_IMSI1)).build()
323 
324         val mobileImsi1 = buildMobileNetworkState(TEST_IMSI1)
325         val mobileImsi1Unmetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI1,
326                 null /* wifiKey */, OEM_NONE, false /* metered */)
327         val mobileImsi2 = buildMobileNetworkState(TEST_IMSI2)
328         val wifiKey1 = buildWifiNetworkState(null /* subscriberId */,
329                 TEST_WIFI_KEY1)
330         val wifiImsi1Key1 = buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1)
331         val wifiImsi1Key1Unmetered = buildNetworkState(TYPE_WIFI, TEST_IMSI1,
332                 TEST_WIFI_KEY1, OEM_NONE, false /* metered */)
333 
334         val identMobileImsi1Metered = buildNetworkIdentity(mockContext,
335                 mobileImsi1, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
336         val identMobileImsi1Unmetered = buildNetworkIdentity(mockContext,
337                 mobileImsi1Unmetered, false /* defaultNetwork */,
338                 TelephonyManager.NETWORK_TYPE_UMTS)
339         val identMobileImsi2Metered = buildNetworkIdentity(mockContext,
340                 mobileImsi2, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
341         val identWifiKey1Metered = buildNetworkIdentity(
342                 mockContext, wifiKey1, true /* defaultNetwork */, 0 /* subType */)
343         val identCarrierWifiImsi1Metered = buildNetworkIdentity(
344                 mockContext, wifiImsi1Key1, true /* defaultNetwork */, 0 /* subType */)
345         val identCarrierWifiImsi1NonMetered = buildNetworkIdentity(mockContext,
346                 wifiImsi1Key1Unmetered, true /* defaultNetwork */, 0 /* subType */)
347 
348         templateCarrierImsi1Metered.assertMatches(identMobileImsi1Metered)
349         templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi1Unmetered)
350         templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi2Metered)
351         templateCarrierImsi1Metered.assertDoesNotMatch(identWifiKey1Metered)
352         templateCarrierImsi1Metered.assertMatches(identCarrierWifiImsi1Metered)
353         templateCarrierImsi1Metered.assertDoesNotMatch(identCarrierWifiImsi1NonMetered)
354     }
355 
356     // TODO: Refactor this test to reduce the line of codes.
357     @Test
testRatTypeGroupMatchesnull358     fun testRatTypeGroupMatches() {
359         val stateMobileImsi1Metered = buildMobileNetworkState(TEST_IMSI1)
360         val stateMobileImsi1NonMetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI1,
361                 null /* wifiKey */, OEM_NONE, false /* metered */)
362         val stateMobileImsi2NonMetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI2,
363                 null /* wifiKey */, OEM_NONE, false /* metered */)
364 
365         // Build UMTS template that matches mobile identities with RAT in the same
366         // group with any IMSI. See {@link NetworkTemplate#getCollapsedRatType}.
367         val templateUmtsMetered = NetworkTemplate.Builder(MATCH_MOBILE)
368                 .setMeteredness(METERED_YES)
369                 .setRatType(TelephonyManager.NETWORK_TYPE_UMTS).build()
370         // Build normal template that matches mobile identities with any RAT and IMSI.
371         val templateAllMetered = NetworkTemplate.Builder(MATCH_MOBILE)
372                 .setMeteredness(METERED_YES).build()
373         // Build template with UNKNOWN RAT that matches mobile identities with RAT that
374         // cannot be determined.
375         val templateUnknownMetered = NetworkTemplate.Builder(MATCH_MOBILE)
376                 .setMeteredness(METERED_YES)
377                 .setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN).build()
378         val templateUmtsNonMetered = NetworkTemplate.Builder(MATCH_MOBILE)
379                 .setMeteredness(METERED_NO)
380                 .setRatType(TelephonyManager.NETWORK_TYPE_UMTS).build()
381         val templateAllNonMetered = NetworkTemplate.Builder(MATCH_MOBILE)
382                 .setMeteredness(METERED_NO).build()
383         val templateUnknownNonMetered = NetworkTemplate.Builder(MATCH_MOBILE)
384                 .setMeteredness(METERED_NO)
385                 .setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN).build()
386 
387         val identUmtsMetered = buildNetworkIdentity(
388                 mockContext, stateMobileImsi1Metered, false, TelephonyManager.NETWORK_TYPE_UMTS)
389         val identHsdpaMetered = buildNetworkIdentity(
390                 mockContext, stateMobileImsi1Metered, false, TelephonyManager.NETWORK_TYPE_HSDPA)
391         val identLteMetered = buildNetworkIdentity(
392                 mockContext, stateMobileImsi1Metered, false, TelephonyManager.NETWORK_TYPE_LTE)
393         val identCombinedMetered = buildNetworkIdentity(
394                 mockContext, stateMobileImsi1Metered, false, NetworkTemplate.NETWORK_TYPE_ALL)
395         val identImsi2UmtsMetered = buildNetworkIdentity(mockContext,
396                 buildMobileNetworkState(TEST_IMSI2), false, TelephonyManager.NETWORK_TYPE_UMTS)
397         val identWifi = buildNetworkIdentity(
398                 mockContext, buildWifiNetworkState(null, TEST_WIFI_KEY1), true, 0)
399 
400         val identUmtsNonMetered = buildNetworkIdentity(
401                 mockContext, stateMobileImsi1NonMetered, false, TelephonyManager.NETWORK_TYPE_UMTS)
402         val identHsdpaNonMetered = buildNetworkIdentity(
403                 mockContext, stateMobileImsi1NonMetered, false,
404                 TelephonyManager.NETWORK_TYPE_HSDPA)
405         val identLteNonMetered = buildNetworkIdentity(
406                 mockContext, stateMobileImsi1NonMetered, false, TelephonyManager.NETWORK_TYPE_LTE)
407         val identCombinedNonMetered = buildNetworkIdentity(
408                 mockContext, stateMobileImsi1NonMetered, false, NetworkTemplate.NETWORK_TYPE_ALL)
409         val identImsi2UmtsNonMetered = buildNetworkIdentity(mockContext,
410                 stateMobileImsi2NonMetered, false, TelephonyManager.NETWORK_TYPE_UMTS)
411 
412         // Assert that identity with the same RAT and meteredness matches.
413         // Verify metered template.
414         templateUmtsMetered.assertMatches(identUmtsMetered)
415         templateAllMetered.assertMatches(identUmtsMetered)
416         templateUnknownMetered.assertDoesNotMatch(identUmtsMetered)
417         // Verify non-metered template.
418         templateUmtsNonMetered.assertMatches(identUmtsNonMetered)
419         templateAllNonMetered.assertMatches(identUmtsNonMetered)
420         templateUnknownNonMetered.assertDoesNotMatch(identUmtsNonMetered)
421 
422         // Assert that identity with the same RAT but meteredness is different.
423         // Thus, it does not match.
424         templateUmtsNonMetered.assertDoesNotMatch(identUmtsMetered)
425         templateAllNonMetered.assertDoesNotMatch(identUmtsMetered)
426 
427         // Assert that identity with the RAT within the same group matches.
428         // Verify metered template.
429         templateUmtsMetered.assertMatches(identHsdpaMetered)
430         templateAllMetered.assertMatches(identHsdpaMetered)
431         templateUnknownMetered.assertDoesNotMatch(identHsdpaMetered)
432         // Verify non-metered template.
433         templateUmtsNonMetered.assertMatches(identHsdpaNonMetered)
434         templateAllNonMetered.assertMatches(identHsdpaNonMetered)
435         templateUnknownNonMetered.assertDoesNotMatch(identHsdpaNonMetered)
436 
437         // Assert that identity with the RAT out of the same group only matches template with
438         // NETWORK_TYPE_ALL.
439         // Verify metered template.
440         templateUmtsMetered.assertDoesNotMatch(identLteMetered)
441         templateAllMetered.assertMatches(identLteMetered)
442         templateUnknownMetered.assertDoesNotMatch(identLteMetered)
443         // Verify non-metered template.
444         templateUmtsNonMetered.assertDoesNotMatch(identLteNonMetered)
445         templateAllNonMetered.assertMatches(identLteNonMetered)
446         templateUnknownNonMetered.assertDoesNotMatch(identLteNonMetered)
447         // Verify non-metered template does not match identity with metered.
448         templateAllNonMetered.assertDoesNotMatch(identLteMetered)
449 
450         // Assert that identity with combined RAT only matches with template with NETWORK_TYPE_ALL
451         // and NETWORK_TYPE_UNKNOWN.
452         // Verify metered template.
453         templateUmtsMetered.assertDoesNotMatch(identCombinedMetered)
454         templateAllMetered.assertMatches(identCombinedMetered)
455         templateUnknownMetered.assertMatches(identCombinedMetered)
456         // Verify non-metered template.
457         templateUmtsNonMetered.assertDoesNotMatch(identCombinedNonMetered)
458         templateAllNonMetered.assertMatches(identCombinedNonMetered)
459         templateUnknownNonMetered.assertMatches(identCombinedNonMetered)
460         // Verify that identity with metered does not match non-metered template.
461         templateAllNonMetered.assertDoesNotMatch(identCombinedMetered)
462         templateUnknownNonMetered.assertDoesNotMatch(identCombinedMetered)
463 
464         // Assert that identity with different IMSI matches.
465         // Verify metered template.
466         templateUmtsMetered.assertMatches(identImsi2UmtsMetered)
467         templateAllMetered.assertMatches(identImsi2UmtsMetered)
468         templateUnknownMetered.assertDoesNotMatch(identImsi2UmtsMetered)
469         // Verify non-metered template.
470         templateUmtsNonMetered.assertMatches(identImsi2UmtsNonMetered)
471         templateAllNonMetered.assertMatches(identImsi2UmtsNonMetered)
472         templateUnknownNonMetered.assertDoesNotMatch(identImsi2UmtsNonMetered)
473         // Verify that the same RAT but different meteredness should not match.
474         templateUmtsNonMetered.assertDoesNotMatch(identImsi2UmtsMetered)
475         templateAllNonMetered.assertDoesNotMatch(identImsi2UmtsMetered)
476 
477         // Assert that wifi identity does not match.
478         templateUmtsMetered.assertDoesNotMatch(identWifi)
479         templateUnknownMetered.assertDoesNotMatch(identWifi)
480         templateUmtsNonMetered.assertDoesNotMatch(identWifi)
481         templateUnknownNonMetered.assertDoesNotMatch(identWifi)
482     }
483 
484     @Test
testEqualsnull485     fun testEquals() {
486         val templateImsi1 = NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES)
487                 .setSubscriberIds(setOf(TEST_IMSI1)).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
488                 .build()
489         val dupTemplateImsi1 = NetworkTemplate(MATCH_MOBILE, arrayOf(TEST_IMSI1),
490                 emptyArray<String>(), METERED_YES, ROAMING_ALL, DEFAULT_NETWORK_ALL,
491                 TelephonyManager.NETWORK_TYPE_UMTS, OEM_MANAGED_ALL)
492         val templateImsi2 = NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES)
493                 .setSubscriberIds(setOf(TEST_IMSI2)).setRatType(TelephonyManager.NETWORK_TYPE_UMTS)
494                 .build()
495 
496         assertEquals(templateImsi1, dupTemplateImsi1)
497         assertEquals(dupTemplateImsi1, templateImsi1)
498         assertNotEquals(templateImsi1, templateImsi2)
499 
500         val templateWifiKey1 = NetworkTemplate.Builder(MATCH_WIFI)
501                 .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
502         val dupTemplateWifiKey1 = NetworkTemplate(MATCH_WIFI, emptyArray<String>(),
503                 arrayOf(TEST_WIFI_KEY1), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
504                 NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
505         val templateWifiKey2 = NetworkTemplate.Builder(MATCH_WIFI)
506                 .setWifiNetworkKeys(setOf(TEST_WIFI_KEY2)).build()
507 
508         assertEquals(templateWifiKey1, dupTemplateWifiKey1)
509         assertEquals(dupTemplateWifiKey1, templateWifiKey1)
510         assertNotEquals(templateWifiKey1, templateWifiKey2)
511     }
512 
513     @Test
testParcelUnparcelnull514     fun testParcelUnparcel() {
515         val templateMobile = NetworkTemplate(MATCH_MOBILE, arrayOf(TEST_IMSI1),
516                 emptyArray<String>(), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
517                 TelephonyManager.NETWORK_TYPE_LTE, OEM_MANAGED_ALL)
518         val templateWifi = NetworkTemplate(MATCH_WIFI, emptyArray<String>(),
519                 arrayOf(TEST_WIFI_KEY1), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, 0,
520                 OEM_MANAGED_ALL)
521         val templateOem = NetworkTemplate(MATCH_MOBILE, emptyArray<String>(),
522                 emptyArray<String>(), METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, 0,
523                 OEM_MANAGED_YES)
524         assertParcelSane(templateMobile, 8)
525         assertParcelSane(templateWifi, 8)
526         assertParcelSane(templateOem, 8)
527     }
528 
529     // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
530     // TelephonyManager#NETWORK_TYPE_* constants.
531     @Test
testNetworkTypeConstantsnull532     fun testNetworkTypeConstants() {
533         for (ratType in TelephonyManager.getAllNetworkTypes()) {
534             assertNotEquals(NETWORK_TYPE_ALL, ratType)
535             assertNotEquals(NETWORK_TYPE_5G_NSA, ratType)
536         }
537     }
538 
539     @Test
testOemNetworkConstantsnull540     fun testOemNetworkConstants() {
541         val constantValues = arrayOf(OEM_MANAGED_YES, OEM_MANAGED_ALL, OEM_MANAGED_NO,
542                 OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
543 
544         // Verify that "not OEM managed network" constants are equal.
545         assertEquals(OEM_MANAGED_NO, OEM_NONE)
546 
547         // Verify the constants don't conflict.
548         assertEquals(constantValues.size, constantValues.distinct().count())
549     }
550 
551     /**
552      * Helper to enumerate and assert OEM managed wifi and mobile {@code NetworkTemplate}s match
553      * their the appropriate OEM managed {@code NetworkIdentity}s.
554      *
555      * @param networkType {@code TYPE_MOBILE} or {@code TYPE_WIFI}
556      * @param matchType A match rule from {@code NetworkTemplate.MATCH_*} corresponding to the
557      *         networkType.
558      * @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is
559      *         {@code TYPE_MOBILE}. Note that {@code MATCH_MOBILE} with an empty subscriberId list
560      *         will match any subscriber ID.
561      * @param templateWifiKey To be populated with {@code TEST_WIFI_KEY*} only if networkType is
562      *         {@code TYPE_WIFI}. Note that {@code MATCH_WIFI} with both an empty subscriberId list
563      *         and an empty wifiNetworkKey list will match any subscriber ID and/or any wifi network
564      *         key.
565      * @param identWifiKey If networkType is {@code TYPE_WIFI}, this value must *NOT* be null.
566      *         Provide one of {@code TEST_WIFI_KEY*}.
567      */
matchOemManagedIdentnull568     private fun matchOemManagedIdent(
569         networkType: Int,
570         matchType: Int,
571         subscriberId: String? = null,
572         templateWifiKey: String? = null,
573         identWifiKey: String? = null
574     ) {
575         val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
576         val matchSubscriberIds =
577                 if (subscriberId == null) emptyArray<String>() else arrayOf(subscriberId)
578         val matchWifiNetworkKeys =
579                 if (templateWifiKey == null) emptyArray<String>() else arrayOf(templateWifiKey)
580 
581         val templateOemYes = NetworkTemplate(matchType, matchSubscriberIds,
582                 matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
583                 DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES)
584         val templateOemAll = NetworkTemplate(matchType, matchSubscriberIds,
585                 matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
586                 DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL)
587 
588         for (identityOemManagedState in oemManagedStates) {
589             val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType,
590                     subscriberId, identWifiKey, identityOemManagedState),
591                     /*defaultNetwork=*/false, /*subType=*/0)
592 
593             // Create a template with each OEM managed type and match it against the NetworkIdentity
594             for (templateOemManagedState in oemManagedStates) {
595                 val template = NetworkTemplate(matchType, matchSubscriberIds,
596                         matchWifiNetworkKeys, METERED_ALL, ROAMING_ALL,
597                         DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, templateOemManagedState)
598                 if (identityOemManagedState == templateOemManagedState) {
599                     template.assertMatches(ident)
600                 } else {
601                     template.assertDoesNotMatch(ident)
602                 }
603             }
604             // OEM_MANAGED_ALL ignores OEM state.
605             templateOemAll.assertMatches(ident)
606             if (identityOemManagedState == OEM_NONE) {
607                 // OEM_MANAGED_YES matches everything except OEM_NONE.
608                 templateOemYes.assertDoesNotMatch(ident)
609             } else {
610                 templateOemYes.assertMatches(ident)
611             }
612         }
613     }
614 
615     @Test
testOemManagedMatchesIdentnull616     fun testOemManagedMatchesIdent() {
617         matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1)
618         matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE)
619         matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateWifiKey = TEST_WIFI_KEY1,
620                 identWifiKey = TEST_WIFI_KEY1)
621         matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, identWifiKey = TEST_WIFI_KEY1)
622     }
623 
624     @Test
testNormalizenull625     fun testNormalize() {
626         var mergedImsiList = arrayOf(TEST_IMSI1, TEST_IMSI2)
627         val identMobileImsi1 = buildNetworkIdentity(mockContext,
628                 buildMobileNetworkState(TEST_IMSI1), false /* defaultNetwork */,
629                 TelephonyManager.NETWORK_TYPE_UMTS)
630         val identMobileImsi2 = buildNetworkIdentity(mockContext,
631                 buildMobileNetworkState(TEST_IMSI2), false /* defaultNetwork */,
632                 TelephonyManager.NETWORK_TYPE_UMTS)
633         val identMobileImsi3 = buildNetworkIdentity(mockContext,
634                 buildMobileNetworkState(TEST_IMSI3), false /* defaultNetwork */,
635                 TelephonyManager.NETWORK_TYPE_UMTS)
636         val identWifiImsi1Key1 = buildNetworkIdentity(
637                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_WIFI_KEY1), true, 0)
638         val identWifiImsi2Key1 = buildNetworkIdentity(
639                 mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_WIFI_KEY1), true, 0)
640         val identWifiImsi3WifiKey1 = buildNetworkIdentity(
641                 mockContext, buildWifiNetworkState(TEST_IMSI3, TEST_WIFI_KEY1), true, 0)
642 
643         normalize(buildTemplateMobileAll(TEST_IMSI1), mergedImsiList).also {
644             it.assertMatches(identMobileImsi1)
645             it.assertMatches(identMobileImsi2)
646             it.assertDoesNotMatch(identMobileImsi3)
647         }
648         val templateCarrierImsi1 = NetworkTemplate.Builder(MATCH_CARRIER)
649                 .setMeteredness(METERED_YES)
650                 .setSubscriberIds(setOf(TEST_IMSI1)).build()
651         normalize(templateCarrierImsi1, mergedImsiList).also {
652             it.assertMatches(identMobileImsi1)
653             it.assertMatches(identMobileImsi2)
654             it.assertDoesNotMatch(identMobileImsi3)
655         }
656         val templateWifiKey1Imsi1 = NetworkTemplate.Builder(MATCH_WIFI)
657                 .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1))
658                 .setSubscriberIds(setOf(TEST_IMSI1)).build()
659         normalize(templateWifiKey1Imsi1, mergedImsiList).also {
660             it.assertMatches(identWifiImsi1Key1)
661             it.assertMatches(identWifiImsi2Key1)
662             it.assertDoesNotMatch(identWifiImsi3WifiKey1)
663         }
664         normalize(buildTemplateMobileWildcard(), mergedImsiList).also {
665             it.assertMatches(identMobileImsi1)
666             it.assertMatches(identMobileImsi2)
667             it.assertMatches(identMobileImsi3)
668         }
669     }
670 }
671