1 /* <lambda>null2 * 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 @file:JvmName("CsTestHelpers") 18 19 package com.android.server 20 21 import android.app.ActivityManager 22 import android.app.AlarmManager 23 import android.content.Context 24 import android.content.pm.PackageManager 25 import android.content.pm.PackageManager.FEATURE_BLUETOOTH 26 import android.content.pm.PackageManager.FEATURE_ETHERNET 27 import android.content.pm.PackageManager.FEATURE_WIFI 28 import android.content.pm.PackageManager.FEATURE_WIFI_DIRECT 29 import android.content.pm.UserInfo 30 import android.content.res.Resources 31 import android.net.IDnsResolver 32 import android.net.INetd 33 import android.net.IpPrefix 34 import android.net.LinkAddress 35 import android.net.LinkProperties 36 import android.net.NetworkAgentConfig 37 import android.net.NetworkCapabilities 38 import android.net.NetworkScore 39 import android.net.RouteInfo 40 import android.net.metrics.IpConnectivityLog 41 import android.os.Binder 42 import android.os.Handler 43 import android.os.HandlerThread 44 import android.os.SystemClock 45 import android.os.SystemConfigManager 46 import android.os.UserHandle 47 import android.os.UserManager 48 import android.provider.Settings 49 import android.test.mock.MockContentResolver 50 import com.android.connectivity.resources.R 51 import com.android.internal.util.WakeupMessage 52 import com.android.internal.util.test.FakeSettingsProvider 53 import com.android.modules.utils.build.SdkLevel 54 import com.android.server.ConnectivityService.Dependencies 55 import com.android.server.connectivity.ConnectivityResources 56 import kotlin.test.fail 57 import org.mockito.ArgumentMatchers 58 import org.mockito.ArgumentMatchers.any 59 import org.mockito.ArgumentMatchers.anyInt 60 import org.mockito.ArgumentMatchers.anyLong 61 import org.mockito.ArgumentMatchers.anyString 62 import org.mockito.ArgumentMatchers.argThat 63 import org.mockito.ArgumentMatchers.eq 64 import org.mockito.Mockito 65 import org.mockito.Mockito.doAnswer 66 import org.mockito.Mockito.doNothing 67 import org.mockito.Mockito.doReturn 68 69 internal inline fun <reified T> mock() = Mockito.mock(T::class.java) 70 internal inline fun <reified T> any() = any(T::class.java) 71 72 internal fun emptyAgentConfig(legacyType: Int) = NetworkAgentConfig.Builder() 73 .setLegacyType(legacyType) 74 .build() 75 76 internal fun defaultNc() = NetworkCapabilities.Builder() 77 // Add sensible defaults for agents that don't want to care 78 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) 79 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) 80 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) 81 .build() 82 83 internal fun defaultScore() = FromS(NetworkScore.Builder().build()) 84 85 internal fun defaultLp() = LinkProperties().apply { 86 addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 32)) 87 addRoute(RouteInfo(IpPrefix("0.0.0.0/0"), null, null)) 88 } 89 <lambda>null90 internal fun makeMockContentResolver(context: Context) = MockContentResolver(context).apply { 91 addProvider(Settings.AUTHORITY, FakeSettingsProvider()) 92 } 93 <lambda>null94 internal fun makeMockUserManager(info: UserInfo, handle: UserHandle) = mock<UserManager>().also { 95 doReturn(listOf(info)).`when`(it).getAliveUsers() 96 doReturn(listOf(handle)).`when`(it).getUserHandles(ArgumentMatchers.anyBoolean()) 97 } 98 <lambda>null99 internal fun makeActivityManager() = mock<ActivityManager>().also { 100 if (SdkLevel.isAtLeastU()) { 101 doNothing().`when`(it).registerUidFrozenStateChangedCallback(any(), any()) 102 } 103 } 104 makeMockPackageManagernull105 internal fun makeMockPackageManager(realContext: Context) = mock<PackageManager>().also { pm -> 106 val supported = listOf(FEATURE_WIFI, FEATURE_WIFI_DIRECT, FEATURE_BLUETOOTH, FEATURE_ETHERNET) 107 doReturn(true).`when`(pm).hasSystemFeature(argThat { supported.contains(it) }) 108 val myPackageName = realContext.packageName 109 val myPackageInfo = realContext.packageManager.getPackageInfo(myPackageName, 110 PackageManager.GET_PERMISSIONS) 111 // Very high version code so that the checks for the module version will always 112 // say that it is recent enough. This is the most sensible default, but if some 113 // test needs to test with different version codes they can re-mock this with a 114 // different value. 115 myPackageInfo.longVersionCode = 9999999L 116 doReturn(arrayOf(myPackageName)).`when`(pm).getPackagesForUid(Binder.getCallingUid()) 117 doReturn(myPackageInfo).`when`(pm).getPackageInfoAsUser( 118 eq(myPackageName), anyInt(), eq(UserHandle.getCallingUserId())) 119 doReturn(listOf(myPackageInfo)).`when`(pm) 120 .getInstalledPackagesAsUser(eq(PackageManager.GET_PERMISSIONS), anyInt()) 121 } 122 <lambda>null123 internal fun makeMockConnResources(resources: Resources, pm: PackageManager) = mock<Context>().let { 124 doReturn(resources).`when`(it).resources 125 doReturn(pm).`when`(it).packageManager 126 ConnectivityResources.setResourcesContextForTest(it) 127 ConnectivityResources(it) 128 } 129 130 private val UNREASONABLY_LONG_ALARM_WAIT_MS = 1000 makeMockAlarmManagernull131 internal fun makeMockAlarmManager(handlerThread: HandlerThread) = mock<AlarmManager>().also { am -> 132 val alrmHdlr = handlerThread.threadHandler 133 doAnswer { 134 val (_, date, _, wakeupMsg, handler) = it.arguments 135 wakeupMsg as WakeupMessage 136 handler as Handler 137 val delayMs = ((date as Long) - SystemClock.elapsedRealtime()).coerceAtLeast(0) 138 if (delayMs > UNREASONABLY_LONG_ALARM_WAIT_MS) { 139 fail("Attempting to send msg more than $UNREASONABLY_LONG_ALARM_WAIT_MS" + 140 "ms into the future : $delayMs") 141 } 142 alrmHdlr.postDelayed({ handler.post(wakeupMsg::onAlarm) }, wakeupMsg, delayMs) 143 }.`when`(am).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), anyLong(), anyString(), 144 any<WakeupMessage>(), any()) 145 doAnswer { 146 alrmHdlr.removeCallbacksAndMessages(it.getArgument<WakeupMessage>(0)) 147 }.`when`(am).cancel(any<WakeupMessage>()) 148 } 149 <lambda>null150 internal fun makeMockSystemConfigManager() = mock<SystemConfigManager>().also { 151 doReturn(intArrayOf(0)).`when`(it).getSystemPermissionUids(anyString()) 152 } 153 154 // Mocking resources used by ConnectivityService. Note these can't be defined to return the 155 // value returned by the mocking, because a non-null method would mean the helper would also 156 // return non-null and the compiler would check that, but mockito has no qualms returning null 157 // from a @NonNull method when stubbing. Hence, mock() = doReturn().getString() would crash 158 // at runtime, because getString() returns non-null String, therefore mock returns non-null String, 159 // and kotlinc adds an intrinsics check for that, which crashes at runtime when mockito actually 160 // returns null. mocknull161 private fun Resources.mock(r: Int, v: Boolean) { doReturn(v).`when`(this).getBoolean(r) } mocknull162 private fun Resources.mock(r: Int, v: Int) { doReturn(v).`when`(this).getInteger(r) } mocknull163 private fun Resources.mock(r: Int, v: String) { doReturn(v).`when`(this).getString(r) } mocknull164 private fun Resources.mock(r: Int, v: Array<String?>) { doReturn(v).`when`(this).getStringArray(r) } mocknull165 private fun Resources.mock(r: Int, v: IntArray) { doReturn(v).`when`(this).getIntArray(r) } 166 initMockedResourcesnull167 internal fun initMockedResources(res: Resources) { 168 // Resources accessed through reflection need to return the id 169 doReturn(R.array.config_networkSupportedKeepaliveCount).`when`(res) 170 .getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any()) 171 doReturn(R.array.network_switch_type_name).`when`(res) 172 .getIdentifier(eq("network_switch_type_name"), eq("array"), any()) 173 // Mock the values themselves 174 res.mock(R.integer.config_networkTransitionTimeout, 60_000) 175 res.mock(R.string.config_networkCaptivePortalServerUrl, "") 176 res.mock(R.array.config_wakeonlan_supported_interfaces, arrayOf(WIFI_WOL_IFNAME)) 177 res.mock(R.array.config_networkSupportedKeepaliveCount, arrayOf("0,1", "1,3")) 178 res.mock(R.array.config_networkNotifySwitches, arrayOfNulls<String>(size = 0)) 179 res.mock(R.array.config_protectedNetworks, intArrayOf(10, 11, 12, 14, 15)) 180 res.mock(R.array.network_switch_type_name, arrayOfNulls<String>(size = 0)) 181 res.mock(R.integer.config_networkAvoidBadWifi, 1) 182 res.mock(R.integer.config_activelyPreferBadWifi, 0) 183 res.mock(R.bool.config_cellular_radio_timesharing_capable, true) 184 } 185 186 private val TEST_LINGER_DELAY_MS = 400 187 private val TEST_NASCENT_DELAY_MS = 300 makeConnectivityServicenull188 internal fun makeConnectivityService(context: Context, netd: INetd, deps: Dependencies) = 189 ConnectivityService( 190 context, 191 mock<IDnsResolver>(), 192 mock<IpConnectivityLog>(), 193 netd, 194 deps).also { 195 it.mLingerDelayMs = TEST_LINGER_DELAY_MS 196 it.mNascentDelayMs = TEST_NASCENT_DELAY_MS 197 } 198