• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2020 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 package com.android.server.pm
17 
18 import android.content.Context
19 import android.content.Intent
20 import android.content.pm.ActivityInfo
21 import android.content.pm.ApplicationInfo
22 import android.content.pm.FallbackCategoryProvider
23 import android.content.pm.FeatureInfo
24 import android.content.pm.PackageParser.SigningDetails
25 import android.content.pm.ResolveInfo
26 import android.content.pm.ServiceInfo
27 import android.content.pm.Signature
28 import android.content.pm.UserInfo
29 import android.content.pm.parsing.ParsingPackage
30 import android.content.pm.parsing.ParsingPackageUtils
31 import android.content.res.Resources
32 import android.hardware.display.DisplayManager
33 import android.os.Build
34 import android.os.Environment
35 import android.os.SystemProperties
36 import android.os.UserHandle
37 import android.os.UserManager
38 import android.os.incremental.IncrementalManager
39 import android.provider.DeviceConfig
40 import android.util.ArrayMap
41 import android.util.DisplayMetrics
42 import android.util.EventLog
43 import android.view.Display
44 import com.android.dx.mockito.inline.extended.ExtendedMockito
45 import com.android.dx.mockito.inline.extended.ExtendedMockito.any
46 import com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean
47 import com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt
48 import com.android.dx.mockito.inline.extended.ExtendedMockito.anyString
49 import com.android.dx.mockito.inline.extended.ExtendedMockito.argThat
50 import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
51 import com.android.dx.mockito.inline.extended.ExtendedMockito.eq
52 import com.android.dx.mockito.inline.extended.ExtendedMockito.spy
53 import com.android.dx.mockito.inline.extended.StaticMockitoSession
54 import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder
55 import com.android.internal.R
56 import com.android.server.LocalServices
57 import com.android.server.LockGuard
58 import com.android.server.SystemConfig
59 import com.android.server.SystemServerInitThreadPool
60 import com.android.server.compat.PlatformCompat
61 import com.android.server.extendedtestutils.wheneverStatic
62 import com.android.server.pm.dex.DexManager
63 import com.android.server.pm.parsing.PackageParser2
64 import com.android.server.pm.parsing.pkg.AndroidPackage
65 import com.android.server.pm.parsing.pkg.PackageImpl
66 import com.android.server.pm.parsing.pkg.ParsedPackage
67 import com.android.server.pm.permission.PermissionManagerServiceInternal
68 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
69 import com.android.server.testutils.TestHandler
70 import com.android.server.testutils.mock
71 import com.android.server.testutils.nullable
72 import com.android.server.testutils.whenever
73 import com.android.server.utils.WatchedArrayMap
74 import org.junit.Assert
75 import org.junit.rules.TestRule
76 import org.junit.runner.Description
77 import org.junit.runners.model.Statement
78 import org.mockito.AdditionalMatchers.or
79 import org.mockito.quality.Strictness
80 import java.io.File
81 import java.io.IOException
82 import java.nio.file.Files
83 import java.security.PublicKey
84 import java.security.cert.CertificateException
85 import java.util.Arrays
86 import java.util.Random
87 import java.util.concurrent.FutureTask
88 
89 /**
90  * A utility for mocking behavior of the system and dependencies when testing PackageManagerService
91  *
92  * Create one of these and call [stageNominalSystemState] as a basis for additional behavior in most
93  * tests.
94  */
95 class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
96     private val random = Random()
97     val mocks = Mocks()
98     val packageCacheDirectory: File =
99             Files.createTempDirectory("packageCache").toFile()
100     val rootDirectory: File =
101             Files.createTempDirectory("root").toFile()
102     val dataAppDirectory: File =
103             File(Files.createTempDirectory("data").toFile(), "app")
104     val frameworkSignature: SigningDetails = SigningDetails(arrayOf(generateSpySignature()), 3)
105     val systemPartitions: List<PackageManagerService.ScanPartition> =
106             redirectScanPartitions(PackageManagerService.SYSTEM_PARTITIONS)
107     val session: StaticMockitoSession
108 
109     /** Tracks temporary files created by this class during the running of a test.  */
110     private val createdFiles = ArrayList<File>()
111 
112     /** Settings that are expected to be added as part of the test  */
113     private val mPendingPackageAdds: MutableList<Pair<String, PackageSetting>> = ArrayList()
114 
115     /** Settings simulated to be stored on disk  */
116     private val mPreExistingSettings = ArrayMap<String, PackageSetting>()
117 
118     /** The active map simulating the in memory storage of Settings  */
119     private val mSettingsMap = WatchedArrayMap<String, PackageSetting>()
120 
121     init {
122         val apply = ExtendedMockito.mockitoSession()
123                 .strictness(Strictness.LENIENT)
124                 .mockStatic(SystemProperties::class.java)
125                 .mockStatic(SystemConfig::class.java)
126                 .mockStatic(SELinuxMMAC::class.java)
127                 .mockStatic(FallbackCategoryProvider::class.java)
128                 .mockStatic(PackageManagerServiceUtils::class.java)
129                 .mockStatic(Environment::class.java)
130                 .mockStatic(SystemServerInitThreadPool::class.java)
131                 .mockStatic(ParsingPackageUtils::class.java)
132                 .mockStatic(LockGuard::class.java)
133                 .mockStatic(EventLog::class.java)
134                 .mockStatic(LocalServices::class.java)
135                 .mockStatic(DeviceConfig::class.java)
136                 .apply(withSession)
137         session = apply.startMocking()
138         whenever(mocks.settings.insertPackageSettingLPw(
<lambda>null139                 any(PackageSetting::class.java), any(AndroidPackage::class.java))) {
140             val name: String = (getArgument<Any>(0) as PackageSetting).name
141             val pendingAdd =
142                     mPendingPackageAdds.firstOrNull { it.first == name } ?: return@whenever null
143             mPendingPackageAdds.remove(pendingAdd)
144             mSettingsMap[name] = pendingAdd.second
145             null
146         }
147         whenever(mocks.settings.addPackageLPw(nullable(), nullable(), nullable(), nullable(),
148                 nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), nullable(),
<lambda>null149                 nullable(), nullable(), nullable(), nullable())) {
150             val name: String = getArgument(0)
151             val pendingAdd = mPendingPackageAdds.firstOrNull { it.first == name }
152                     ?: return@whenever null
153             mPendingPackageAdds.remove(pendingAdd)
154             mSettingsMap[name] = pendingAdd.second
155             pendingAdd.second
156         }
157         whenever(mocks.settings.packagesLocked).thenReturn(mSettingsMap)
<lambda>null158         whenever(mocks.settings.getPackageLPr(anyString())) { mSettingsMap[getArgument<Any>(0)] }
<lambda>null159         whenever(mocks.settings.readLPw(nullable())) {
160             mSettingsMap.putAll(mPreExistingSettings)
161             !mPreExistingSettings.isEmpty()
162         }
163     }
164 
165     /** Collection of mocks used for PackageManagerService tests. */
166 
167     class Mocks {
168         val lock = PackageManagerTracedLock()
169         val installLock = Any()
170         val injector: PackageManagerService.Injector = mock()
171         val systemWrapper: PackageManagerService.SystemWrapper = mock()
172         val context: Context = mock()
173         val userManagerService: UserManagerService = mock()
174         val componentResolver: ComponentResolver = mock()
175         val permissionManagerInternal: PermissionManagerServiceInternal = mock()
176         val incrementalManager: IncrementalManager = mock()
177         val platformCompat: PlatformCompat = mock()
178         val settings: Settings = mock()
179         val resources: Resources = mock()
180         val systemConfig: SystemConfig = mock()
181         val apexManager: ApexManager = mock()
182         val userManagerInternal: UserManagerInternal = mock()
183         val packageParser: PackageParser2 = mock()
184         val keySetManagerService: KeySetManagerService = mock()
185         val packageAbiHelper: PackageAbiHelper = mock()
186         val appsFilter: AppsFilter = mock()
187         val dexManager: DexManager = mock()
188         val installer: Installer = mock()
189         val displayMetrics: DisplayMetrics = mock()
190         val domainVerificationManagerInternal: DomainVerificationManagerInternal = mock()
191         val handler = TestHandler(null)
192     }
193 
194     companion object {
195         private const val DEVICE_PROVISIONING_PACKAGE_NAME =
196                 "com.example.android.device.provisioning"
197         private val DEFAULT_AVAILABLE_FEATURES_MAP = ArrayMap<String, FeatureInfo>()
198         private val DEFAULT_ACTIVE_APEX_INFO_LIST = emptyList<ApexManager.ActiveApexInfo>()
199         private val DEFAULT_SHARED_LIBRARIES_LIST =
200                 ArrayMap<String, SystemConfig.SharedLibraryEntry>()
201         private val DEFAULT_USERS = Arrays.asList(
202                 UserInfo(UserHandle.USER_SYSTEM, "primary", "",
203                         UserInfo.FLAG_PRIMARY or UserInfo.FLAG_SYSTEM or UserInfo.FLAG_FULL,
204                         UserManager.USER_TYPE_FULL_SYSTEM))
205         public val DEFAULT_VERSION_INFO = Settings.VersionInfo()
206 
207         init {
208             DEFAULT_VERSION_INFO.fingerprint = "abcdef"
209             DEFAULT_VERSION_INFO.sdkVersion = Build.VERSION_CODES.R
210             DEFAULT_VERSION_INFO.databaseVersion = Settings.CURRENT_DATABASE_VERSION
211         }
212     }
213 
214     /**
215      * Clean up any potentially dangling state. This should be run at the end of every test to
216      * account for changes to static memory, such as [LocalServices]
217      */
cleanupnull218     fun cleanup() {
219         createdFiles.forEach(File::delete)
220         createdFiles.clear()
221         mSettingsMap.clear()
222         mPendingPackageAdds.clear()
223         mPreExistingSettings.clear()
224         session.finishMocking()
225     }
226 
227     /**
228      * Run this method to ensure that all expected actions were executed, such as pending
229      * [Settings] adds.
230      */
validateFinalStatenull231     fun validateFinalState() {
232         if (mPendingPackageAdds.isNotEmpty()) {
233             Assert.fail(
234                     "Not all expected settings were added: ${mPendingPackageAdds.map { it.first }}")
235         }
236     }
237 
238     /**
239      * This method stages enough of system startup to execute the PackageManagerService constructor
240      * successfullly.
241      */
242     @Throws(Exception::class)
stageNominalSystemStatenull243     fun stageNominalSystemState() {
244         whenever(mocks.injector.context).thenReturn(mocks.context)
245         whenever(mocks.injector.lock).thenReturn(mocks.lock)
246         whenever(mocks.injector.installLock).thenReturn(mocks.installLock)
247         whenever(mocks.injector.systemWrapper).thenReturn(mocks.systemWrapper)
248         whenever(mocks.injector.userManagerService).thenReturn(mocks.userManagerService)
249         whenever(mocks.injector.componentResolver).thenReturn(mocks.componentResolver)
250         whenever(mocks.injector.permissionManagerServiceInternal) {
251             mocks.permissionManagerInternal
252         }
253         whenever(mocks.injector.incrementalManager).thenReturn(mocks.incrementalManager)
254         whenever(mocks.injector.compatibility).thenReturn(mocks.platformCompat)
255         whenever(mocks.injector.settings).thenReturn(mocks.settings)
256         whenever(mocks.injector.dexManager).thenReturn(mocks.dexManager)
257         whenever(mocks.injector.systemConfig).thenReturn(mocks.systemConfig)
258         whenever(mocks.injector.apexManager).thenReturn(mocks.apexManager)
259         whenever(mocks.injector.scanningCachingPackageParser).thenReturn(mocks.packageParser)
260         whenever(mocks.injector.scanningPackageParser).thenReturn(mocks.packageParser)
261         whenever(mocks.injector.systemPartitions).thenReturn(systemPartitions)
262         whenever(mocks.injector.appsFilter).thenReturn(mocks.appsFilter)
263         whenever(mocks.injector.abiHelper).thenReturn(mocks.packageAbiHelper)
264         whenever(mocks.injector.userManagerInternal).thenReturn(mocks.userManagerInternal)
265         whenever(mocks.injector.installer).thenReturn(mocks.installer)
266         whenever(mocks.injector.displayMetrics).thenReturn(mocks.displayMetrics)
267         whenever(mocks.injector.domainVerificationManagerInternal)
268             .thenReturn(mocks.domainVerificationManagerInternal)
269         whenever(mocks.injector.handler) { mocks.handler }
270         wheneverStatic { SystemConfig.getInstance() }.thenReturn(mocks.systemConfig)
271         whenever(mocks.systemConfig.availableFeatures).thenReturn(DEFAULT_AVAILABLE_FEATURES_MAP)
272         whenever(mocks.systemConfig.sharedLibraries).thenReturn(DEFAULT_SHARED_LIBRARIES_LIST)
273         wheneverStatic { SystemProperties.getBoolean("fw.free_cache_v2", true) }.thenReturn(true)
274         wheneverStatic { Environment.getPackageCacheDirectory() }.thenReturn(packageCacheDirectory)
275         wheneverStatic { SystemProperties.digestOf("ro.build.fingerprint") }.thenReturn("cacheName")
276         wheneverStatic { Environment.getRootDirectory() }.thenReturn(rootDirectory)
277         wheneverStatic { SystemServerInitThreadPool.submit(any(Runnable::class.java), anyString()) }
278                 .thenAnswer { FutureTask<Any?>(it.getArgument(0), null) }
279 
280         wheneverStatic { Environment.getDataDirectory() }.thenReturn(dataAppDirectory.parentFile)
281         wheneverStatic { Environment.getDataSystemDirectory() }
282                 .thenReturn(File(dataAppDirectory.parentFile, "system"))
283         whenever(mocks.context.resources).thenReturn(mocks.resources)
284         whenever(mocks.resources.getString(R.string.config_deviceProvisioningPackage)) {
285             DEVICE_PROVISIONING_PACKAGE_NAME
286         }
287         whenever(mocks.apexManager.activeApexInfos).thenReturn(DEFAULT_ACTIVE_APEX_INFO_LIST)
288         whenever(mocks.settings.packagesLocked).thenReturn(mSettingsMap)
289         whenever(mocks.settings.internalVersion).thenReturn(DEFAULT_VERSION_INFO)
290         whenever(mocks.settings.keySetManagerService).thenReturn(mocks.keySetManagerService)
291         whenever(mocks.settings.keySetManagerService).thenReturn(mocks.keySetManagerService)
292         whenever(mocks.settings.snapshot()).thenReturn(mocks.settings)
293         whenever(mocks.packageAbiHelper.derivePackageAbi(
294                 any(AndroidPackage::class.java), anyBoolean(), nullable(), any(File::class.java))) {
295             android.util.Pair(PackageAbiHelper.Abis("", ""),
296                     PackageAbiHelper.NativeLibraryPaths("", false, "", ""))
297         }
298         whenever(mocks.userManagerInternal.getUsers(true, false, false)).thenReturn(DEFAULT_USERS)
299         whenever(mocks.userManagerService.userIds).thenReturn(intArrayOf(0))
300         whenever(mocks.userManagerService.exists(0)).thenReturn(true)
301         whenever(mocks.packageAbiHelper.deriveNativeLibraryPaths(
302                 any(AndroidPackage::class.java), anyBoolean(), any(File::class.java))) {
303             PackageAbiHelper.NativeLibraryPaths("", false, "", "")
304         }
305         // everything visible by default
306         whenever(mocks.appsFilter.shouldFilterApplication(
307                 anyInt(), nullable(), nullable(), anyInt())) { false }
308 
309         val displayManager: DisplayManager = mock()
310         whenever(mocks.context.getSystemService(DisplayManager::class.java))
311                 .thenReturn(displayManager)
312         val display: Display = mock()
313         whenever(displayManager.getDisplay(Display.DEFAULT_DISPLAY)).thenReturn(display)
314 
315         stageFrameworkScan()
316         stageInstallerScan()
317         stageServicesExtensionScan()
318         stageSystemSharedLibraryScan()
319         stagePermissionsControllerScan()
320         stageInstantAppResolverScan()
321     }
322 
323     /**
324      * This method will stage the parsing and scanning of a package as well as add it to the
325      * [PackageSetting]s read from disk.
326      */
327     @Throws(Exception::class)
stageScanExistingPackagenull328     fun stageScanExistingPackage(
329         packageName: String,
330         versionCode: Long,
331         parent: File?,
332         withPackage: (PackageImpl) -> PackageImpl = { it },
333         withSetting:
<lambda>null334         (PackageSettingBuilder) -> PackageSettingBuilder = { it },
335         withExistingSetting:
<lambda>null336         (PackageSettingBuilder) -> PackageSettingBuilder = { it }
337     ) {
338         val existingSettingBuilderRef = arrayOfNulls<PackageSettingBuilder>(1)
339         stageScanNewPackage(packageName, versionCode, parent, withPackage,
settingBuildernull340                 withSetting = { settingBuilder ->
341                     withSetting(settingBuilder)
342                     existingSettingBuilderRef[0] = settingBuilder
343                     settingBuilder
344                 })
345         existingSettingBuilderRef[0]?.setPackage(null)
<lambda>null346         val packageSetting = existingSettingBuilderRef[0]?.let { withExistingSetting(it) }!!.build()
347         addPreExistingSetting(packageName, packageSetting)
348     }
349 
350     /**
351      * This method will stage a [PackageSetting] read from disk, but does not stage any scanning
352      * or parsing of the package.
353      */
addPreExistingSettingnull354     fun addPreExistingSetting(packageName: String, packageSetting: PackageSetting) {
355         mPreExistingSettings[packageName] = packageSetting
356     }
357 
358     /**
359      * This method will stage the parsing and scanning of a package but will not add it to the set
360      * of [PackageSetting]s read from disk.
361      */
362     @Throws(Exception::class)
stageScanNewPackagenull363     fun stageScanNewPackage(
364         packageName: String,
365         versionCode: Long,
366         parent: File?,
367         withPackage: (PackageImpl) -> PackageImpl = { it },
<lambda>null368         withSetting: (PackageSettingBuilder) -> PackageSettingBuilder = { it }
369     ) {
370         val pair = createBasicAndroidPackage(parent, packageName, versionCode)
371         val apkPath = pair.first
372         val pkg = withPackage(pair.second)
373         stageParse(apkPath, pkg)
374         val parentFile = apkPath.parentFile
375         val settingBuilder = withSetting(createBasicSettingBuilder(parentFile, pkg))
376         stageSettingInsert(packageName, settingBuilder.build())
377     }
378 
379     /**
380      * Creates a simple package that should reasonably parse for scan operations. This can be used
381      * as a basis for more complicated packages.
382      */
createBasicAndroidPackagenull383     fun createBasicAndroidPackage(
384         parent: File?,
385         packageName: String,
386         versionCode: Long,
387         signingDetails: SigningDetails =
388                 createRandomSigningDetails()
389     ): Pair<File, PackageImpl> {
390         val apkPath = File(File(parent, packageName), "base.apk")
391         val pkg = PackageImpl.forTesting(packageName, apkPath.parentFile.path) as PackageImpl
392         pkg.signingDetails = signingDetails
393         wheneverStatic { ParsingPackageUtils.getSigningDetails(eq(pkg), anyBoolean()) }
394                 .thenReturn(signingDetails)
395         pkg.versionCode = versionCode.toInt()
396         pkg.versionCodeMajor = (versionCode shr 32).toInt()
397         pkg.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT
398         return Pair(apkPath, pkg)
399     }
400 
401     /**
402      * This method will create a spy of a [SigningDetails] object to be used when simulating the
403      * collection of signatures.
404      */
createRandomSigningDetailsnull405     fun createRandomSigningDetails(): SigningDetails {
406         val signingDetails = spy(SigningDetails(arrayOf(generateSpySignature()),
407                 SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3))
408         doReturn(true).whenever(signingDetails).checkCapability(
409                 anyString(), anyInt())
410         doReturn(true).whenever(signingDetails).checkCapability(
411                 any(SigningDetails::class.java), anyInt())
412         return signingDetails
413     }
414 
415     /**
416      * This method will create a basic [PackageSettingBuilder] from an [AndroidPackage] with all of
417      * the necessary parameters to be returned by a simple scan. This can be used as a basis for
418      * more complicated settings.
419      */
createBasicSettingBuildernull420     fun createBasicSettingBuilder(parentFile: File, pkg: AndroidPackage): PackageSettingBuilder {
421         return createBasicSettingBuilder(parentFile, pkg.packageName, pkg.longVersionCode,
422                 pkg.signingDetails)
423                 .setPackage(pkg)
424     }
425 
426     /**
427      * This method will create a basic [PackageSettingBuilder] with all of the necessary parameters
428      * to be returned by a simple scan. This can be used as a basis for more complicated settings.
429      */
createBasicSettingBuildernull430     fun createBasicSettingBuilder(
431         parentFile: File,
432         packageName: String,
433         versionCode: Long,
434         signingDetails: SigningDetails
435     ): PackageSettingBuilder {
436         return PackageSettingBuilder()
437                 .setCodePath(parentFile.path)
438                 .setName(packageName)
439                 .setPVersionCode(versionCode)
440                 .setSigningDetails(signingDetails)
441     }
442 
createBasicApplicationInfonull443     fun createBasicApplicationInfo(pkg: ParsingPackage): ApplicationInfo {
444         val applicationInfo: ApplicationInfo = mock()
445         applicationInfo.packageName = pkg.packageName
446         return applicationInfo
447     }
448 
createBasicActivityInfonull449     fun createBasicActivityInfo(
450         pkg: ParsingPackage,
451         applicationInfo: ApplicationInfo?,
452         className: String?
453     ):
454             ActivityInfo {
455         val activityInfo = ActivityInfo()
456         activityInfo.applicationInfo = applicationInfo
457         activityInfo.packageName = pkg.packageName
458         activityInfo.name = className
459         return activityInfo
460     }
461 
createBasicServiceInfonull462     fun createBasicServiceInfo(
463         pkg: ParsingPackage,
464         applicationInfo: ApplicationInfo?,
465         className: String?
466     ):
467             ServiceInfo {
468         val serviceInfo = ServiceInfo()
469         serviceInfo.applicationInfo = applicationInfo
470         serviceInfo.packageName = pkg.packageName
471         serviceInfo.name = className
472         return serviceInfo
473     }
474 
475     /** Finds the appropriate partition, if available, based on a scan flag unique to it.  */
getPartitionFromFlagnull476     fun getPartitionFromFlag(scanFlagMask: Int): PackageManagerService.ScanPartition =
477             systemPartitions.first { (it.scanFlag and scanFlagMask) != 0 }
478 
479     @Throws(Exception::class)
stageParsenull480     private fun stageParse(path: File, parseResult: ParsingPackage): ParsedPackage {
481         val basePath = path.parentFile
482         basePath.mkdirs()
483         path.createNewFile()
484         createdFiles.add(path)
485         val parsedPackage = parseResult.hideAsParsed() as ParsedPackage
486         whenever(mocks.packageParser.parsePackage(
487                 or(eq(path), eq(basePath)), anyInt(), anyBoolean())) { parsedPackage }
488         return parsedPackage
489     }
490 
stageSettingInsertnull491     private fun stageSettingInsert(name: String, setting: PackageSetting): PackageSetting {
492         mPendingPackageAdds.add(Pair(name, setting))
493         return setting
494     }
495 
496     @Throws(Exception::class)
stageFrameworkScannull497     private fun stageFrameworkScan() {
498         val apk = File(File(rootDirectory, "framework"), "framework-res.apk")
499         val frameworkPkg = PackageImpl.forTesting("android",
500                 apk.parentFile.path) as PackageImpl
501         wheneverStatic { ParsingPackageUtils.getSigningDetails(frameworkPkg, true) }
502                 .thenReturn(frameworkSignature)
503         stageParse(apk, frameworkPkg)
504         stageSettingInsert("android",
505                 PackageSettingBuilder().setCodePath(apk.path).setName(
506                         "android").setPackage(frameworkPkg).build())
507     }
508 
509     @Throws(Exception::class)
stageInstantAppResolverScannull510     private fun stageInstantAppResolverScan() {
511         whenever(mocks.resources.getStringArray(R.array.config_ephemeralResolverPackage)) {
512             arrayOf("com.android.test.ephemeral.resolver")
513         }
514         stageScanNewPackage("com.android.test.ephemeral.resolver",
515                 1L, getPartitionFromFlag(PackageManagerService.SCAN_AS_PRODUCT).privAppFolder,
516                 withPackage = { pkg: PackageImpl ->
517                     val applicationInfo: ApplicationInfo = createBasicApplicationInfo(pkg)
518                     whenever(applicationInfo.isPrivilegedApp).thenReturn(true)
519                     mockQueryServices(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE,
520                             createBasicServiceInfo(pkg, applicationInfo, "test.EphemeralService"))
521                     mockQueryActivities(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS,
522                             createBasicActivityInfo(pkg, applicationInfo, "test.SettingsActivity"))
523                     pkg
524                 },
525                 withSetting = { setting: PackageSettingBuilder ->
526                     setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
527                 })
528     }
529 
530     @Throws(Exception::class)
stagePermissionsControllerScannull531     private fun stagePermissionsControllerScan() {
532         stageScanNewPackage("com.android.permissions.controller",
533                 1L, systemPartitions[0].privAppFolder,
534                 withPackage = { pkg: PackageImpl ->
535                     val applicationInfo: ApplicationInfo = createBasicApplicationInfo(pkg)
536                     whenever(applicationInfo.isPrivilegedApp).thenReturn(true)
537                     mockQueryActivities(Intent.ACTION_MANAGE_PERMISSIONS,
538                             createBasicActivityInfo(
539                                     pkg, applicationInfo, "test.PermissionActivity"))
540                     pkg
541                 },
542                 withSetting = { setting: PackageSettingBuilder ->
543                     setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
544                 })
545     }
546 
547     @Throws(Exception::class)
stageSystemSharedLibraryScannull548     private fun stageSystemSharedLibraryScan() {
549         stageScanNewPackage("android.ext.shared",
550                 1L, systemPartitions[0].appFolder,
551                 withPackage = { it.addLibraryName("android.ext.shared") as PackageImpl },
552                 withSetting = { setting: PackageSettingBuilder ->
553                     setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
554                 }
555         )
556     }
557 
558     @Throws(Exception::class)
stageServicesExtensionScannull559     private fun stageServicesExtensionScan() {
560         whenever(mocks.context.getString(R.string.config_servicesExtensionPackage)) {
561             "com.android.test.services.extension"
562         }
563         stageScanNewPackage("com.android.test.services.extension",
564                 1L, getPartitionFromFlag(PackageManagerService.SCAN_AS_SYSTEM_EXT).privAppFolder,
565                 withSetting = { setting: PackageSettingBuilder ->
566                     setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
567                 })
568     }
569 
570     @Throws(Exception::class)
stageInstallerScannull571     private fun stageInstallerScan() {
572         stageScanNewPackage(
573                 "com.android.test.installer",
574                 1L, getPartitionFromFlag(PackageManagerService.SCAN_AS_PRODUCT).privAppFolder,
575                 withPackage = { pkg: PackageImpl ->
576                     val applicationInfo: ApplicationInfo = createBasicApplicationInfo(pkg)
577                     whenever(applicationInfo.isPrivilegedApp).thenReturn(true)
578                     val installerActivity: ActivityInfo = createBasicActivityInfo(
579                             pkg, applicationInfo, "test.InstallerActivity")
580                     mockQueryActivities(Intent.ACTION_INSTALL_PACKAGE, installerActivity)
581                     mockQueryActivities(Intent.ACTION_UNINSTALL_PACKAGE, installerActivity)
582                     mockQueryActivities(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE,
583                             installerActivity)
584                     pkg
585                 },
586                 withSetting = { setting: PackageSettingBuilder ->
587                     setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
588                 }
589         )
590     }
591 
mockQueryActivitiesnull592     private fun mockQueryActivities(action: String, vararg activities: ActivityInfo) {
593         whenever(mocks.componentResolver.queryActivities(
594                 argThat { intent: Intent? -> intent != null && (action == intent.action) },
595                 nullable(), anyInt(), anyInt())) {
596             ArrayList(activities.asList().map { info: ActivityInfo? ->
597                 ResolveInfo().apply { activityInfo = info }
598             })
599         }
600     }
601 
mockQueryServicesnull602     private fun mockQueryServices(action: String, vararg services: ServiceInfo) {
603         whenever(mocks.componentResolver.queryServices(
604                 argThat { intent: Intent? -> intent != null && (action == intent.action) },
605                 nullable(), anyInt(), anyInt())) {
606             ArrayList(services.asList().map { info ->
607                 ResolveInfo().apply { serviceInfo = info }
608             })
609         }
610     }
611 
generateSpySignaturenull612     fun generateSpySignature(): Signature {
613         val bytes = ByteArray(32)
614         random.nextBytes(bytes)
615         val signature = spy(Signature(bytes))
616         try {
617             val mockPublicKey: PublicKey = mock()
618             doReturn(mockPublicKey).whenever(signature).getPublicKey()
619         } catch (e: CertificateException) {
620             throw RuntimeException(e)
621         }
622         return signature
623     }
624 
625     /** Override get*Folder methods to point to temporary local directories  */
626 
627     @Throws(IOException::class)
redirectScanPartitionsnull628     private fun redirectScanPartitions(partitions: List<PackageManagerService.ScanPartition>):
629             List<PackageManagerService.ScanPartition> {
630         val spiedPartitions: MutableList<PackageManagerService.ScanPartition> =
631                 ArrayList(partitions.size)
632         for (partition: PackageManagerService.ScanPartition in partitions) {
633             val spy = spy(partition)
634             val newRoot = Files.createTempDirectory(partition.folder.name).toFile()
635             whenever(spy.overlayFolder).thenReturn(File(newRoot, "overlay"))
636             whenever(spy.appFolder).thenReturn(File(newRoot, "app"))
637             whenever(spy.privAppFolder).thenReturn(File(newRoot, "priv-app"))
638             whenever(spy.folder).thenReturn(newRoot)
639             spiedPartitions.add(spy)
640         }
641         return spiedPartitions
642     }
643 }
644 
645 /**
646  * Sets up a basic [MockSystem] for use in a test method. This will create a MockSystem before the
647  * test method and any [org.junit.Before] annotated methods. It can then be used to access the
648  * MockSystem via the [system] method or the mocks directly via [mocks].
649  */
650 class MockSystemRule : TestRule {
651     var mockSystem: MockSystem? = null
applynull652     override fun apply(base: Statement?, description: Description?) = object : Statement() {
653         @Throws(Throwable::class)
654         override fun evaluate() {
655             mockSystem = MockSystem()
656             try {
657                 base!!.evaluate()
658             } finally {
659                 mockSystem?.cleanup()
660                 mockSystem = null
661             }
662         }
663     }
664 
665     /** Fetch the [MockSystem] instance prepared for this test */
systemnull666     fun system(): MockSystem = mockSystem!!
667     /** Fetch the [MockSystem.Mocks] prepared for this test */
668     fun mocks(): MockSystem.Mocks = mockSystem!!.mocks
669 }
670