• 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.content.Context
20 import android.net.ConnectivityManager.TYPE_MOBILE
21 import android.net.ConnectivityManager.TYPE_WIFI
22 import android.net.NetworkIdentity.OEM_NONE
23 import android.net.NetworkIdentity.OEM_PAID
24 import android.net.NetworkIdentity.OEM_PRIVATE
25 import android.net.NetworkIdentity.SUBTYPE_COMBINED
26 import android.net.NetworkIdentity.buildNetworkIdentity
27 import android.net.NetworkStats.DEFAULT_NETWORK_ALL
28 import android.net.NetworkStats.METERED_ALL
29 import android.net.NetworkStats.ROAMING_ALL
30 import android.net.NetworkTemplate.MATCH_MOBILE
31 import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
32 import android.net.NetworkTemplate.MATCH_WIFI
33 import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
34 import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA
35 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
36 import android.net.NetworkTemplate.OEM_MANAGED_ALL
37 import android.net.NetworkTemplate.OEM_MANAGED_NO
38 import android.net.NetworkTemplate.OEM_MANAGED_YES
39 import android.net.NetworkTemplate.SUBSCRIBER_ID_MATCH_RULE_EXACT
40 import android.net.NetworkTemplate.WIFI_NETWORKID_ALL
41 import android.net.NetworkTemplate.buildTemplateCarrierMetered
42 import android.net.NetworkTemplate.buildTemplateMobileWithRatType
43 import android.net.NetworkTemplate.buildTemplateWifi
44 import android.net.NetworkTemplate.buildTemplateWifiWildcard
45 import android.os.Build
46 import android.telephony.TelephonyManager
47 import com.android.testutils.DevSdkIgnoreRule
48 import com.android.testutils.DevSdkIgnoreRunner
49 import com.android.testutils.assertParcelSane
50 import org.junit.Before
51 import org.junit.Test
52 import org.junit.runner.RunWith
53 import org.mockito.Mockito.mock
54 import org.mockito.MockitoAnnotations
55 import kotlin.test.assertEquals
56 import kotlin.test.assertFalse
57 import kotlin.test.assertNotEquals
58 import kotlin.test.assertTrue
59 
60 private const val TEST_IMSI1 = "imsi1"
61 private const val TEST_IMSI2 = "imsi2"
62 private const val TEST_SSID1 = "ssid1"
63 private const val TEST_SSID2 = "ssid2"
64 
65 @RunWith(DevSdkIgnoreRunner::class)
66 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
67 class NetworkTemplateTest {
68     private val mockContext = mock(Context::class.java)
69 
buildMobileNetworkStatenull70     private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot =
71             buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
72     private fun buildWifiNetworkState(subscriberId: String?, ssid: String?): NetworkStateSnapshot =
73             buildNetworkState(TYPE_WIFI, subscriberId = subscriberId, ssid = ssid)
74 
75     private fun buildNetworkState(
76         type: Int,
77         subscriberId: String? = null,
78         ssid: String? = null,
79         oemManaged: Int = OEM_NONE,
80         metered: Boolean = true
81     ): NetworkStateSnapshot {
82         val lp = LinkProperties()
83         val caps = NetworkCapabilities().apply {
84             setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !metered)
85             setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
86             setSSID(ssid)
87             setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID,
88                     (oemManaged and OEM_PAID) == OEM_PAID)
89             setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
90                     (oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
91         }
92         return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
93     }
94 
NetworkTemplatenull95     private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) =
96             assertTrue(matches(ident), "$this does not match $ident")
97 
98     private fun NetworkTemplate.assertDoesNotMatch(ident: NetworkIdentity) =
99             assertFalse(matches(ident), "$this should match $ident")
100 
101     @Before
102     fun setup() {
103         MockitoAnnotations.initMocks(this)
104     }
105 
106     @Test
testWifiWildcardMatchesnull107     fun testWifiWildcardMatches() {
108         val templateWifiWildcard = buildTemplateWifiWildcard()
109 
110         val identMobileImsi1 = buildNetworkIdentity(mockContext,
111                 buildMobileNetworkState(TEST_IMSI1),
112                 false, TelephonyManager.NETWORK_TYPE_UMTS)
113         val identWifiImsiNullSsid1 = buildNetworkIdentity(
114                 mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
115         val identWifiImsi1Ssid1 = buildNetworkIdentity(
116                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
117 
118         templateWifiWildcard.assertDoesNotMatch(identMobileImsi1)
119         templateWifiWildcard.assertMatches(identWifiImsiNullSsid1)
120         templateWifiWildcard.assertMatches(identWifiImsi1Ssid1)
121     }
122 
123     @Test
testWifiMatchesnull124     fun testWifiMatches() {
125         val templateWifiSsid1 = buildTemplateWifi(TEST_SSID1)
126         val templateWifiSsid1ImsiNull = buildTemplateWifi(TEST_SSID1, null)
127         val templateWifiSsid1Imsi1 = buildTemplateWifi(TEST_SSID1, TEST_IMSI1)
128         val templateWifiSsidAllImsi1 = buildTemplateWifi(WIFI_NETWORKID_ALL, TEST_IMSI1)
129 
130         val identMobile1 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI1),
131                 false, TelephonyManager.NETWORK_TYPE_UMTS)
132         val identWifiImsiNullSsid1 = buildNetworkIdentity(
133                 mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
134         val identWifiImsi1Ssid1 = buildNetworkIdentity(
135                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID1), true, 0)
136         val identWifiImsi2Ssid1 = buildNetworkIdentity(
137                 mockContext, buildWifiNetworkState(TEST_IMSI2, TEST_SSID1), true, 0)
138         val identWifiImsi1Ssid2 = buildNetworkIdentity(
139                 mockContext, buildWifiNetworkState(TEST_IMSI1, TEST_SSID2), true, 0)
140 
141         // Verify that template with SSID only matches any subscriberId and specific SSID.
142         templateWifiSsid1.assertDoesNotMatch(identMobile1)
143         templateWifiSsid1.assertMatches(identWifiImsiNullSsid1)
144         templateWifiSsid1.assertMatches(identWifiImsi1Ssid1)
145         templateWifiSsid1.assertMatches(identWifiImsi2Ssid1)
146         templateWifiSsid1.assertDoesNotMatch(identWifiImsi1Ssid2)
147 
148         // Verify that template with SSID1 and null imsi matches any network with
149         // SSID1 and null imsi.
150         templateWifiSsid1ImsiNull.assertDoesNotMatch(identMobile1)
151         templateWifiSsid1ImsiNull.assertMatches(identWifiImsiNullSsid1)
152         templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid1)
153         templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi2Ssid1)
154         templateWifiSsid1ImsiNull.assertDoesNotMatch(identWifiImsi1Ssid2)
155 
156         // Verify that template with SSID1 and imsi1 matches any network with
157         // SSID1 and imsi1.
158         templateWifiSsid1Imsi1.assertDoesNotMatch(identMobile1)
159         templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsiNullSsid1)
160         templateWifiSsid1Imsi1.assertMatches(identWifiImsi1Ssid1)
161         templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi2Ssid1)
162         templateWifiSsid1Imsi1.assertDoesNotMatch(identWifiImsi1Ssid2)
163 
164         // Verify that template with SSID all and imsi1 matches any network with
165         // any SSID and imsi1.
166         templateWifiSsidAllImsi1.assertDoesNotMatch(identMobile1)
167         templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsiNullSsid1)
168         templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid1)
169         templateWifiSsidAllImsi1.assertDoesNotMatch(identWifiImsi2Ssid1)
170         templateWifiSsidAllImsi1.assertMatches(identWifiImsi1Ssid2)
171     }
172 
173     @Test
testCarrierMeteredMatchesnull174     fun testCarrierMeteredMatches() {
175         val templateCarrierImsi1Metered = buildTemplateCarrierMetered(TEST_IMSI1)
176 
177         val mobileImsi1 = buildMobileNetworkState(TEST_IMSI1)
178         val mobileImsi1Unmetered = buildNetworkState(TYPE_MOBILE, TEST_IMSI1, null /* ssid */,
179                 OEM_NONE, false /* metered */)
180         val mobileImsi2 = buildMobileNetworkState(TEST_IMSI2)
181         val wifiSsid1 = buildWifiNetworkState(null /* subscriberId */, TEST_SSID1)
182         val wifiImsi1Ssid1 = buildWifiNetworkState(TEST_IMSI1, TEST_SSID1)
183         val wifiImsi1Ssid1Unmetered = buildNetworkState(TYPE_WIFI, TEST_IMSI1, TEST_SSID1,
184                 OEM_NONE, false /* metered */)
185 
186         val identMobileImsi1Metered = buildNetworkIdentity(mockContext,
187                 mobileImsi1, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
188         val identMobileImsi1Unmetered = buildNetworkIdentity(mockContext,
189                 mobileImsi1Unmetered, false /* defaultNetwork */,
190                 TelephonyManager.NETWORK_TYPE_UMTS)
191         val identMobileImsi2Metered = buildNetworkIdentity(mockContext,
192                 mobileImsi2, false /* defaultNetwork */, TelephonyManager.NETWORK_TYPE_UMTS)
193         val identWifiSsid1Metered = buildNetworkIdentity(
194                 mockContext, wifiSsid1, true /* defaultNetwork */, 0 /* subType */)
195         val identCarrierWifiImsi1Metered = buildNetworkIdentity(
196                 mockContext, wifiImsi1Ssid1, true /* defaultNetwork */, 0 /* subType */)
197         val identCarrierWifiImsi1NonMetered = buildNetworkIdentity(mockContext,
198                 wifiImsi1Ssid1Unmetered, true /* defaultNetwork */, 0 /* subType */)
199 
200         templateCarrierImsi1Metered.assertMatches(identMobileImsi1Metered)
201         templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi1Unmetered)
202         templateCarrierImsi1Metered.assertDoesNotMatch(identMobileImsi2Metered)
203         templateCarrierImsi1Metered.assertDoesNotMatch(identWifiSsid1Metered)
204         templateCarrierImsi1Metered.assertMatches(identCarrierWifiImsi1Metered)
205         templateCarrierImsi1Metered.assertDoesNotMatch(identCarrierWifiImsi1NonMetered)
206     }
207 
208     @Test
testRatTypeGroupMatchesnull209     fun testRatTypeGroupMatches() {
210         val stateMobile = buildMobileNetworkState(TEST_IMSI1)
211         // Build UMTS template that matches mobile identities with RAT in the same
212         // group with any IMSI. See {@link NetworkTemplate#getCollapsedRatType}.
213         val templateUmts = buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UMTS)
214         // Build normal template that matches mobile identities with any RAT and IMSI.
215         val templateAll = buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL)
216         // Build template with UNKNOWN RAT that matches mobile identities with RAT that
217         // cannot be determined.
218         val templateUnknown =
219                 buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN)
220 
221         val identUmts = buildNetworkIdentity(
222                 mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_UMTS)
223         val identHsdpa = buildNetworkIdentity(
224                 mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_HSDPA)
225         val identLte = buildNetworkIdentity(
226                 mockContext, stateMobile, false, TelephonyManager.NETWORK_TYPE_LTE)
227         val identCombined = buildNetworkIdentity(
228                 mockContext, stateMobile, false, SUBTYPE_COMBINED)
229         val identImsi2 = buildNetworkIdentity(mockContext, buildMobileNetworkState(TEST_IMSI2),
230                 false, TelephonyManager.NETWORK_TYPE_UMTS)
231         val identWifi = buildNetworkIdentity(
232                 mockContext, buildWifiNetworkState(null, TEST_SSID1), true, 0)
233 
234         // Assert that identity with the same RAT matches.
235         templateUmts.assertMatches(identUmts)
236         templateAll.assertMatches(identUmts)
237         templateUnknown.assertDoesNotMatch(identUmts)
238         // Assert that identity with the RAT within the same group matches.
239         templateUmts.assertMatches(identHsdpa)
240         templateAll.assertMatches(identHsdpa)
241         templateUnknown.assertDoesNotMatch(identHsdpa)
242         // Assert that identity with the RAT out of the same group only matches template with
243         // NETWORK_TYPE_ALL.
244         templateUmts.assertDoesNotMatch(identLte)
245         templateAll.assertMatches(identLte)
246         templateUnknown.assertDoesNotMatch(identLte)
247         // Assert that identity with combined RAT only matches with template with NETWORK_TYPE_ALL
248         // and NETWORK_TYPE_UNKNOWN.
249         templateUmts.assertDoesNotMatch(identCombined)
250         templateAll.assertMatches(identCombined)
251         templateUnknown.assertMatches(identCombined)
252         // Assert that identity with different IMSI matches.
253         templateUmts.assertMatches(identImsi2)
254         templateAll.assertMatches(identImsi2)
255         templateUnknown.assertDoesNotMatch(identImsi2)
256         // Assert that wifi identity does not match.
257         templateUmts.assertDoesNotMatch(identWifi)
258         templateAll.assertDoesNotMatch(identWifi)
259         templateUnknown.assertDoesNotMatch(identWifi)
260     }
261 
262     @Test
testParcelUnparcelnull263     fun testParcelUnparcel() {
264         val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL,
265                 ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE,
266                 OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
267         val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL,
268                 ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL,
269                 SUBSCRIBER_ID_MATCH_RULE_EXACT)
270         val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL,
271                 ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES,
272                 SUBSCRIBER_ID_MATCH_RULE_EXACT)
273         assertParcelSane(templateMobile, 10)
274         assertParcelSane(templateWifi, 10)
275         assertParcelSane(templateOem, 10)
276     }
277 
278     // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
279     // TelephonyManager#NETWORK_TYPE_* constants.
280     @Test
testNetworkTypeConstantsnull281     fun testNetworkTypeConstants() {
282         for (ratType in TelephonyManager.getAllNetworkTypes()) {
283             assertNotEquals(NETWORK_TYPE_ALL, ratType)
284             assertNotEquals(NETWORK_TYPE_5G_NSA, ratType)
285         }
286     }
287 
288     @Test
testOemNetworkConstantsnull289     fun testOemNetworkConstants() {
290         val constantValues = arrayOf(OEM_MANAGED_YES, OEM_MANAGED_ALL, OEM_MANAGED_NO,
291                 OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
292 
293         // Verify that "not OEM managed network" constants are equal.
294         assertEquals(OEM_MANAGED_NO, OEM_NONE)
295 
296         // Verify the constants don't conflict.
297         assertEquals(constantValues.size, constantValues.distinct().count())
298     }
299 
300     /**
301      * Helper to enumerate and assert OEM managed wifi and mobile {@code NetworkTemplate}s match
302      * their the appropriate OEM managed {@code NetworkIdentity}s.
303      *
304      * @param networkType {@code TYPE_MOBILE} or {@code TYPE_WIFI}
305      * @param matchType A match rule from {@code NetworkTemplate.MATCH_*} corresponding to the
306      *         networkType.
307      * @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is
308      *         {@code TYPE_MOBILE}. May be left as null when matchType is
309      *         {@link NetworkTemplate.MATCH_MOBILE_WILDCARD}.
310      * @param templateSsid Top be populated with {@code TEST_SSID*} only if networkType is
311      *         {@code TYPE_WIFI}. May be left as null when matchType is
312      *         {@link NetworkTemplate.MATCH_WIFI_WILDCARD}.
313      * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide
314      *         one of {@code TEST_SSID*}.
315      */
matchOemManagedIdentnull316     private fun matchOemManagedIdent(
317         networkType: Int,
318         matchType: Int,
319         subscriberId: String? = null,
320         templateSsid: String? = null,
321         identSsid: String? = null
322     ) {
323         val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
324         val matchSubscriberIds = arrayOf(subscriberId)
325 
326         val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
327                 templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
328                 OEM_MANAGED_YES, SUBSCRIBER_ID_MATCH_RULE_EXACT)
329         val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
330                 templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
331                 OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT)
332 
333         for (identityOemManagedState in oemManagedStates) {
334             val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType,
335                     subscriberId, identSsid, identityOemManagedState), /*defaultNetwork=*/false,
336                     /*subType=*/0)
337 
338             // Create a template with each OEM managed type and match it against the NetworkIdentity
339             for (templateOemManagedState in oemManagedStates) {
340                 val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
341                         templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
342                         NETWORK_TYPE_ALL, templateOemManagedState, SUBSCRIBER_ID_MATCH_RULE_EXACT)
343                 if (identityOemManagedState == templateOemManagedState) {
344                     template.assertMatches(ident)
345                 } else {
346                     template.assertDoesNotMatch(ident)
347                 }
348             }
349             // OEM_MANAGED_ALL ignores OEM state.
350             templateOemAll.assertMatches(ident)
351             if (identityOemManagedState == OEM_NONE) {
352                 // OEM_MANAGED_YES matches everything except OEM_NONE.
353                 templateOemYes.assertDoesNotMatch(ident)
354             } else {
355                 templateOemYes.assertMatches(ident)
356             }
357         }
358     }
359 
360     @Test
testOemManagedMatchesIdentnull361     fun testOemManagedMatchesIdent() {
362         matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1)
363         matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE_WILDCARD)
364         matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateSsid = TEST_SSID1,
365                 identSsid = TEST_SSID1)
366         matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD, identSsid = TEST_SSID1)
367     }
368 }
369