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.content.pm.PackageManager.FEATURE_LEANBACK 20 import android.net.INetd 21 import android.net.NativeNetworkConfig 22 import android.net.NativeNetworkType 23 import android.net.NetworkCapabilities 24 import android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK 25 import android.net.NetworkRequest 26 import android.net.VpnManager 27 import android.os.Build 28 import androidx.test.filters.SmallTest 29 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo 30 import com.android.testutils.DevSdkIgnoreRunner 31 import com.android.testutils.RecorderCallback.CallbackEntry.Available 32 import com.android.testutils.TestableNetworkCallback 33 import kotlin.test.assertFailsWith 34 import org.junit.Assert.assertEquals 35 import org.junit.Test 36 import org.junit.runner.RunWith 37 import org.junit.runners.Parameterized 38 import org.mockito.Mockito.doReturn 39 import org.mockito.Mockito.inOrder 40 import org.mockito.Mockito.never 41 import org.mockito.Mockito.timeout 42 43 private const val TIMEOUT_MS = 2_000L 44 private const val NO_CALLBACK_TIMEOUT_MS = 200L 45 46 @DevSdkIgnoreRunner.MonitorThreadLeak 47 @RunWith(DevSdkIgnoreRunner::class) 48 @SmallTest 49 @IgnoreUpTo(Build.VERSION_CODES.R) 50 class CSLocalAgentCreationTests : CSTest() { 51 @Parameterized.Parameter(0) lateinit var params: TestParams 52 53 data class TestParams( 54 val sdkLevel: Int, 55 val isTv: Boolean = false, 56 val addLocalNetCapToRequest: Boolean = true 57 ) 58 59 companion object { 60 @JvmStatic 61 @Parameterized.Parameters argumentsnull62 fun arguments() = listOf( 63 TestParams(VERSION_V, isTv = false, addLocalNetCapToRequest = true), 64 TestParams(VERSION_V, isTv = false, addLocalNetCapToRequest = false), 65 TestParams(VERSION_V, isTv = true, addLocalNetCapToRequest = true), 66 TestParams(VERSION_V, isTv = true, addLocalNetCapToRequest = false), 67 TestParams(VERSION_U, isTv = false, addLocalNetCapToRequest = true), 68 TestParams(VERSION_U, isTv = false, addLocalNetCapToRequest = false), 69 TestParams(VERSION_U, isTv = true, addLocalNetCapToRequest = true), 70 TestParams(VERSION_U, isTv = true, addLocalNetCapToRequest = false), 71 TestParams(VERSION_T, isTv = false, addLocalNetCapToRequest = false), 72 TestParams(VERSION_T, isTv = true, addLocalNetCapToRequest = false), 73 ) 74 } 75 76 private fun makeNativeNetworkConfigLocal(netId: Int, permission: Int) = 77 NativeNetworkConfig( 78 netId, 79 NativeNetworkType.PHYSICAL_LOCAL, 80 permission, 81 false /* secure */, 82 VpnManager.TYPE_VPN_NONE, 83 false /* excludeLocalRoutes */ 84 ) 85 86 @Test 87 fun testLocalAgents() { 88 val netdInOrder = inOrder(netd) 89 deps.setBuildSdk(params.sdkLevel) 90 doReturn(params.isTv).`when`(packageManager).hasSystemFeature(FEATURE_LEANBACK) 91 val allNetworksCb = TestableNetworkCallback() 92 val request = NetworkRequest.Builder() 93 if (params.addLocalNetCapToRequest) { 94 request.addCapability(NET_CAPABILITY_LOCAL_NETWORK) 95 } 96 cm.registerNetworkCallback(request.build(), allNetworksCb) 97 val ncTemplate = NetworkCapabilities.Builder().run { 98 addTransportType(NetworkCapabilities.TRANSPORT_THREAD) 99 addCapability(NET_CAPABILITY_LOCAL_NETWORK) 100 }.build() 101 val localAgent = if (params.sdkLevel >= VERSION_V || 102 params.sdkLevel == VERSION_U && params.isTv) { 103 Agent(nc = ncTemplate, score = keepConnectedScore(), lnc = defaultLnc()) 104 } else { 105 assertFailsWith<IllegalArgumentException> { Agent(nc = ncTemplate, lnc = defaultLnc()) } 106 netdInOrder.verify(netd, never()).networkCreate(any()) 107 return 108 } 109 localAgent.connect() 110 netdInOrder.verify(netd).networkCreate( 111 makeNativeNetworkConfigLocal(localAgent.network.netId, INetd.PERMISSION_NONE) 112 ) 113 if (params.addLocalNetCapToRequest) { 114 assertEquals(localAgent.network, allNetworksCb.expect<Available>().network) 115 } else { 116 allNetworksCb.assertNoCallback(NO_CALLBACK_TIMEOUT_MS) 117 } 118 cm.unregisterNetworkCallback(allNetworksCb) 119 localAgent.disconnect() 120 netdInOrder.verify(netd, timeout(TIMEOUT_MS)).networkDestroy(localAgent.network.netId) 121 } 122 123 @Test testBadAgentsnull124 fun testBadAgents() { 125 assertFailsWith<IllegalArgumentException> { 126 Agent( 127 nc = NetworkCapabilities.Builder() 128 .addCapability(NET_CAPABILITY_LOCAL_NETWORK) 129 .build(), 130 lnc = null 131 ) 132 } 133 assertFailsWith<IllegalArgumentException> { 134 Agent(nc = NetworkCapabilities.Builder().build(), lnc = defaultLnc()) 135 } 136 } 137 } 138