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 kotlin.test.assertEquals 58 import kotlin.test.assertTrue 59 60 private const val SECONDARY_USER = 10 61 private val SECONDARY_USER_HANDLE = UserHandle(SECONDARY_USER) 62 private const val TEST_PACKAGE_UID = 123 63 private const val TEST_PACKAGE_UID2 = 321 64 65 @DevSdkIgnoreRunner.MonitorThreadLeak 66 @RunWith(DevSdkIgnoreRunner::class) 67 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) 68 class CSSatelliteNetworkTest : CSTest() { 69 @get:Rule 70 val ignoreRule = DevSdkIgnoreRule() 71 72 /** 73 * Test createMultiLayerNrisFromSatelliteNetworkPreferredUids returns correct 74 * NetworkRequestInfo. 75 */ 76 @Test testCreateMultiLayerNrisFromSatelliteNetworkPreferredUidsnull77 fun testCreateMultiLayerNrisFromSatelliteNetworkPreferredUids() { 78 // Verify that empty uid set should not create any NRI for it. 79 val nrisNoUid = service.createMultiLayerNrisFromSatelliteNetworkFallbackUids(emptySet()) 80 Assert.assertEquals(0, nrisNoUid.size.toLong()) 81 val uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) 82 val uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2) 83 val uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) 84 assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(mutableSetOf(uid1)) 85 assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(mutableSetOf(uid1, uid3)) 86 assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(mutableSetOf(uid1, uid2)) 87 } 88 89 /** 90 * Test that satellite network satisfies satellite fallback per-app default network request and 91 * send correct net id and uid ranges to netd. 92 */ doTestSatelliteNetworkFallbackUidsnull93 private fun doTestSatelliteNetworkFallbackUids(restricted: Boolean) { 94 val netdInOrder = inOrder(netd) 95 96 val satelliteAgent = createSatelliteAgent("satellite0", restricted) 97 satelliteAgent.connect() 98 99 val satelliteNetId = satelliteAgent.network.netId 100 val permission = if (restricted) {INetd.PERMISSION_SYSTEM} else {INetd.PERMISSION_NONE} 101 netdInOrder.verify(netd).networkCreate( 102 nativeNetworkConfigPhysical(satelliteNetId, permission)) 103 104 val uid1 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) 105 val uid2 = PRIMARY_USER_HANDLE.getUid(TEST_PACKAGE_UID2) 106 val uid3 = SECONDARY_USER_HANDLE.getUid(TEST_PACKAGE_UID) 107 108 // Initial satellite network fallback uids status. 109 updateSatelliteNetworkFallbackUids(setOf()) 110 netdInOrder.verify(netd, never()).networkAddUidRangesParcel(any()) 111 netdInOrder.verify(netd, never()).networkRemoveUidRangesParcel(any()) 112 113 // Update satellite network fallback uids and verify that net id and uid ranges send to netd 114 var uids = mutableSetOf(uid1, uid2, uid3) 115 val uidRanges1 = toUidRangeStableParcels(uidRangesForUids(uids)) 116 val config1 = NativeUidRangeConfig( 117 satelliteNetId, uidRanges1, 118 PREFERENCE_ORDER_SATELLITE_FALLBACK 119 ) 120 updateSatelliteNetworkFallbackUids(uids) 121 netdInOrder.verify(netd).networkAddUidRangesParcel(config1) 122 netdInOrder.verify(netd, never()).networkRemoveUidRangesParcel(any()) 123 124 // Update satellite network fallback uids and verify that net id and uid ranges send to netd 125 uids = mutableSetOf(uid1) 126 val uidRanges2: Array<UidRangeParcel?> = toUidRangeStableParcels(uidRangesForUids(uids)) 127 val config2 = NativeUidRangeConfig( 128 satelliteNetId, uidRanges2, 129 PREFERENCE_ORDER_SATELLITE_FALLBACK 130 ) 131 updateSatelliteNetworkFallbackUids(uids) 132 netdInOrder.verify(netd).networkRemoveUidRangesParcel(config1) 133 netdInOrder.verify(netd).networkAddUidRangesParcel(config2) 134 } 135 136 @Test testSatelliteNetworkFallbackUids_restrictednull137 fun testSatelliteNetworkFallbackUids_restricted() { 138 doTestSatelliteNetworkFallbackUids(restricted = true) 139 } 140 141 @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) testSatelliteNetworkFallbackUids_nonRestrictednull142 fun testSatelliteNetworkFallbackUids_nonRestricted() { 143 doTestSatelliteNetworkFallbackUids(restricted = false) 144 } 145 doTestSatelliteNeverBecomeDefaultNetworknull146 private fun doTestSatelliteNeverBecomeDefaultNetwork(restricted: Boolean) { 147 val agent = createSatelliteAgent("satellite0", restricted) 148 agent.connect() 149 val defaultCb = TestableNetworkCallback() 150 cm.registerDefaultNetworkCallback(defaultCb) 151 // Satellite network must not become the default network 152 defaultCb.assertNoCallback() 153 } 154 155 @Test testSatelliteNeverBecomeDefaultNetwork_restrictednull156 fun testSatelliteNeverBecomeDefaultNetwork_restricted() { 157 doTestSatelliteNeverBecomeDefaultNetwork(restricted = true) 158 } 159 160 @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) testSatelliteNeverBecomeDefaultNetwork_notRestrictednull161 fun testSatelliteNeverBecomeDefaultNetwork_notRestricted() { 162 doTestSatelliteNeverBecomeDefaultNetwork(restricted = false) 163 } 164 assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUidsnull165 private fun assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(uids: Set<Int>) { 166 val nris: Set<ConnectivityService.NetworkRequestInfo> = 167 service.createMultiLayerNrisFromSatelliteNetworkFallbackUids(uids) 168 val nri = nris.iterator().next() 169 // Verify that one NRI is created with multilayer requests. Because one NRI can contain 170 // multiple uid ranges, so it only need create one NRI here. 171 assertEquals(1, nris.size.toLong()) 172 assertTrue(nri.isMultilayerRequest) 173 assertEquals(nri.uids, uidRangesForUids(uids)) 174 assertEquals(PREFERENCE_ORDER_SATELLITE_FALLBACK, nri.mPreferenceOrder) 175 } 176 updateSatelliteNetworkFallbackUidsnull177 private fun updateSatelliteNetworkFallbackUids(uids: Set<Int>) { 178 visibleOnHandlerThread(csHandler) { 179 deps.satelliteNetworkFallbackUidUpdate!!.accept(uids) 180 } 181 } 182 nativeNetworkConfigPhysicalnull183 private fun nativeNetworkConfigPhysical(netId: Int, permission: Int) = 184 NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission, 185 false /* secure */, VpnManager.TYPE_VPN_NONE, false /* excludeLocalRoutes */) 186 187 private fun createSatelliteAgent(name: String, restricted: Boolean = true): CSAgentWrapper { 188 return Agent(score = keepScore(), lp = lp(name), 189 nc = satelliteNc(restricted) 190 ) 191 } 192 toUidRangeStableParcelsnull193 private fun toUidRangeStableParcels(ranges: Set<UidRange>): Array<UidRangeParcel?> { 194 val stableRanges = arrayOfNulls<UidRangeParcel>(ranges.size) 195 for ((index, range) in ranges.withIndex()) { 196 stableRanges[index] = UidRangeParcel(range.start, range.stop) 197 } 198 return stableRanges 199 } 200 uidRangesForUidsnull201 private fun uidRangesForUids(vararg uids: Int): Set<UidRange> { 202 val ranges = ArraySet<UidRange>() 203 for (uid in uids) { 204 ranges.add(UidRange(uid, uid)) 205 } 206 return ranges 207 } 208 uidRangesForUidsnull209 private fun uidRangesForUids(uids: Collection<Int>): Set<UidRange> { 210 return uidRangesForUids(*CollectionUtils.toIntArray(uids)) 211 } 212 satelliteNcnull213 private fun satelliteNc(restricted: Boolean) = 214 NetworkCapabilities.Builder().apply { 215 addTransportType(TRANSPORT_SATELLITE) 216 217 addCapability(NET_CAPABILITY_INTERNET) 218 addCapability(NET_CAPABILITY_NOT_SUSPENDED) 219 addCapability(NET_CAPABILITY_NOT_ROAMING) 220 addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 221 if (restricted) { 222 removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 223 } 224 removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED) 225 }.build() 226 <lambda>null227 private fun lp(iface: String) = LinkProperties().apply { 228 interfaceName = iface 229 addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 32)) 230 addRoute(RouteInfo(IpPrefix("0.0.0.0/0"), null, null)) 231 } 232 233 // This allows keeping all the networks connected without having to file individual requests 234 // for them. keepScorenull235 private fun keepScore() = FromS( 236 NetworkScore.Builder().setKeepConnectedReason(KEEP_CONNECTED_FOR_TEST).build() 237 ) 238 } 239