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.UserHandle 25 import android.os.storage.StorageManager 26 import android.util.ArrayMap 27 import android.util.PackageUtils 28 import com.android.internal.pm.parsing.pkg.PackageImpl 29 import com.android.internal.pm.parsing.pkg.ParsedPackage 30 import com.android.server.SystemConfig.SharedLibraryEntry 31 import com.android.server.compat.PlatformCompat 32 import com.android.server.extendedtestutils.wheneverStatic 33 import com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME 34 import com.android.server.pm.pkg.AndroidPackage 35 import com.android.server.testutils.any 36 import com.android.server.testutils.eq 37 import com.android.server.testutils.mock 38 import com.android.server.testutils.nullable 39 import com.android.server.testutils.spy 40 import com.android.server.testutils.whenever 41 import com.android.server.utils.WatchedLongSparseArray 42 import com.google.common.truth.Truth.assertThat 43 import java.io.File 44 import kotlin.test.assertFailsWith 45 import kotlin.test.assertFalse 46 import kotlin.test.assertTrue 47 import libcore.util.HexEncoding 48 import org.junit.Before 49 import org.junit.Rule 50 import org.junit.Test 51 import org.junit.rules.RuleChain 52 import org.junit.rules.TemporaryFolder 53 import org.junit.runner.RunWith 54 import org.junit.runners.JUnit4 55 import org.mockito.Mock 56 import org.mockito.Mockito.doAnswer 57 import org.mockito.Mockito.verify 58 import org.mockito.MockitoAnnotations 59 60 @RunWith(JUnit4::class) 61 class SharedLibrariesImplTest { 62 63 companion object { 64 const val TEST_LIB_NAME = "test.lib" 65 const val TEST_LIB_PACKAGE_NAME = "com.android.lib.test" 66 const val BUILTIN_LIB_NAME = "builtin.lib" 67 const val STATIC_LIB_NAME = "static.lib" 68 const val STATIC_LIB_VERSION = 7L 69 const val STATIC_LIB_DECLARING_PACKAGE_NAME = "com.android.lib.static.provider" 70 const val STATIC_LIB_PACKAGE_NAME = "com.android.lib.static.provider_7" 71 const val DYNAMIC_LIB_NAME = "dynamic.lib" 72 const val DYNAMIC_LIB_PACKAGE_NAME = "com.android.lib.dynamic.provider" 73 const val CONSUMER_PACKAGE_NAME = "com.android.lib.consumer" 74 const val VERSION_UNDEFINED = SharedLibraryInfo.VERSION_UNDEFINED.toLong() 75 } 76 77 private val mMockSystem = MockSystemRule() 78 private val mTempFolder = TemporaryFolder() 79 80 @Rule 81 @JvmField 82 val mRules = RuleChain.outerRule(mTempFolder).around(mMockSystem)!! 83 84 private lateinit var mSharedLibrariesImpl: SharedLibrariesImpl 85 private lateinit var mPms: PackageManagerService 86 private lateinit var mSettings: Settings 87 private lateinit var mComputer: Computer 88 private lateinit var mExistingPackages: ArrayMap<String, AndroidPackage> 89 private lateinit var builtinLibDirectory: File 90 91 @Mock 92 private lateinit var mDeletePackageHelper: DeletePackageHelper 93 @Mock 94 private lateinit var mStorageManager: StorageManager 95 @Mock 96 private lateinit var mFile: File 97 @Mock 98 private lateinit var mPlatformCompat: PlatformCompat 99 100 @Before 101 fun setup() { 102 MockitoAnnotations.initMocks(this) 103 mMockSystem.system().stageNominalSystemState() 104 stageBuiltinLibrary(mTempFolder.newFolder()) 105 stageScanExistingPackages() 106 107 mPms = spy(PackageManagerService(mMockSystem.mocks().injector, 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.removeSharedLibrary(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.getLatestStaticSharedLibraVersion(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, null, null, false, 0, null, null, null) 227 var installRequest = InstallRequest(parsedPackage, 0, 0, UserHandle(0), scanResult, null) 228 229 val latestInfoSetting = 230 mSharedLibrariesImpl.getStaticSharedLibLatestVersionSetting(installRequest)!! 231 232 assertThat(latestInfoSetting).isNotNull() 233 assertThat(latestInfoSetting.packageName).isEqualTo(STATIC_LIB_PACKAGE_NAME) 234 } 235 236 @Test 237 fun updateSharedLibraries_withDynamicLibPackage() { 238 val testPackageSetting = mSettings.getPackageLPr(DYNAMIC_LIB_PACKAGE_NAME) 239 testPackageSetting.setPkgStateLibraryFiles(listOf()) 240 assertThat(testPackageSetting.usesLibraryFiles).isEmpty() 241 242 mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg!!, testPackageSetting, 243 null /* changingLib */, null /* changingLibSetting */, mExistingPackages) 244 245 assertThat(testPackageSetting.usesLibraryFiles).hasSize(1) 246 assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME)) 247 } 248 249 @Test 250 fun updateSharedLibraries_withStaticLibPackage() { 251 val testPackageSetting = mSettings.getPackageLPr(STATIC_LIB_PACKAGE_NAME) 252 testPackageSetting.setPkgStateLibraryFiles(listOf()) 253 assertThat(testPackageSetting.usesLibraryFiles).isEmpty() 254 255 mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg!!, testPackageSetting, 256 null /* changingLib */, null /* changingLibSetting */, mExistingPackages) 257 258 assertThat(testPackageSetting.usesLibraryFiles).hasSize(2) 259 assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME)) 260 assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME)) 261 } 262 263 @Test 264 fun updateSharedLibraries_withConsumerPackage() { 265 val testPackageSetting = mSettings.getPackageLPr(CONSUMER_PACKAGE_NAME) 266 testPackageSetting.setPkgStateLibraryFiles(listOf()) 267 assertThat(testPackageSetting.usesLibraryFiles).isEmpty() 268 269 mSharedLibrariesImpl.updateSharedLibraries(testPackageSetting.pkg!!, testPackageSetting, 270 null /* changingLib */, null /* changingLibSetting */, mExistingPackages) 271 272 assertThat(testPackageSetting.usesLibraryFiles).hasSize(3) 273 assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME)) 274 assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME)) 275 assertThat(testPackageSetting.usesLibraryFiles) 276 .contains(apkPath(STATIC_LIB_DECLARING_PACKAGE_NAME)) 277 } 278 279 @Test 280 fun updateAllSharedLibraries() { 281 mExistingPackages.forEach { 282 val setting = mSettings.getPackageLPr(it.key) 283 setting.setPkgStateLibraryFiles(listOf()) 284 assertThat(setting.usesLibraryFiles).isEmpty() 285 } 286 287 mSharedLibrariesImpl.updateAllSharedLibrariesLPw( 288 null /* updatedPkg */, null /* updatedPkgSetting */, mExistingPackages) 289 290 var testPackageSetting = mSettings.getPackageLPr(DYNAMIC_LIB_PACKAGE_NAME) 291 assertThat(testPackageSetting.usesLibraryFiles).hasSize(1) 292 assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME)) 293 294 testPackageSetting = mSettings.getPackageLPr(STATIC_LIB_PACKAGE_NAME) 295 assertThat(testPackageSetting.usesLibraryFiles).hasSize(2) 296 assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME)) 297 assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME)) 298 299 testPackageSetting = mSettings.getPackageLPr(CONSUMER_PACKAGE_NAME) 300 assertThat(testPackageSetting.usesLibraryFiles).hasSize(3) 301 assertThat(testPackageSetting.usesLibraryFiles).contains(builtinLibPath(BUILTIN_LIB_NAME)) 302 assertThat(testPackageSetting.usesLibraryFiles).contains(apkPath(DYNAMIC_LIB_PACKAGE_NAME)) 303 assertThat(testPackageSetting.usesLibraryFiles) 304 .contains(apkPath(STATIC_LIB_DECLARING_PACKAGE_NAME)) 305 } 306 307 @Test 308 fun getAllowedSharedLibInfos_withStaticSharedLibInfo() { 309 val testInfo = libOfStatic(TEST_LIB_PACKAGE_NAME, TEST_LIB_NAME, 1L) 310 val scanResult = ScanResult(mock(), null, null, 311 false, 0, null, testInfo, null) 312 var installRequest = InstallRequest(mock(), 0, 0, UserHandle(0), scanResult, null) 313 314 val allowedInfos = mSharedLibrariesImpl.getAllowedSharedLibInfos(installRequest) 315 316 assertThat(allowedInfos).hasSize(1) 317 assertThat(allowedInfos[0].name).isEqualTo(TEST_LIB_NAME) 318 } 319 320 @Test 321 fun getAllowedSharedLibInfos_withDynamicSharedLibInfo() { 322 val testInfo = libOfDynamic(TEST_LIB_PACKAGE_NAME, TEST_LIB_NAME) 323 val pair = createBasicAndroidPackage( 324 TEST_LIB_PACKAGE_NAME, 10L, libraries = arrayOf(TEST_LIB_NAME)) 325 val parsedPackage = pair.second.apply { 326 isSystem = true 327 } as ParsedPackage 328 val packageSetting = mMockSystem.system() 329 .createBasicSettingBuilder(pair.first.parentFile, parsedPackage.hideAsFinal()) 330 .setPkgFlags(ApplicationInfo.FLAG_SYSTEM).build() 331 val scanRequest = ScanRequest(parsedPackage, null, null, null, null, 332 null, null, null, 0, 0, false, null, null) 333 val scanResult = ScanResult(scanRequest, packageSetting, null, 334 false, 0, null, null, listOf(testInfo)) 335 var installRequest = InstallRequest(parsedPackage, 0, 0, UserHandle(0), scanResult, null) 336 337 val allowedInfos = mSharedLibrariesImpl.getAllowedSharedLibInfos(installRequest) 338 339 assertThat(allowedInfos).hasSize(1) 340 assertThat(allowedInfos[0].name).isEqualTo(TEST_LIB_NAME) 341 } 342 343 private fun getExistingPackages(vararg args: String): ArrayMap<String, AndroidPackage> { 344 val existingPackages = ArrayMap<String, AndroidPackage>() 345 args.forEach { 346 existingPackages[it] = mSettings.getPackageLPr(it).pkg 347 } 348 return existingPackages 349 } 350 351 private fun stageBuiltinLibrary(folder: File) { 352 builtinLibDirectory = folder 353 val libPath = File(builtinLibPath(BUILTIN_LIB_NAME)) 354 libPath.createNewFile() 355 MockSystem.addDefaultSharedLibrary(BUILTIN_LIB_NAME, libEntry(BUILTIN_LIB_NAME)) 356 } 357 358 private fun stageScanExistingPackages() { 359 // add a dynamic shared library that is using the builtin library 360 stageScanExistingPackage(DYNAMIC_LIB_PACKAGE_NAME, 1L, 361 libraries = arrayOf(DYNAMIC_LIB_NAME), 362 usesLibraries = arrayOf(BUILTIN_LIB_NAME)) 363 364 // add a static shared library v7 that is using the dynamic shared library 365 stageScanExistingPackage(STATIC_LIB_DECLARING_PACKAGE_NAME, STATIC_LIB_VERSION, 366 staticLibrary = STATIC_LIB_NAME, staticLibraryVersion = STATIC_LIB_VERSION, 367 usesLibraries = arrayOf(DYNAMIC_LIB_NAME)) 368 369 // add a consumer package that is using the dynamic and static shared library 370 stageScanExistingPackage(CONSUMER_PACKAGE_NAME, 1L, 371 isSystem = true, 372 usesLibraries = arrayOf(DYNAMIC_LIB_NAME), 373 usesStaticLibraries = arrayOf(STATIC_LIB_NAME), 374 usesStaticLibraryVersions = arrayOf(STATIC_LIB_VERSION)) 375 } 376 377 private fun stageScanExistingPackage( 378 packageName: String, 379 version: Long, 380 isSystem: Boolean = false, 381 libraries: Array<String>? = null, 382 staticLibrary: String? = null, 383 staticLibraryVersion: Long = 0L, 384 usesLibraries: Array<String>? = null, 385 usesStaticLibraries: Array<String>? = null, 386 usesStaticLibraryVersions: Array<Long>? = null 387 ) { 388 val withPackage = { pkg: PackageImpl -> 389 pkg.setSystem(isSystem || libraries != null) 390 pkg.setTargetSdkVersion(Build.VERSION_CODES.S) 391 libraries?.forEach { pkg.addLibraryName(it) } 392 staticLibrary?.let { 393 pkg.setStaticSharedLibraryName(it) 394 pkg.setStaticSharedLibraryVersion(staticLibraryVersion) 395 pkg.setStaticSharedLibrary(true) 396 } 397 usesLibraries?.forEach { pkg.addUsesLibrary(it) } 398 usesStaticLibraries?.forEachIndexed { index, s -> 399 pkg.addUsesStaticLibrary(s, 400 usesStaticLibraryVersions?.get(index) ?: 0L, 401 arrayOf(s)) 402 } 403 pkg 404 } 405 val withSetting = { settingBuilder: PackageSettingBuilder -> 406 if (staticLibrary != null) { 407 settingBuilder.setName(getStaticSharedLibInternalPackageName(packageName, version)) 408 } 409 if (isSystem || libraries != null) { 410 settingBuilder.setPkgFlags(ApplicationInfo.FLAG_SYSTEM) 411 } 412 settingBuilder 413 } 414 mMockSystem.system().stageScanExistingPackage( 415 packageName, version, mMockSystem.system().dataAppDirectory, withPackage, withSetting) 416 } 417 418 private fun createBasicAndroidPackage( 419 packageName: String, 420 version: Long, 421 libraries: Array<String>? = null, 422 staticLibrary: String? = null, 423 staticLibraryVersion: Long = 0L, 424 usesLibraries: Array<String>? = null, 425 usesStaticLibraries: Array<String>? = null, 426 usesStaticLibraryVersions: Array<Long>? = null 427 ): Pair<File, PackageImpl> { 428 assertFalse { libraries != null && staticLibrary != null } 429 assertTrue { (usesStaticLibraries?.size ?: -1) == (usesStaticLibraryVersions?.size ?: -1) } 430 431 val pair = mMockSystem.system() 432 .createBasicAndroidPackage(mMockSystem.system().dataAppDirectory, packageName, version) 433 pair.second.apply { 434 setTargetSdkVersion(Build.VERSION_CODES.S) 435 libraries?.forEach { addLibraryName(it) } 436 staticLibrary?.let { 437 setStaticSharedLibraryName(it) 438 setStaticSharedLibraryVersion(staticLibraryVersion) 439 setStaticSharedLibrary(true) 440 } 441 usesLibraries?.forEach { addUsesLibrary(it) } 442 usesStaticLibraries?.forEachIndexed { index, s -> 443 addUsesStaticLibrary(s, 444 usesStaticLibraryVersions?.get(index) ?: 0L, 445 arrayOf(s)) 446 } 447 } 448 return pair 449 } 450 451 private fun libEntry(libName: String, path: String? = null): SharedLibraryEntry = 452 SharedLibraryEntry(libName, path ?: builtinLibPath(libName), 453 arrayOfNulls(0), false /* isNative */) 454 455 private fun libOfBuiltin(libName: String): SharedLibraryInfo = 456 SharedLibraryInfo(builtinLibPath(libName), 457 null /* packageName */, 458 null /* codePaths */, 459 libName, 460 VERSION_UNDEFINED, 461 SharedLibraryInfo.TYPE_BUILTIN, 462 VersionedPackage(PLATFORM_PACKAGE_NAME, 0L /* versionCode */), 463 null /* dependentPackages */, 464 null /* dependencies */, 465 false /* isNative */) 466 467 private fun libOfStatic( 468 declaringPackageName: String, 469 libName: String, 470 version: Long 471 ): SharedLibraryInfo = 472 SharedLibraryInfo(null /* path */, 473 getStaticSharedLibInternalPackageName(declaringPackageName, version), 474 listOf(apkPath(declaringPackageName)), 475 libName, 476 version, 477 SharedLibraryInfo.TYPE_STATIC, 478 VersionedPackage(declaringPackageName, version /* versionCode */), 479 null /* dependentPackages */, 480 null /* dependencies */, 481 false /* isNative */) 482 483 private fun libOfDynamic(packageName: String, libName: String): SharedLibraryInfo = 484 SharedLibraryInfo(null /* path */, 485 packageName, 486 listOf(apkPath(packageName)), 487 libName, 488 VERSION_UNDEFINED, 489 SharedLibraryInfo.TYPE_DYNAMIC, 490 VersionedPackage(packageName, 1L /* versionCode */), 491 null /* dependentPackages */, 492 null /* dependencies */, 493 false /* isNative */) 494 495 private fun builtinLibPath(libName: String) = 496 File(builtinLibDirectory, "$libName.jar").path 497 498 private fun apkPath(packageName: String) = 499 File(mMockSystem.system().dataAppDirectory, packageName).path 500 501 private fun getStaticSharedLibInternalPackageName( 502 declaringPackageName: String, 503 version: Long 504 ) = "${declaringPackageName}_$version" 505 } 506