diff options
6 files changed, 141 insertions, 6 deletions
diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java index 4220590a6943..c83cf9601cd7 100644 --- a/core/java/android/content/pm/parsing/ApkLite.java +++ b/core/java/android/content/pm/parsing/ApkLite.java @@ -156,6 +156,12 @@ public class ApkLite { */ private final @Nullable String[][] mUsesSdkLibrariesCertDigests; + private final @NonNull List<String> mUsesStaticLibraries; + + private final @Nullable long[] mUsesStaticLibrariesVersions; + + private final @Nullable String[][] mUsesStaticLibrariesCertDigests; + /** * Indicates if this system app can be updated. */ @@ -185,7 +191,10 @@ public class ApkLite { Set<String> requiredSplitTypes, Set<String> splitTypes, boolean hasDeviceAdminReceiver, boolean isSdkLibrary, List<String> usesSdkLibraries, long[] usesSdkLibrariesVersionsMajor, - String[][] usesSdkLibrariesCertDigests, boolean updatableSystem, + String[][] usesSdkLibrariesCertDigests, + List<String> usesStaticLibraries, long[] usesStaticLibrariesVersionsMajor, + String[][] usesStaticLibrariesCertDigests, + boolean updatableSystem, String emergencyInstaller, List<SharedLibraryInfo> declaredLibraries) { mPath = path; mPackageName = packageName; @@ -223,6 +232,9 @@ public class ApkLite { mUsesSdkLibraries = usesSdkLibraries; mUsesSdkLibrariesVersionsMajor = usesSdkLibrariesVersionsMajor; mUsesSdkLibrariesCertDigests = usesSdkLibrariesCertDigests; + mUsesStaticLibraries = usesStaticLibraries; + mUsesStaticLibrariesVersions = usesStaticLibrariesVersionsMajor; + mUsesStaticLibrariesCertDigests = usesStaticLibrariesCertDigests; mUpdatableSystem = updatableSystem; mEmergencyInstaller = emergencyInstaller; mArchivedPackage = null; @@ -266,6 +278,9 @@ public class ApkLite { mUsesSdkLibraries = Collections.emptyList(); mUsesSdkLibrariesVersionsMajor = null; mUsesSdkLibrariesCertDigests = null; + mUsesStaticLibraries = Collections.emptyList(); + mUsesStaticLibrariesVersions = null; + mUsesStaticLibrariesCertDigests = null; mUpdatableSystem = true; mEmergencyInstaller = null; mArchivedPackage = archivedPackage; @@ -602,6 +617,21 @@ public class ApkLite { return mUsesSdkLibrariesCertDigests; } + @DataClass.Generated.Member + public @NonNull List<String> getUsesStaticLibraries() { + return mUsesStaticLibraries; + } + + @DataClass.Generated.Member + public @Nullable long[] getUsesStaticLibrariesVersions() { + return mUsesStaticLibrariesVersions; + } + + @DataClass.Generated.Member + public @Nullable String[][] getUsesStaticLibrariesCertDigests() { + return mUsesStaticLibrariesCertDigests; + } + /** * Indicates if this system app can be updated. */ @@ -632,10 +662,10 @@ public class ApkLite { } @DataClass.Generated( - time = 1729247366948L, + time = 1730202160705L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java", - inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final boolean mUpdatableSystem\nprivate final @android.annotation.Nullable java.lang.String mEmergencyInstaller\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java index 50d875845b2f..34c3f5798bc5 100644 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java @@ -91,6 +91,7 @@ public class ApkLiteParseUtils { private static final String TAG_USES_SPLIT = "uses-split"; private static final String TAG_MANIFEST = "manifest"; private static final String TAG_USES_SDK_LIBRARY = "uses-sdk-library"; + private static final String TAG_USES_STATIC_LIBRARY = "uses-static-library"; private static final String TAG_SDK_LIBRARY = "sdk-library"; private static final int SDK_VERSION = Build.VERSION.SDK_INT; private static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES; @@ -466,6 +467,11 @@ public class ApkLiteParseUtils { List<String> usesSdkLibraries = new ArrayList<>(); long[] usesSdkLibrariesVersionsMajor = new long[0]; String[][] usesSdkLibrariesCertDigests = new String[0][0]; + + List<String> usesStaticLibraries = new ArrayList<>(); + long[] usesStaticLibrariesVersions = new long[0]; + String[][] usesStaticLibrariesCertDigests = new String[0][0]; + List<SharedLibraryInfo> declaredLibraries = new ArrayList<>(); // Only search the tree when the tag is the direct child of <manifest> tag @@ -580,6 +586,51 @@ public class ApkLiteParseUtils { usesSdkLibrariesCertDigests, new String[]{usesSdkCertDigest}, /*allowDuplicates=*/ true); break; + case TAG_USES_STATIC_LIBRARY: + String usesStaticLibName = parser.getAttributeValue( + ANDROID_RES_NAMESPACE, "name"); + long usesStaticLibVersion = parser.getAttributeIntValue( + ANDROID_RES_NAMESPACE, "version", -1); + String usesStaticLibCertDigest = parser.getAttributeValue( + ANDROID_RES_NAMESPACE, "certDigest"); + + if (usesStaticLibName == null || usesStaticLibName.isBlank() + || usesStaticLibVersion < 0 + || usesStaticLibCertDigest == null) { + return input.error( + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, + "Bad uses-static-library declaration name: " + + usesStaticLibName + + " version: " + usesStaticLibVersion + + " certDigest: " + usesStaticLibCertDigest); + } + + if (usesStaticLibraries.contains(usesStaticLibName)) { + return input.error( + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, + "Bad uses-sdk-library declaration. Depending on" + + " multiple versions of static library: " + + usesStaticLibName); + } + + usesStaticLibraries.add(usesStaticLibName); + usesStaticLibrariesVersions = ArrayUtils.appendLong( + usesStaticLibrariesVersions, usesStaticLibVersion, + /*allowDuplicates=*/ true); + + // We allow ":" delimiters in the SHA declaration as this is the format + // emitted by the certtool making it easy for developers to copy/paste. + // TODO(372862145): Add test for this replacement + usesStaticLibCertDigest = + usesStaticLibCertDigest.replace(":", "").toLowerCase(); + + // TODO(372862145): Add support for multiple signer for app targeting + // O-MR1 + usesStaticLibrariesCertDigests = ArrayUtils.appendElement( + String[].class, usesStaticLibrariesCertDigests, + new String[]{usesStaticLibCertDigest}, + /*allowDuplicates=*/ true); + break; case TAG_SDK_LIBRARY: isSdkLibrary = true; // Mirrors ParsingPackageUtils#parseSdkLibrary until lite and full @@ -753,7 +804,9 @@ public class ApkLiteParseUtils { rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second, hasDeviceAdminReceiver, isSdkLibrary, usesSdkLibraries, usesSdkLibrariesVersionsMajor, usesSdkLibrariesCertDigests, - updatableSystem, emergencyInstaller, declaredLibraries)); + usesStaticLibraries, usesStaticLibrariesVersions, + usesStaticLibrariesCertDigests, updatableSystem, emergencyInstaller, + declaredLibraries)); } private static boolean isDeviceAdminReceiver( diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java index 79c597327f5a..76b25fed2ac2 100644 --- a/core/java/android/content/pm/parsing/PackageLite.java +++ b/core/java/android/content/pm/parsing/PackageLite.java @@ -121,6 +121,12 @@ public class PackageLite { private final @Nullable String[][] mUsesSdkLibrariesCertDigests; + private final @NonNull List<String> mUsesStaticLibraries; + + private final @Nullable long[] mUsesStaticLibrariesVersions; + + private final @Nullable String[][] mUsesStaticLibrariesCertDigests; + private final @NonNull List<SharedLibraryInfo> mDeclaredLibraries; /** @@ -158,6 +164,9 @@ public class PackageLite { mUsesSdkLibraries = baseApk.getUsesSdkLibraries(); mUsesSdkLibrariesVersionsMajor = baseApk.getUsesSdkLibrariesVersionsMajor(); mUsesSdkLibrariesCertDigests = baseApk.getUsesSdkLibrariesCertDigests(); + mUsesStaticLibraries = baseApk.getUsesStaticLibraries(); + mUsesStaticLibrariesVersions = baseApk.getUsesStaticLibrariesVersions(); + mUsesStaticLibrariesCertDigests = baseApk.getUsesStaticLibrariesCertDigests(); mSplitNames = splitNames; mSplitTypes = splitTypes; mIsFeatureSplits = isFeatureSplits; @@ -462,6 +471,21 @@ public class PackageLite { } @DataClass.Generated.Member + public @NonNull List<String> getUsesStaticLibraries() { + return mUsesStaticLibraries; + } + + @DataClass.Generated.Member + public @Nullable long[] getUsesStaticLibrariesVersions() { + return mUsesStaticLibrariesVersions; + } + + @DataClass.Generated.Member + public @Nullable String[][] getUsesStaticLibrariesCertDigests() { + return mUsesStaticLibrariesCertDigests; + } + + @DataClass.Generated.Member public @NonNull List<SharedLibraryInfo> getDeclaredLibraries() { return mDeclaredLibraries; } @@ -475,10 +499,10 @@ public class PackageLite { } @DataClass.Generated( - time = 1729248757933L, + time = 1730203707341L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java", - inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesSdkLibraries\nprivate final @android.annotation.Nullable long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesSdkLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesStaticLibraries\nprivate final @android.annotation.Nullable long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.Nullable java.lang.String[][] mUsesStaticLibrariesCertDigests\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mDeclaredLibraries\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") @Deprecated private void __metadata() {} diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index aee1c3b2f28c..2490725aaf17 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -150,6 +150,7 @@ android_test { ":HelloWorldUsingSdk1AndSdk1", ":HelloWorldUsingSdk1And2", ":HelloWorldUsingSdkMalformedNegativeVersion", + ":CtsStaticSharedLibConsumerApp1", ], } diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml index 3bc81724bc0a..3f7c83a82787 100644 --- a/core/tests/coretests/AndroidTest.xml +++ b/core/tests/coretests/AndroidTest.xml @@ -39,6 +39,8 @@ value="/data/local/tmp/tests/coretests/pm/HelloWorldUsingSdkMalformedNegativeVersion.apk"/> <option name="push-file" key="HelloWorldSdk1.apk" value="/data/local/tmp/tests/coretests/pm/HelloWorldSdk1.apk"/> + <option name="push-file" key="CtsStaticSharedLibConsumerApp1.apk" + value="/data/local/tmp/tests/coretests/pm/CtsStaticSharedLibConsumerApp1.apk"/> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> diff --git a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java index f9b481ffc1ef..d4618d744644 100644 --- a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java +++ b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java @@ -71,6 +71,7 @@ public class ApkLiteParseUtilsTest { private static final String TEST_APP_USING_SDK1_AND_SDK1 = "HelloWorldUsingSdk1AndSdk1.apk"; private static final String TEST_APP_USING_SDK_MALFORMED_VERSION = "HelloWorldUsingSdkMalformedNegativeVersion.apk"; + private static final String TEST_APP_USING_STATIC_LIB = "CtsStaticSharedLibConsumerApp1.apk"; private static final String TEST_SDK1 = "HelloWorldSdk1.apk"; private static final String TEST_SDK1_PACKAGE = "com.test.sdk1_1"; private static final String TEST_SDK1_NAME = "com.test.sdk1"; @@ -166,6 +167,30 @@ public class ApkLiteParseUtilsTest { @SuppressLint("CheckResult") @Test + public void testParseApkLite_getUsesStaticLibrary_sameAsPackageParser() throws Exception { + File apkFile = copyApkToTmpDir(TEST_APP_USING_STATIC_LIB); + ParseResult<ApkLite> result = ApkLiteParseUtils + .parseApkLite(ParseTypeImpl.forDefaultParsing().reset(), apkFile, 0); + assertThat(result.isError()).isFalse(); + ApkLite baseApk = result.getResult(); + + AndroidPackage pkg = mPackageParser2.parsePackage(apkFile, 0, true).hideAsFinal(); + assertThat(baseApk.getUsesStaticLibraries()) + .containsExactlyElementsIn(pkg.getUsesStaticLibraries()); + List<Long> versionsBoxed = Arrays.stream(pkg.getUsesStaticLibrariesVersions()).boxed() + .toList(); + assertThat(baseApk.getUsesStaticLibrariesVersions()).asList() + .containsExactlyElementsIn(versionsBoxed); + + String[][] liteCerts = baseApk.getUsesStaticLibrariesCertDigests(); + String[][] pkgCerts = pkg.getUsesStaticLibrariesCertDigests(); + for (int i = 0; i < liteCerts.length; i++) { + assertThat(liteCerts[i]).isEqualTo(pkgCerts[i]); + } + } + + @SuppressLint("CheckResult") + @Test public void testParseApkLite_malformedUsesSdkLibrary_duplicate() throws Exception { File apkFile = copyApkToTmpDir(TEST_APP_USING_SDK1_AND_SDK1); ParseResult<ApkLite> result = ApkLiteParseUtils |