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