• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 com.android.server
18 
19 import android.net.IpPrefix
20 import android.net.INetd
21 import android.net.LinkAddress
22 import android.net.LinkProperties
23 import android.net.NativeNetworkConfig
24 import android.net.NativeNetworkType
25 import android.net.NetworkCapabilities
26 import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
27 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED
28 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED
29 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING
30 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED
31 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED
32 import android.net.NetworkScore
33 import android.net.NetworkCapabilities.TRANSPORT_SATELLITE
34 import android.net.NetworkScore.KEEP_CONNECTED_FOR_TEST
35 import android.net.RouteInfo
36 import android.net.UidRange
37 import android.net.UidRangeParcel
38 import android.net.VpnManager
39 import android.net.netd.aidl.NativeUidRangeConfig
40 import android.os.Build
41 import android.os.UserHandle
42 import android.util.ArraySet
43 import com.android.net.module.util.CollectionUtils
44 import com.android.server.ConnectivityService.PREFERENCE_ORDER_SATELLITE_FALLBACK
45 import com.android.testutils.DevSdkIgnoreRule
46 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
47 import com.android.testutils.DevSdkIgnoreRunner
48 import com.android.testutils.TestableNetworkCallback
49 import com.android.testutils.visibleOnHandlerThread
50 import org.junit.Assert
51 import org.junit.Rule
52 import org.junit.Test
53 import org.junit.runner.RunWith
54 import org.mockito.ArgumentMatchers.any
55 import org.mockito.Mockito.inOrder
56 import org.mockito.Mockito.never
57 import org.mockito.Mockito.verify
58 import kotlin.test.assertEquals
59 import kotlin.test.assertTrue
60 
61 private const val SECONDARY_USER = 10
62 private val SECONDARY_USER_HANDLE = UserHandle(SECONDARY_USER)
63 private const val TEST_PACKAGE_UID = 123
64 private const val TEST_PACKAGE_UID2 = 321
65 
66 @DevSdkIgnoreRunner.MonitorThreadLeak
67 @RunWith(DevSdkIgnoreRunner::class)
68 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
69 class CSSatelliteNetworkTest : CSTest() {
70     @get:Rule
71     val ignoreRule = DevSdkIgnoreRule()
72 
73     /**
74      * Test createMultiLayerNrisFromSatelliteNetworkPreferredUids returns correct
75      * NetworkRequestInfo.
76      */
77     @Test
testCreateMultiLayerNrisFromSatelliteNetworkPreferredUidsnull78     fun testCreateMultiLayerNrisFromSatelliteNetworkPreferredUids() {
79         // Verify that empty uid set should not create any NRI for it.
80         val nrisNoUid = service.createMultiLayerNrisFromSatelliteNetworkFallbackUids(emptySet())
81         Assert.assertEquals(0, nrisNoUid.size.toLong())
82         val uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)
83         val uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2)
84         val uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)
85         assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(mutableSetOf(uid1))
86         assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(mutableSetOf(uid1, uid3))
87         assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(mutableSetOf(uid1, uid2))
88     }
89 
90     /**
91      * Test that satellite network satisfies satellite fallback per-app default network request and
92      * send correct net id and uid ranges to netd.
93      */
doTestSatelliteNetworkFallbackUidsnull94     private fun doTestSatelliteNetworkFallbackUids(restricted: Boolean) {
95         val netdInOrder = inOrder(netd)
96 
97         val satelliteAgent = createSatelliteAgent("satellite0", restricted)
98         satelliteAgent.connect()
99 
100         val satelliteNetId = satelliteAgent.network.netId
101         val permission = if (restricted) {INetd.PERMISSION_SYSTEM} else {INetd.PERMISSION_NONE}
102         netdInOrder.verify(netd).networkCreate(
103             nativeNetworkConfigPhysical(satelliteNetId, permission))
104 
105         val uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)
106         val uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2)
107         val uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID)
108 
109         // Initial satellite network fallback uids status.
110         updateSatelliteNetworkFallbackUids(setOf())
111         netdInOrder.verify(netd, never()).networkAddUidRangesParcel(any())
112         netdInOrder.verify(netd, never()).networkRemoveUidRangesParcel(any())
113 
114         // Update satellite network fallback uids and verify that net id and uid ranges send to netd
115         var uids = mutableSetOf(uid1, uid2, uid3)
116         val uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids))
117         val config1 = NativeUidRangeConfig(
118             satelliteNetId, uidRanges1,
119             PREFERENCE_ORDER_SATELLITE_FALLBACK
120         )
121         updateSatelliteNetworkFallbackUids(uids)
122         netdInOrder.verify(netd).networkAddUidRangesParcel(config1)
123         netdInOrder.verify(netd, never()).networkRemoveUidRangesParcel(any())
124 
125         // Update satellite network fallback uids and verify that net id and uid ranges send to netd
126         uids = mutableSetOf(uid1)
127         val uidRanges2: Array<UidRangeParcel?> = toUidRangeStableParcels(uidRangesForUids(uids))
128         val config2 = NativeUidRangeConfig(
129             satelliteNetId, uidRanges2,
130             PREFERENCE_ORDER_SATELLITE_FALLBACK
131         )
132         updateSatelliteNetworkFallbackUids(uids)
133         netdInOrder.verify(netd).networkRemoveUidRangesParcel(config1)
134         netdInOrder.verify(netd).networkAddUidRangesParcel(config2)
135     }
136 
137     @Test
testSatelliteNetworkFallbackUids_restrictednull138     fun testSatelliteNetworkFallbackUids_restricted() {
139         doTestSatelliteNetworkFallbackUids(restricted = true)
140     }
141 
142     @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
testSatelliteNetworkFallbackUids_nonRestrictednull143     fun testSatelliteNetworkFallbackUids_nonRestricted() {
144         doTestSatelliteNetworkFallbackUids(restricted = false)
145     }
146 
doTestSatelliteNeverBecomeDefaultNetworknull147     private fun doTestSatelliteNeverBecomeDefaultNetwork(restricted: Boolean) {
148         val agent = createSatelliteAgent("satellite0", restricted)
149         agent.connect()
150         val defaultCb = TestableNetworkCallback()
151         cm.registerDefaultNetworkCallback(defaultCb)
152         // Satellite network must not become the default network
153         defaultCb.assertNoCallback()
154     }
155 
156     @Test
testSatelliteNeverBecomeDefaultNetwork_restrictednull157     fun testSatelliteNeverBecomeDefaultNetwork_restricted() {
158         doTestSatelliteNeverBecomeDefaultNetwork(restricted = true)
159     }
160 
161     @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
testSatelliteNeverBecomeDefaultNetwork_notRestrictednull162     fun testSatelliteNeverBecomeDefaultNetwork_notRestricted() {
163         doTestSatelliteNeverBecomeDefaultNetwork(restricted = false)
164     }
165 
doTestUnregisterAfterReplacementSatisfiernull166     private fun doTestUnregisterAfterReplacementSatisfier(destroyBeforeRequest: Boolean = false,
167                                                           destroyAfterRequest: Boolean = false) {
168         val satelliteAgent = createSatelliteAgent("satellite0")
169         satelliteAgent.connect()
170 
171         if (destroyBeforeRequest) {
172             satelliteAgent.unregisterAfterReplacement(timeoutMs = 5000)
173         }
174 
175         val uids = setOf(TEST_PACKAGE_UID)
176         updateSatelliteNetworkFallbackUids(uids)
177 
178         if (destroyBeforeRequest) {
179             verify(netd, never()).networkAddUidRangesParcel(any())
180         } else {
181             verify(netd).networkAddUidRangesParcel(
182                 NativeUidRangeConfig(
183                     satelliteAgent.network.netId,
184                     toUidRangeStableParcels(uidRangesForUids(uids)),
185                     PREFERENCE_ORDER_SATELLITE_FALLBACK
186                 )
187             )
188         }
189 
190         if (destroyAfterRequest) {
191             satelliteAgent.unregisterAfterReplacement(timeoutMs = 5000)
192         }
193 
194         updateSatelliteNetworkFallbackUids(setOf())
195         if (destroyBeforeRequest || destroyAfterRequest) {
196             // If the network is already destroyed, networkRemoveUidRangesParcel should not be
197             // called.
198             verify(netd, never()).networkRemoveUidRangesParcel(any())
199         } else {
200             verify(netd).networkRemoveUidRangesParcel(
201                     NativeUidRangeConfig(
202                             satelliteAgent.network.netId,
203                             toUidRangeStableParcels(uidRangesForUids(uids)),
204                             PREFERENCE_ORDER_SATELLITE_FALLBACK
205                     )
206             )
207         }
208     }
209 
210     @Test
testUnregisterAfterReplacementSatisfier_destroyBeforeRequestnull211     fun testUnregisterAfterReplacementSatisfier_destroyBeforeRequest() {
212         doTestUnregisterAfterReplacementSatisfier(destroyBeforeRequest = true)
213     }
214 
215     @Test
testUnregisterAfterReplacementSatisfier_destroyAfterRequestnull216     fun testUnregisterAfterReplacementSatisfier_destroyAfterRequest() {
217         doTestUnregisterAfterReplacementSatisfier(destroyAfterRequest = true)
218     }
219 
220     @Test
testUnregisterAfterReplacementSatisfier_notDestroyednull221     fun testUnregisterAfterReplacementSatisfier_notDestroyed() {
222         doTestUnregisterAfterReplacementSatisfier()
223     }
224 
assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUidsnull225     private fun assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(uids: Set<Int>) {
226         val nris: Set<ConnectivityService.NetworkRequestInfo> =
227             service.createMultiLayerNrisFromSatelliteNetworkFallbackUids(uids)
228         val nri = nris.iterator().next()
229         // Verify that one NRI is created with multilayer requests. Because one NRI can contain
230         // multiple uid ranges, so it only need create one NRI here.
231         assertEquals(1, nris.size.toLong())
232         assertTrue(nri.isMultilayerRequest)
233         assertEquals(nri.uids, uidRangesForUids(uids))
234         assertEquals(PREFERENCE_ORDER_SATELLITE_FALLBACK, nri.mPreferenceOrder)
235     }
236 
updateSatelliteNetworkFallbackUidsnull237     private fun updateSatelliteNetworkFallbackUids(uids: Set<Int>) {
238         visibleOnHandlerThread(csHandler) {
239             deps.satelliteNetworkFallbackUidUpdate!!.accept(uids)
240         }
241     }
242 
nativeNetworkConfigPhysicalnull243     private fun nativeNetworkConfigPhysical(netId: Int, permission: Int) =
244         NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission,
245             false /* secure */, VpnManager.TYPE_VPN_NONE, false /* excludeLocalRoutes */)
246 
247     private fun createSatelliteAgent(name: String, restricted: Boolean = true): CSAgentWrapper {
248         return Agent(score = keepScore(), lp = lp(name),
249             nc = satelliteNc(restricted)
250         )
251     }
252 
toUidRangeStableParcelsnull253     private fun toUidRangeStableParcels(ranges: Set<UidRange>): Array<UidRangeParcel?> {
254         val stableRanges = arrayOfNulls<UidRangeParcel>(ranges.size)
255         for ((index, range) in ranges.withIndex()) {
256             stableRanges[index] = UidRangeParcel(range.start, range.stop)
257         }
258         return stableRanges
259     }
260 
uidRangesForUidsnull261     private fun uidRangesForUids(vararg uids: Int): Set<UidRange> {
262         val ranges = ArraySet<UidRange>()
263         for (uid in uids) {
264             ranges.add(UidRange(uid, uid))
265         }
266         return ranges
267     }
268 
uidRangesForUidsnull269     private fun uidRangesForUids(uids: Collection<Int>): Set<UidRange> {
270         return uidRangesForUids(*CollectionUtils.toIntArray(uids))
271     }
272 
satelliteNcnull273     private fun satelliteNc(restricted: Boolean) =
274             NetworkCapabilities.Builder().apply {
275                 addTransportType(TRANSPORT_SATELLITE)
276 
277                 addCapability(NET_CAPABILITY_INTERNET)
278                 addCapability(NET_CAPABILITY_NOT_SUSPENDED)
279                 addCapability(NET_CAPABILITY_NOT_ROAMING)
280                 addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
281                 if (restricted) {
282                     removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
283                 }
284                 removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
285             }.build()
286 
<lambda>null287     private fun lp(iface: String) = LinkProperties().apply {
288         interfaceName = iface
289         addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 32))
290         addRoute(RouteInfo(IpPrefix("0.0.0.0/0"), null, null))
291     }
292 
293     // This allows keeping all the networks connected without having to file individual requests
294     // for them.
keepScorenull295     private fun keepScore() = FromS(
296         NetworkScore.Builder().setKeepConnectedReason(KEEP_CONNECTED_FOR_TEST).build()
297     )
298 }
299