• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2021 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.pm
18 
19 import android.content.pm.ApplicationInfo
20 import android.content.pm.PackageManager
21 import android.content.pm.SharedLibraryInfo
22 import android.content.pm.VersionedPackage
23 import android.os.Build
24 import android.os.storage.StorageManager
25 import android.util.ArrayMap
26 import android.util.PackageUtils
27 import com.android.server.SystemConfig.SharedLibraryEntry
28 import com.android.server.compat.PlatformCompat
29 import com.android.server.extendedtestutils.wheneverStatic
30 import com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME
31 import com.android.server.pm.parsing.pkg.AndroidPackage
32 import com.android.server.pm.parsing.pkg.PackageImpl
33 import com.android.server.pm.parsing.pkg.ParsedPackage
34 import com.android.server.testutils.any
35 import com.android.server.testutils.eq
36 import com.android.server.testutils.mock
37 import com.android.server.testutils.nullable
38 import com.android.server.testutils.spy
39 import com.android.server.testutils.whenever
40 import com.android.server.utils.WatchedLongSparseArray
41 import com.google.common.truth.Truth.assertThat
42 import libcore.util.HexEncoding
43 import org.junit.Before
44 import org.junit.Rule
45 import org.junit.Test
46 import org.junit.rules.RuleChain
47 import org.junit.rules.TemporaryFolder
48 import org.junit.runner.RunWith
49 import org.junit.runners.JUnit4
50 import org.mockito.Mock
51 import org.mockito.Mockito.doAnswer
52 import org.mockito.Mockito.verify
53 import org.mockito.MockitoAnnotations
54 import java.io.File
55 import kotlin.test.assertFailsWith
56 import kotlin.test.assertFalse
57 import kotlin.test.assertTrue
58 
59 @RunWith(JUnit4::class)
60 class SharedLibrariesImplTest {
61 
62     companion object {
63         const val TEST_LIB_NAME = "test.lib"
64         const val TEST_LIB_PACKAGE_NAME = "com.android.lib.test"
65         const val BUILTIN_LIB_NAME = "builtin.lib"
66         const val STATIC_LIB_NAME = "static.lib"
67         const val STATIC_LIB_VERSION = 7L
68         const val STATIC_LIB_DECLARING_PACKAGE_NAME = "com.android.lib.static.provider"
69         const val STATIC_LIB_PACKAGE_NAME = "com.android.lib.static.provider_7"
70         const val DYNAMIC_LIB_NAME = "dynamic.lib"
71         const val DYNAMIC_LIB_PACKAGE_NAME = "com.android.lib.dynamic.provider"
72         const val CONSUMER_PACKAGE_NAME = "com.android.lib.consumer"
73         const val VERSION_UNDEFINED = SharedLibraryInfo.VERSION_UNDEFINED.toLong()
74     }
75 
76     private val mMockSystem = MockSystemRule()
77     private val mTempFolder = TemporaryFolder()
78 
79     @Rule
80     @JvmField
81     val mRules = RuleChain.outerRule(mTempFolder).around(mMockSystem)!!
82 
83     private lateinit var mSharedLibrariesImpl: SharedLibrariesImpl
84     private lateinit var mPms: PackageManagerService
85     private lateinit var mSettings: Settings
86     private lateinit var mComputer: Computer
87     private lateinit var mExistingPackages: ArrayMap<String, AndroidPackage>
88     private lateinit var builtinLibDirectory: File
89 
90     @Mock
91     private lateinit var mDeletePackageHelper: DeletePackageHelper
92     @Mock
93     private lateinit var mStorageManager: StorageManager
94     @Mock
95     private lateinit var mFile: File
96     @Mock
97     private lateinit var mPlatformCompat: PlatformCompat
98 
99     @Before
100     fun setup() {
101         MockitoAnnotations.initMocks(this)
102         mMockSystem.system().stageNominalSystemState()
103         stageBuiltinLibrary(mTempFolder.newFolder())
104         stageScanExistingPackages()
105 
106         mPms = spy(PackageManagerService(mMockSystem.mocks().injector,
107             false /*coreOnly*/,
108             false /*factoryTest*/,
109             MockSystem.DEFAULT_VERSION_INFO.fingerprint,
110             false /*isEngBuild*/,
111             false /*isUserDebugBuild*/,
112             Build.VERSION_CODES.CUR_DEVELOPMENT,
113             Build.VERSION.INCREMENTAL))
114         mMockSystem.system().validateFinalState()
115         mSettings = mMockSystem.mocks().injector.settings
116         mSharedLibrariesImpl = mMockSystem.mocks().injector.sharedLibrariesImpl
117         mSharedLibrariesImpl.setDeletePackageHelper(mDeletePackageHelper)
118         mComputer = spy(mPms.snapshotComputer())
119         mExistingPackages = getExistingPackages(
120             DYNAMIC_LIB_PACKAGE_NAME, STATIC_LIB_PACKAGE_NAME, CONSUMER_PACKAGE_NAME)
121 
122         whenever(mMockSystem.mocks().injector.getSystemService(StorageManager::class.java))
123             .thenReturn(mStorageManager)
124         whenever(mStorageManager.findPathForUuid(nullable())).thenReturn(mFile)
125         doAnswer { mComputer }.`when`(mPms).snapshotComputer()
126         doAnswer { STATIC_LIB_PACKAGE_NAME }.`when`(mComputer).resolveInternalPackageName(
127             eq(STATIC_LIB_DECLARING_PACKAGE_NAME), eq(STATIC_LIB_VERSION))
128         whenever(mDeletePackageHelper.deletePackageX(any(), any(), any(), any(), any()))
129             .thenReturn(PackageManager.DELETE_SUCCEEDED)
130         whenever(mMockSystem.mocks().injector.compatibility).thenReturn(mPlatformCompat)
131         wheneverStatic { HexEncoding.decode(STATIC_LIB_NAME, false) }
132                 .thenReturn(PackageUtils.computeSha256DigestBytes(
133                         mSettings.getPackageLPr(STATIC_LIB_PACKAGE_NAME)
134                             .pkg.signingDetails.signatures!![0].toByteArray()))
135     }
136 
137     @Test
138     fun snapshot_shouldSealed() {
139         val builtinLibs = mSharedLibrariesImpl.snapshot().all[BUILTIN_LIB_NAME]
140         assertThat(builtinLibs).isNotNull()
141 
142         assertFailsWith(IllegalStateException::class) {
143             mSharedLibrariesImpl.snapshot().all[BUILTIN_LIB_NAME] = WatchedLongSparseArray()
144         }
145         assertFailsWith(IllegalStateException::class) {
146             builtinLibs!!.put(VERSION_UNDEFINED, libOfBuiltin(BUILTIN_LIB_NAME))
147         }
148     }
149 
150     @Test
151     fun addBuiltInSharedLibrary() {
152         mSharedLibrariesImpl.addBuiltInSharedLibraryLPw(libEntry(TEST_LIB_NAME))
153 
154         assertThat(mSharedLibrariesImpl.getSharedLibraryInfos(TEST_LIB_NAME)).isNotNull()
155         assertThat(mSharedLibrariesImpl.getSharedLibraryInfo(TEST_LIB_NAME, VERSION_UNDEFINED))
156             .isNotNull()
157     }
158 
159     @Test
160     fun addBuiltInSharedLibrary_withDuplicateLibName() {
161         val duplicate = libEntry(BUILTIN_LIB_NAME, "duplicate.path")
162         mSharedLibrariesImpl.addBuiltInSharedLibraryLPw(duplicate)
163         val sharedLibInfo = mSharedLibrariesImpl
164             .getSharedLibraryInfo(BUILTIN_LIB_NAME, VERSION_UNDEFINED)
165 
166         assertThat(sharedLibInfo).isNotNull()
167         assertThat(sharedLibInfo!!.path).isNotEqualTo(duplicate.filename)
168     }
169 
170     @Test
171     fun commitSharedLibraryInfo_withStaticSharedLib() {
172         val testInfo = libOfStatic(TEST_LIB_PACKAGE_NAME, TEST_LIB_NAME, 1L)
173         mSharedLibrariesImpl.commitSharedLibraryInfoLPw(testInfo)
174         val sharedLibInfos = mSharedLibrariesImpl
175             .getStaticLibraryInfos(testInfo.declaringPackage.packageName)
176 
177         assertThat(mSharedLibrariesImpl.getSharedLibraryInfos(TEST_LIB_NAME))
178             .isNotNull()
179         assertThat(mSharedLibrariesImpl.getSharedLibraryInfo(testInfo.name, testInfo.longVersion))
180             .isNotNull()
181         assertThat(sharedLibInfos).isNotNull()
182         assertThat(sharedLibInfos.get(testInfo.longVersion)).isNotNull()
183     }
184 
185     @Test
186     fun removeSharedLibrary() {
187         val staticInfo = mSharedLibrariesImpl
188             .getSharedLibraryInfo(STATIC_LIB_NAME, STATIC_LIB_VERSION)!!
189 
190         mSharedLibrariesImpl.removeSharedLibraryLPw(STATIC_LIB_NAME, STATIC_LIB_VERSION)
191 
192         assertThat(mSharedLibrariesImpl.getSharedLibraryInfos(STATIC_LIB_NAME)).isNull()
193         assertThat(mSharedLibrariesImpl
194             .getStaticLibraryInfos(staticInfo.declaringPackage.packageName)).isNull()
195     }
196 
197     @Test
198     fun pruneUnusedStaticSharedLibraries() {
199         mSharedLibrariesImpl.pruneUnusedStaticSharedLibraries(mPms.snapshotComputer(),
200             Long.MAX_VALUE, 0)
201 
202         verify(mDeletePackageHelper)
203             .deletePackageX(eq(STATIC_LIB_PACKAGE_NAME), any(), any(), any(), any())
204     }
205 
206     @Test
207     fun getLatestSharedLibraVersion() {
208         val pair = createBasicAndroidPackage(STATIC_LIB_PACKAGE_NAME + "_" + 10, 10L,
209             staticLibrary = STATIC_LIB_NAME, staticLibraryVersion = 10L)
210 
211         val latestInfo =
212             mSharedLibrariesImpl.getLatestStaticSharedLibraVersionLPr(pair.second)!!
213 
214         assertThat(latestInfo).isNotNull()
215         assertThat(latestInfo.name).isEqualTo(STATIC_LIB_NAME)
216         assertThat(latestInfo.longVersion).isEqualTo(STATIC_LIB_VERSION)
217     }
218 
219     @Test
220     fun getStaticSharedLibLatestVersionSetting() {
221         val pair = createBasicAndroidPackage(STATIC_LIB_PACKAGE_NAME + "_" + 10, 10L,
222             staticLibrary = STATIC_LIB_NAME, staticLibraryVersion = 10L)
223         val parsedPackage = pair.second as ParsedPackage
224         val scanRequest = ScanRequest(parsedPackage, null, null, null, null,
225             null, null, null, 0, 0, false, null, null)
226         val scanResult = ScanResult(scanRequest, true, null, null, false, 0, null, null, null)
227 
228         val latestInfoSetting =
229             mSharedLibrariesImpl.getStaticSharedLibLatestVersionSetting(scanResult)!!
230 
231         assertThat(latestInfoSetting).isNotNull()
232         assertThat(latestInfoSetting.packageName).isEqualTo(STATIC_LIB_PACKAGE_NAME)
233     }
234 
235     @Test
236     fun updateSharedLibraries_withDynamicLibPackage() {
237         val testPackageSetting = mSettings.getPackageLPr(DYNAMIC_LIB_PACKAGE_NAME)
238         testPackageSetting.setPkgStateLibraryFiles(listOf())
239         assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
240 
241         mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
242                 null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
243 
244         assertThat(testPackageSetting.usesLibraryFiles).hasSize(1)
245         assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME))
246     }
247 
248     @Test
249     fun updateSharedLibraries_withStaticLibPackage() {
250         val testPackageSetting = mSettings.getPackageLPr(STATIC_LIB_PACKAGE_NAME)
251         testPackageSetting.setPkgStateLibraryFiles(listOf())
252         assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
253 
254         mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
255                 null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
256 
257         assertThat(testPackageSetting.usesLibraryFiles).hasSize(2)
258         assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME))
259         assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME))
260     }
261 
262     @Test
263     fun updateSharedLibraries_withConsumerPackage() {
264         val testPackageSetting = mSettings.getPackageLPr(CONSUMER_PACKAGE_NAME)
265         testPackageSetting.setPkgStateLibraryFiles(listOf())
266         assertThat(testPackageSetting.usesLibraryFiles).isEmpty()
267 
268         mSharedLibrariesImpl.updateSharedLibrariesLPw(testPackageSetting.pkg, testPackageSetting,
269                 null /* changingLib */, null /* changingLibSetting */, mExistingPackages)
270 
271         assertThat(testPackageSetting.usesLibraryFiles).hasSize(3)
272         assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME))
273         assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME))
274         assertThat(testPackageSetting.usesLibraryFiles)
275             .contains(apkPath(STATIC_LIB_DECLARING_PACKAGE_NAME))
276     }
277 
278     @Test
279     fun updateAllSharedLibraries() {
280         mExistingPackages.forEach {
281             val setting = mSettings.getPackageLPr(it.key)
282             setting.setPkgStateLibraryFiles(listOf())
283             assertThat(setting.usesLibraryFiles).isEmpty()
284         }
285 
286         mSharedLibrariesImpl.updateAllSharedLibrariesLPw(
287                 null /* updatedPkg */, null /* updatedPkgSetting */, mExistingPackages)
288 
289         var testPackageSetting = mSettings.getPackageLPr(DYNAMIC_LIB_PACKAGE_NAME)
290         assertThat(testPackageSetting.usesLibraryFiles).hasSize(1)
291         assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME))
292 
293         testPackageSetting = mSettings.getPackageLPr(STATIC_LIB_PACKAGE_NAME)
294         assertThat(testPackageSetting.usesLibraryFiles).hasSize(2)
295         assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME))
296         assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME))
297 
298         testPackageSetting = mSettings.getPackageLPr(CONSUMER_PACKAGE_NAME)
299         assertThat(testPackageSetting.usesLibraryFiles).hasSize(3)
300         assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME))
301         assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME))
302         assertThat(testPackageSetting.usesLibraryFiles)
303             .contains(apkPath(STATIC_LIB_DECLARING_PACKAGE_NAME))
304     }
305 
306     @Test
307     fun getAllowedSharedLibInfos_withStaticSharedLibInfo() {
308         val testInfo = libOfStatic(TEST_LIB_PACKAGE_NAME, TEST_LIB_NAME, 1L)
309         val scanResult = ScanResult(mock(), true, null, null,
310             false, 0, null, testInfo, null)
311 
312         val allowedInfos = mSharedLibrariesImpl.getAllowedSharedLibInfos(scanResult)
313 
314         assertThat(allowedInfos).hasSize(1)
315         assertThat(allowedInfos[0].name).isEqualTo(TEST_LIB_NAME)
316     }
317 
318     @Test
319     fun getAllowedSharedLibInfos_withDynamicSharedLibInfo() {
320         val testInfo = libOfDynamic(TEST_LIB_PACKAGE_NAME, TEST_LIB_NAME)
321         val pair = createBasicAndroidPackage(
322             TEST_LIB_PACKAGE_NAME, 10L, libraries = arrayOf(TEST_LIB_NAME))
323         val parsedPackage = pair.second.apply {
324             isSystem = true
325         } as ParsedPackage
326         val packageSetting = mMockSystem.system()
327             .createBasicSettingBuilder(pair.first.parentFile, parsedPackage.hideAsFinal())
328             .setPkgFlags(ApplicationInfo.FLAG_SYSTEM).build()
329         val scanRequest = ScanRequest(parsedPackage, null, null, null, null,
330             null, null, null, 0, 0, false, null, null)
331         val scanResult = ScanResult(scanRequest, true, packageSetting, null,
332             false, 0, null, null, listOf(testInfo))
333 
334         val allowedInfos = mSharedLibrariesImpl.getAllowedSharedLibInfos(scanResult)
335 
336         assertThat(allowedInfos).hasSize(1)
337         assertThat(allowedInfos[0].name).isEqualTo(TEST_LIB_NAME)
338     }
339 
340     private fun getExistingPackages(vararg args: String): ArrayMap<String, AndroidPackage> {
341         val existingPackages = ArrayMap<String, AndroidPackage>()
342         args.forEach {
343             existingPackages[it] = mSettings.getPackageLPr(it).pkg
344         }
345         return existingPackages
346     }
347 
348     private fun stageBuiltinLibrary(folder: File) {
349         builtinLibDirectory = folder
350         val libPath = File(builtinLibPath(BUILTIN_LIB_NAME))
351         libPath.createNewFile()
352         MockSystem.addDefaultSharedLibrary(BUILTIN_LIB_NAME, libEntry(BUILTIN_LIB_NAME))
353     }
354 
355     private fun stageScanExistingPackages() {
356         // add a dynamic shared library that is using the builtin library
357         stageScanExistingPackage(DYNAMIC_LIB_PACKAGE_NAME, 1L,
358             libraries = arrayOf(DYNAMIC_LIB_NAME),
359             usesLibraries = arrayOf(BUILTIN_LIB_NAME))
360 
361         // add a static shared library v7 that is using the dynamic shared library
362         stageScanExistingPackage(STATIC_LIB_DECLARING_PACKAGE_NAME, STATIC_LIB_VERSION,
363             staticLibrary = STATIC_LIB_NAME, staticLibraryVersion = STATIC_LIB_VERSION,
364             usesLibraries = arrayOf(DYNAMIC_LIB_NAME))
365 
366         // add a consumer package that is using the dynamic and static shared library
367         stageScanExistingPackage(CONSUMER_PACKAGE_NAME, 1L,
368             isSystem = true,
369             usesLibraries = arrayOf(DYNAMIC_LIB_NAME),
370             usesStaticLibraries = arrayOf(STATIC_LIB_NAME),
371             usesStaticLibraryVersions = arrayOf(STATIC_LIB_VERSION))
372     }
373 
374     private fun stageScanExistingPackage(
375         packageName: String,
376         version: Long,
377         isSystem: Boolean = false,
378         libraries: Array<String>? = null,
379         staticLibrary: String? = null,
380         staticLibraryVersion: Long = 0L,
381         usesLibraries: Array<String>? = null,
382         usesStaticLibraries: Array<String>? = null,
383         usesStaticLibraryVersions: Array<Long>? = null
384     ) {
385         val withPackage = { pkg: PackageImpl ->
386             pkg.setSystem(isSystem || libraries != null)
387             pkg.setTargetSdkVersion(Build.VERSION_CODES.S)
388             libraries?.forEach { pkg.addLibraryName(it) }
389             staticLibrary?.let {
390                 pkg.setStaticSharedLibName(it)
391                 pkg.setStaticSharedLibVersion(staticLibraryVersion)
392                 pkg.setStaticSharedLibrary(true)
393             }
394             usesLibraries?.forEach { pkg.addUsesLibrary(it) }
395             usesStaticLibraries?.forEachIndexed { index, s ->
396                 pkg.addUsesStaticLibrary(s,
397                     usesStaticLibraryVersions?.get(index) ?: 0L,
398                     arrayOf(s))
399             }
400             pkg
401         }
402         val withSetting = { settingBuilder: PackageSettingBuilder ->
403             if (staticLibrary != null) {
404                 settingBuilder.setName(getStaticSharedLibInternalPackageName(packageName, version))
405             }
406             if (isSystem || libraries != null) {
407                 settingBuilder.setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
408             }
409             settingBuilder
410         }
411         mMockSystem.system().stageScanExistingPackage(
412             packageName, version, mMockSystem.system().dataAppDirectory, withPackage, withSetting)
413     }
414 
415     private fun createBasicAndroidPackage(
416         packageName: String,
417         version: Long,
418         libraries: Array<String>? = null,
419         staticLibrary: String? = null,
420         staticLibraryVersion: Long = 0L,
421         usesLibraries: Array<String>? = null,
422         usesStaticLibraries: Array<String>? = null,
423         usesStaticLibraryVersions: Array<Long>? = null
424     ): Pair<File, PackageImpl> {
425         assertFalse { libraries != null && staticLibrary != null }
426         assertTrue { (usesStaticLibraries?.size ?: -1) == (usesStaticLibraryVersions?.size ?: -1) }
427 
428         val pair = mMockSystem.system()
429             .createBasicAndroidPackage(mMockSystem.system().dataAppDirectory, packageName, version)
430         pair.second.apply {
431             setTargetSdkVersion(Build.VERSION_CODES.S)
432             libraries?.forEach { addLibraryName(it) }
433             staticLibrary?.let {
434                 setStaticSharedLibName(it)
435                 setStaticSharedLibVersion(staticLibraryVersion)
436                 setStaticSharedLibrary(true)
437             }
438             usesLibraries?.forEach { addUsesLibrary(it) }
439             usesStaticLibraries?.forEachIndexed { index, s ->
440                 addUsesStaticLibrary(s,
441                     usesStaticLibraryVersions?.get(index) ?: 0L,
442                         arrayOf(s))
443             }
444         }
445         return pair
446     }
447 
448     private fun libEntry(libName: String, path: String? = null): SharedLibraryEntry =
449         SharedLibraryEntry(libName, path ?: builtinLibPath(libName),
450             arrayOfNulls(0), false /* isNative */)
451 
452     private fun libOfBuiltin(libName: String): SharedLibraryInfo =
453         SharedLibraryInfo(builtinLibPath(libName),
454             null /* packageName */,
455             null /* codePaths */,
456             libName,
457             VERSION_UNDEFINED,
458             SharedLibraryInfo.TYPE_BUILTIN,
459             VersionedPackage(PLATFORM_PACKAGE_NAME, 0L /* versionCode */),
460             null /* dependentPackages */,
461             null /* dependencies */,
462             false /* isNative */)
463 
464     private fun libOfStatic(
465         declaringPackageName: String,
466         libName: String,
467         version: Long
468     ): SharedLibraryInfo =
469         SharedLibraryInfo(null /* path */,
470             getStaticSharedLibInternalPackageName(declaringPackageName, version),
471             listOf(apkPath(declaringPackageName)),
472             libName,
473             version,
474             SharedLibraryInfo.TYPE_STATIC,
475             VersionedPackage(declaringPackageName, version /* versionCode */),
476             null /* dependentPackages */,
477             null /* dependencies */,
478             false /* isNative */)
479 
480     private fun libOfDynamic(packageName: String, libName: String): SharedLibraryInfo =
481         SharedLibraryInfo(null /* path */,
482             packageName,
483             listOf(apkPath(packageName)),
484             libName,
485             VERSION_UNDEFINED,
486             SharedLibraryInfo.TYPE_DYNAMIC,
487             VersionedPackage(packageName, 1L /* versionCode */),
488             null /* dependentPackages */,
489             null /* dependencies */,
490             false /* isNative */)
491 
492     private fun builtinLibPath(libName: String) =
493         File(builtinLibDirectory, "$libName.jar").path
494 
495     private fun apkPath(packageName: String) =
496         File(mMockSystem.system().dataAppDirectory, packageName).path
497 
498     private fun getStaticSharedLibInternalPackageName(
499         declaringPackageName: String,
500         version: Long
501     ) = "${declaringPackageName}_$version"
502 }
503