Loading core/java/android/content/pm/PackageParser.java +24 −59 Original line number Diff line number Diff line Loading @@ -4782,7 +4782,7 @@ public class PackageParser { // except for watches which always supported 1:1. minAspectRatio = owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q ? 0 : mCallback.hasFeature(FEATURE_WATCH) : (mCallback != null && mCallback.hasFeature(FEATURE_WATCH)) ? DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH : DEFAULT_PRE_Q_MIN_ASPECT_RATIO; } Loading Loading @@ -8359,71 +8359,36 @@ public class PackageParser { } // TODO(b/129261524): Clean up API public static PackageInfo generatePackageInfoFromApex(File apexFile, boolean collectCerts) /** * PackageInfo parser specifically for apex files. * NOTE: It will collect certificates * * @param apexFile * @return PackageInfo * @throws PackageParserException */ public static PackageInfo generatePackageInfoFromApex(File apexFile, int flags) throws PackageParserException { PackageInfo pi = new PackageInfo(); int parseFlags = 0; if (collectCerts) { parseFlags |= PARSE_COLLECT_CERTIFICATES; try { if (apexFile.getCanonicalPath().startsWith("/system")) { // Don't need verify the APK integrity of APEXes on /system, just like // we don't do that for APKs. // TODO(b/126514108): we may be able to do this for APEXes on /data as well. parseFlags |= PARSE_IS_SYSTEM_DIR; } } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, "Failed to get path for " + apexFile.getPath(), e); } } PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile, parseFlags); // Properly fill in the ApplicationInfo with data from AndroidManifest // Add ApplicationInfo to the PackageInfo. // TODO(b/129267599) ApplicationInfo ai = new ApplicationInfo(); ai.packageName = apk.packageName; ai.sourceDir = apexFile.getPath(); ai.flags = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED; ai.enabled = true; ai.minSdkVersion = apk.minSdkVersion; ai.targetSdkVersion = apk.targetSdkVersion; ai.targetSandboxVersion = PARSE_DEFAULT_TARGET_SANDBOX; ai.setVersionCode(apk.getLongVersionCode()); pi.packageName = apk.packageName; pi.splitNames = new String[]{apk.splitName}; pi.setLongVersionCode(apk.getLongVersionCode()); pi.applicationInfo = ai; pi.coreApp = apk.coreApp; if (collectCerts) { if (apk.signingDetails.hasPastSigningCertificates()) { // Package has included signing certificate rotation information. Return // the oldest cert so that programmatic checks keep working even if unaware // of key rotation. pi.signatures = new Signature[1]; pi.signatures[0] = apk.signingDetails.pastSigningCertificates[0]; } else if (apk.signingDetails.hasSignatures()) { // otherwise keep old behavior int numberOfSigs = apk.signingDetails.signatures.length; pi.signatures = new Signature[numberOfSigs]; System.arraycopy(apk.signingDetails.signatures, 0, pi.signatures, 0, numberOfSigs); } PackageParser pp = new PackageParser(); final Package p = pp.parsePackage(apexFile, flags, false); PackageUserState state = new PackageUserState(); PackageInfo pi = generatePackageInfo(p, EmptyArray.INT, flags, 0, 0, Collections.emptySet(), state); pi.applicationInfo.sourceDir = apexFile.getPath(); pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED; pi.isApex = true; if (apk.signingDetails != SigningDetails.UNKNOWN) { // Collect certificates if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { collectCertificates(p, apexFile, false); if (p.mSigningDetails != SigningDetails.UNKNOWN) { // only return a valid SigningInfo if there is signing information to report pi.signingInfo = new SigningInfo(apk.signingDetails); pi.signingInfo = new SigningInfo(p.mSigningDetails); } else { pi.signingInfo = null; } } pi.isApex = true; return pi; } } core/tests/coretests/res/raw/com_android_tzdata.apex −11.1 KiB (945 KiB) File changed.No diff preview for this file type. View original file View changed file core/tests/coretests/src/android/content/pm/PackageParserTest.java +8 −18 Original line number Diff line number Diff line Loading @@ -499,30 +499,20 @@ public class PackageParserTest { public void testApexPackageInfoGeneration() throws Exception { File apexFile = copyRawResourceToFile("com.android.tzdata.apex", R.raw.com_android_tzdata); PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, false); int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, flags); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertTrue(pi.applicationInfo.enabled); assertEquals(28, pi.applicationInfo.targetSdkVersion); assertEquals(1, pi.applicationInfo.longVersionCode); assertEquals(191000070, pi.applicationInfo.longVersionCode); assertNotNull(pi.applicationInfo.metaData); assertEquals(apexFile.getPath(), pi.applicationInfo.sourceDir); assertEquals("Bundle[{com.android.vending.derived.apk.id=1}]", pi.applicationInfo.metaData.toString()); assertEquals("com.google.android.tzdata", pi.packageName); assertTrue(pi.splitNames.length > 0); assertEquals(1, pi.getLongVersionCode()); assertNull(pi.signingInfo); assertNull(pi.signatures); assertTrue(pi.isApex); pi = PackageParser.generatePackageInfoFromApex(apexFile, true); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertTrue(pi.applicationInfo.enabled); assertEquals(28, pi.applicationInfo.targetSdkVersion); assertEquals(1, pi.applicationInfo.longVersionCode); assertEquals("com.google.android.tzdata", pi.packageName); assertTrue(pi.splitNames.length > 0); assertEquals(1, pi.getLongVersionCode()); assertEquals(191000070, pi.getLongVersionCode()); assertNotNull(pi.signingInfo); assertNotNull(pi.signatures); assertTrue(pi.signingInfo.getApkContentsSigners().length > 0); assertTrue(pi.isApex); } Loading services/core/java/com/android/server/pm/ApexManager.java +3 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.PackageParser.PackageParserException; import android.os.RemoteException; Loading Loading @@ -95,7 +96,8 @@ class ApexManager { } try { list.add(PackageParser.generatePackageInfoFromApex( new File(ai.packagePath), true /* collect certs */)); new File(ai.packagePath), PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES)); } catch (PackageParserException pe) { throw new IllegalStateException("Unable to parse: " + ai, pe); } Loading Loading
core/java/android/content/pm/PackageParser.java +24 −59 Original line number Diff line number Diff line Loading @@ -4782,7 +4782,7 @@ public class PackageParser { // except for watches which always supported 1:1. minAspectRatio = owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q ? 0 : mCallback.hasFeature(FEATURE_WATCH) : (mCallback != null && mCallback.hasFeature(FEATURE_WATCH)) ? DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH : DEFAULT_PRE_Q_MIN_ASPECT_RATIO; } Loading Loading @@ -8359,71 +8359,36 @@ public class PackageParser { } // TODO(b/129261524): Clean up API public static PackageInfo generatePackageInfoFromApex(File apexFile, boolean collectCerts) /** * PackageInfo parser specifically for apex files. * NOTE: It will collect certificates * * @param apexFile * @return PackageInfo * @throws PackageParserException */ public static PackageInfo generatePackageInfoFromApex(File apexFile, int flags) throws PackageParserException { PackageInfo pi = new PackageInfo(); int parseFlags = 0; if (collectCerts) { parseFlags |= PARSE_COLLECT_CERTIFICATES; try { if (apexFile.getCanonicalPath().startsWith("/system")) { // Don't need verify the APK integrity of APEXes on /system, just like // we don't do that for APKs. // TODO(b/126514108): we may be able to do this for APEXes on /data as well. parseFlags |= PARSE_IS_SYSTEM_DIR; } } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION, "Failed to get path for " + apexFile.getPath(), e); } } PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile, parseFlags); // Properly fill in the ApplicationInfo with data from AndroidManifest // Add ApplicationInfo to the PackageInfo. // TODO(b/129267599) ApplicationInfo ai = new ApplicationInfo(); ai.packageName = apk.packageName; ai.sourceDir = apexFile.getPath(); ai.flags = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED; ai.enabled = true; ai.minSdkVersion = apk.minSdkVersion; ai.targetSdkVersion = apk.targetSdkVersion; ai.targetSandboxVersion = PARSE_DEFAULT_TARGET_SANDBOX; ai.setVersionCode(apk.getLongVersionCode()); pi.packageName = apk.packageName; pi.splitNames = new String[]{apk.splitName}; pi.setLongVersionCode(apk.getLongVersionCode()); pi.applicationInfo = ai; pi.coreApp = apk.coreApp; if (collectCerts) { if (apk.signingDetails.hasPastSigningCertificates()) { // Package has included signing certificate rotation information. Return // the oldest cert so that programmatic checks keep working even if unaware // of key rotation. pi.signatures = new Signature[1]; pi.signatures[0] = apk.signingDetails.pastSigningCertificates[0]; } else if (apk.signingDetails.hasSignatures()) { // otherwise keep old behavior int numberOfSigs = apk.signingDetails.signatures.length; pi.signatures = new Signature[numberOfSigs]; System.arraycopy(apk.signingDetails.signatures, 0, pi.signatures, 0, numberOfSigs); } PackageParser pp = new PackageParser(); final Package p = pp.parsePackage(apexFile, flags, false); PackageUserState state = new PackageUserState(); PackageInfo pi = generatePackageInfo(p, EmptyArray.INT, flags, 0, 0, Collections.emptySet(), state); pi.applicationInfo.sourceDir = apexFile.getPath(); pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED; pi.isApex = true; if (apk.signingDetails != SigningDetails.UNKNOWN) { // Collect certificates if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { collectCertificates(p, apexFile, false); if (p.mSigningDetails != SigningDetails.UNKNOWN) { // only return a valid SigningInfo if there is signing information to report pi.signingInfo = new SigningInfo(apk.signingDetails); pi.signingInfo = new SigningInfo(p.mSigningDetails); } else { pi.signingInfo = null; } } pi.isApex = true; return pi; } }
core/tests/coretests/res/raw/com_android_tzdata.apex −11.1 KiB (945 KiB) File changed.No diff preview for this file type. View original file View changed file
core/tests/coretests/src/android/content/pm/PackageParserTest.java +8 −18 Original line number Diff line number Diff line Loading @@ -499,30 +499,20 @@ public class PackageParserTest { public void testApexPackageInfoGeneration() throws Exception { File apexFile = copyRawResourceToFile("com.android.tzdata.apex", R.raw.com_android_tzdata); PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, false); int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, flags); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertTrue(pi.applicationInfo.enabled); assertEquals(28, pi.applicationInfo.targetSdkVersion); assertEquals(1, pi.applicationInfo.longVersionCode); assertEquals(191000070, pi.applicationInfo.longVersionCode); assertNotNull(pi.applicationInfo.metaData); assertEquals(apexFile.getPath(), pi.applicationInfo.sourceDir); assertEquals("Bundle[{com.android.vending.derived.apk.id=1}]", pi.applicationInfo.metaData.toString()); assertEquals("com.google.android.tzdata", pi.packageName); assertTrue(pi.splitNames.length > 0); assertEquals(1, pi.getLongVersionCode()); assertNull(pi.signingInfo); assertNull(pi.signatures); assertTrue(pi.isApex); pi = PackageParser.generatePackageInfoFromApex(apexFile, true); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertTrue(pi.applicationInfo.enabled); assertEquals(28, pi.applicationInfo.targetSdkVersion); assertEquals(1, pi.applicationInfo.longVersionCode); assertEquals("com.google.android.tzdata", pi.packageName); assertTrue(pi.splitNames.length > 0); assertEquals(1, pi.getLongVersionCode()); assertEquals(191000070, pi.getLongVersionCode()); assertNotNull(pi.signingInfo); assertNotNull(pi.signatures); assertTrue(pi.signingInfo.getApkContentsSigners().length > 0); assertTrue(pi.isApex); } Loading
services/core/java/com/android/server/pm/ApexManager.java +3 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.PackageParser.PackageParserException; import android.os.RemoteException; Loading Loading @@ -95,7 +96,8 @@ class ApexManager { } try { list.add(PackageParser.generatePackageInfoFromApex( new File(ai.packagePath), true /* collect certs */)); new File(ai.packagePath), PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES)); } catch (PackageParserException pe) { throw new IllegalStateException("Unable to parse: " + ai, pe); } Loading