• Home
  • History
  • Annotate
  • 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_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