Loading core/java/android/content/pm/PackageParser.java +57 −73 Original line number Original line Diff line number Diff line Loading @@ -620,21 +620,6 @@ public class PackageParser { return path.endsWith(APK_FILE_EXTENSION); return path.endsWith(APK_FILE_EXTENSION); } } /** * Generate and return the {@link PackageInfo} for a parsed package. * * @param p the parsed package. * @param flags indicating which optional information is included. */ @UnsupportedAppUsage public static PackageInfo generatePackageInfo(PackageParser.Package p, int gids[], int flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state) { return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, UserHandle.getCallingUserId()); } /** /** * Returns true if the package is installed and not hidden, or if the caller * Returns true if the package is installed and not hidden, or if the caller * explicitly wanted all uninstalled and hidden packages as well. * explicitly wanted all uninstalled and hidden packages as well. Loading @@ -661,8 +646,45 @@ public class PackageParser { return checkUseInstalledOrHidden(0, state, null); return checkUseInstalledOrHidden(0, state, null); } } /** * Generate and return the {@link PackageInfo} for a parsed package. * * @param p the parsed package. * @param flags indicating which optional information is included. */ @UnsupportedAppUsage @UnsupportedAppUsage public static PackageInfo generatePackageInfo(PackageParser.Package p, public static PackageInfo generatePackageInfo(PackageParser.Package p, int[] gids, int flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state) { return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, UserHandle.getCallingUserId()); } @UnsupportedAppUsage public static PackageInfo generatePackageInfo(PackageParser.Package p, int[] gids, int flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId) { return generatePackageInfo(p, null, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, userId); } /** * PackageInfo generator specifically for apex files. * * @param pkg Package to generate info from. Should be derived from an apex. * @param apexInfo Apex info relating to the package. * @return PackageInfo * @throws PackageParserException */ public static PackageInfo generatePackageInfo( PackageParser.Package pkg, ApexInfo apexInfo, int flags) { return generatePackageInfo(pkg, apexInfo, EmptyArray.INT, flags, 0, 0, Collections.emptySet(), new PackageUserState(), UserHandle.getCallingUserId()); } private static PackageInfo generatePackageInfo(PackageParser.Package p, ApexInfo apexInfo, int gids[], int flags, long firstInstallTime, long lastUpdateTime, int gids[], int flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId) { Set<String> grantedPermissions, PackageUserState state, int userId) { if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) { if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) { Loading Loading @@ -809,6 +831,25 @@ public class PackageParser { } } } } } } if (apexInfo != null) { File apexFile = new File(apexInfo.modulePath); pi.applicationInfo.sourceDir = apexFile.getPath(); pi.applicationInfo.publicSourceDir = apexFile.getPath(); if (apexInfo.isFactory) { pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; } else { pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; } if (apexInfo.isActive) { pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED; } else { pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED; } pi.isApex = true; } // deprecated method of getting signing certificates // deprecated method of getting signing certificates if ((flags & PackageManager.GET_SIGNATURES) != 0) { if ((flags & PackageManager.GET_SIGNATURES) != 0) { if (p.mSigningDetails.hasPastSigningCertificates()) { if (p.mSigningDetails.hasPastSigningCertificates()) { Loading Loading @@ -8461,61 +8502,4 @@ public class PackageParser { } } } } // TODO(b/129261524): Clean up API /** * PackageInfo parser specifically for apex files. * NOTE: It will collect certificates * * @param apexInfo * @return PackageInfo * @throws PackageParserException */ public static PackageInfo generatePackageInfoFromApex(ApexInfo apexInfo, int flags) throws PackageParserException { PackageParser pp = new PackageParser(); File apexFile = new File(apexInfo.modulePath); 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.publicSourceDir = apexFile.getPath(); if (apexInfo.isFactory) { pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; } else { pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; } if (apexInfo.isActive) { pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED; } else { pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED; } pi.isApex = true; // Collect certificates if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { collectCertificates(p, apexFile, false); // Keep legacy mechanism for handling signatures. While this is deprecated, it's // still part of the public API and needs to be maintained if (p.mSigningDetails.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] = p.mSigningDetails.pastSigningCertificates[0]; } else if (p.mSigningDetails.hasSignatures()) { // otherwise keep old behavior int numberOfSigs = p.mSigningDetails.signatures.length; pi.signatures = new Signature[numberOfSigs]; System.arraycopy(p.mSigningDetails.signatures, 0, pi.signatures, 0, numberOfSigs); } if (p.mSigningDetails != SigningDetails.UNKNOWN) { // only return a valid SigningInfo if there is signing information to report pi.signingInfo = new SigningInfo(p.mSigningDetails); } else { pi.signingInfo = null; } } return pi; } } } core/tests/coretests/src/android/content/pm/PackageParserTest.java +6 −1 Original line number Original line Diff line number Diff line Loading @@ -520,7 +520,12 @@ public class PackageParserTest { apexInfo.modulePath = apexFile.getPath(); apexInfo.modulePath = apexFile.getPath(); apexInfo.versionCode = 191000070; apexInfo.versionCode = 191000070; int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexInfo, flags); PackageParser pp = new PackageParser(); Package p = pp.parsePackage(apexFile, flags, false); PackageParser.collectCertificates(p, false); PackageInfo pi = PackageParser.generatePackageInfo(p, apexInfo, flags); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertTrue(pi.applicationInfo.enabled); assertTrue(pi.applicationInfo.enabled); assertEquals(28, pi.applicationInfo.targetSdkVersion); assertEquals(28, pi.applicationInfo.targetSdkVersion); Loading services/core/java/com/android/server/pm/ApexManager.java +29 −20 Original line number Original line Diff line number Diff line Loading @@ -282,30 +282,39 @@ abstract class ApexManager { if ((new File(ai.modulePath)).isDirectory()) { if ((new File(ai.modulePath)).isDirectory()) { break; break; } } int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_SIGNATURES; PackageParser.Package pkg; try { try { final PackageInfo pkg = PackageParser.generatePackageInfoFromApex( File apexFile = new File(ai.modulePath); ai, PackageManager.GET_META_DATA PackageParser pp = new PackageParser(); | PackageManager.GET_SIGNING_CERTIFICATES); pkg = pp.parsePackage(apexFile, flags, false); mAllPackagesCache.add(pkg); PackageParser.collectCertificates(pkg, false); } catch (PackageParser.PackageParserException pe) { throw new IllegalStateException("Unable to parse: " + ai, pe); } final PackageInfo packageInfo = PackageParser.generatePackageInfo(pkg, ai, flags); mAllPackagesCache.add(packageInfo); if (ai.isActive) { if (ai.isActive) { if (activePackagesSet.contains(pkg.packageName)) { if (activePackagesSet.contains(packageInfo.packageName)) { throw new IllegalStateException( throw new IllegalStateException( "Two active packages have the same name: " "Two active packages have the same name: " + pkg.packageName); + packageInfo.packageName); } } activePackagesSet.add(pkg.packageName); activePackagesSet.add(packageInfo.packageName); } } if (ai.isFactory) { if (ai.isFactory) { if (factoryPackagesSet.contains(pkg.packageName)) { if (factoryPackagesSet.contains(packageInfo.packageName)) { throw new IllegalStateException( throw new IllegalStateException( "Two factory packages have the same name: " "Two factory packages have the same name: " + pkg.packageName); + packageInfo.packageName); } } factoryPackagesSet.add(pkg.packageName); factoryPackagesSet.add(packageInfo.packageName); } } catch (PackageParser.PackageParserException pe) { throw new IllegalStateException("Unable to parse: " + ai, pe); } } } } } catch (RemoteException re) { } catch (RemoteException re) { Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString()); Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString()); Loading services/core/java/com/android/server/pm/StagingManager.java +13 −9 Original line number Original line Diff line number Diff line Loading @@ -160,25 +160,29 @@ public class StagingManager { final ApexInfoList apexInfoList = mApexManager.submitStagedSession(session.sessionId, final ApexInfoList apexInfoList = mApexManager.submitStagedSession(session.sessionId, childSessionsIds.toArray()); childSessionsIds.toArray()); final List<PackageInfo> result = new ArrayList<>(); final List<PackageInfo> result = new ArrayList<>(); for (ApexInfo newPackage : apexInfoList.apexInfos) { for (ApexInfo apexInfo : apexInfoList.apexInfos) { final PackageInfo pkg; final PackageInfo packageInfo; int flags = PackageManager.GET_META_DATA; PackageParser.Package pkg; try { try { pkg = PackageParser.generatePackageInfoFromApex(newPackage, File apexFile = new File(apexInfo.modulePath); PackageManager.GET_META_DATA); PackageParser pp = new PackageParser(); pkg = pp.parsePackage(apexFile, flags, false); } catch (PackageParserException e) { } catch (PackageParserException e) { throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, "Failed to parse APEX package " + newPackage.modulePath, e); "Failed to parse APEX package " + apexInfo.modulePath, e); } } final PackageInfo activePackage = mApexManager.getPackageInfo(pkg.packageName, packageInfo = PackageParser.generatePackageInfo(pkg, apexInfo, flags); final PackageInfo activePackage = mApexManager.getPackageInfo(packageInfo.packageName, ApexManager.MATCH_ACTIVE_PACKAGE); ApexManager.MATCH_ACTIVE_PACKAGE); if (activePackage == null) { if (activePackage == null) { Slog.w(TAG, "Attempting to install new APEX package " + pkg.packageName); Slog.w(TAG, "Attempting to install new APEX package " + packageInfo.packageName); throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, "It is forbidden to install new APEX packages."); "It is forbidden to install new APEX packages."); } } checkRequiredVersionCode(session, activePackage); checkRequiredVersionCode(session, activePackage); checkDowngrade(session, activePackage, pkg); checkDowngrade(session, activePackage, packageInfo); result.add(pkg); result.add(packageInfo); } } Slog.d(TAG, "Session " + session.sessionId + " has following APEX packages: [" Slog.d(TAG, "Session " + session.sessionId + " has following APEX packages: [" + result.stream().map(p -> p.packageName).collect(Collectors.joining(",")) + "]"); + result.stream().map(p -> p.packageName).collect(Collectors.joining(",")) + "]"); Loading Loading
core/java/android/content/pm/PackageParser.java +57 −73 Original line number Original line Diff line number Diff line Loading @@ -620,21 +620,6 @@ public class PackageParser { return path.endsWith(APK_FILE_EXTENSION); return path.endsWith(APK_FILE_EXTENSION); } } /** * Generate and return the {@link PackageInfo} for a parsed package. * * @param p the parsed package. * @param flags indicating which optional information is included. */ @UnsupportedAppUsage public static PackageInfo generatePackageInfo(PackageParser.Package p, int gids[], int flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state) { return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, UserHandle.getCallingUserId()); } /** /** * Returns true if the package is installed and not hidden, or if the caller * Returns true if the package is installed and not hidden, or if the caller * explicitly wanted all uninstalled and hidden packages as well. * explicitly wanted all uninstalled and hidden packages as well. Loading @@ -661,8 +646,45 @@ public class PackageParser { return checkUseInstalledOrHidden(0, state, null); return checkUseInstalledOrHidden(0, state, null); } } /** * Generate and return the {@link PackageInfo} for a parsed package. * * @param p the parsed package. * @param flags indicating which optional information is included. */ @UnsupportedAppUsage @UnsupportedAppUsage public static PackageInfo generatePackageInfo(PackageParser.Package p, public static PackageInfo generatePackageInfo(PackageParser.Package p, int[] gids, int flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state) { return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, UserHandle.getCallingUserId()); } @UnsupportedAppUsage public static PackageInfo generatePackageInfo(PackageParser.Package p, int[] gids, int flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId) { return generatePackageInfo(p, null, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, userId); } /** * PackageInfo generator specifically for apex files. * * @param pkg Package to generate info from. Should be derived from an apex. * @param apexInfo Apex info relating to the package. * @return PackageInfo * @throws PackageParserException */ public static PackageInfo generatePackageInfo( PackageParser.Package pkg, ApexInfo apexInfo, int flags) { return generatePackageInfo(pkg, apexInfo, EmptyArray.INT, flags, 0, 0, Collections.emptySet(), new PackageUserState(), UserHandle.getCallingUserId()); } private static PackageInfo generatePackageInfo(PackageParser.Package p, ApexInfo apexInfo, int gids[], int flags, long firstInstallTime, long lastUpdateTime, int gids[], int flags, long firstInstallTime, long lastUpdateTime, Set<String> grantedPermissions, PackageUserState state, int userId) { Set<String> grantedPermissions, PackageUserState state, int userId) { if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) { if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) { Loading Loading @@ -809,6 +831,25 @@ public class PackageParser { } } } } } } if (apexInfo != null) { File apexFile = new File(apexInfo.modulePath); pi.applicationInfo.sourceDir = apexFile.getPath(); pi.applicationInfo.publicSourceDir = apexFile.getPath(); if (apexInfo.isFactory) { pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; } else { pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; } if (apexInfo.isActive) { pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED; } else { pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED; } pi.isApex = true; } // deprecated method of getting signing certificates // deprecated method of getting signing certificates if ((flags & PackageManager.GET_SIGNATURES) != 0) { if ((flags & PackageManager.GET_SIGNATURES) != 0) { if (p.mSigningDetails.hasPastSigningCertificates()) { if (p.mSigningDetails.hasPastSigningCertificates()) { Loading Loading @@ -8461,61 +8502,4 @@ public class PackageParser { } } } } // TODO(b/129261524): Clean up API /** * PackageInfo parser specifically for apex files. * NOTE: It will collect certificates * * @param apexInfo * @return PackageInfo * @throws PackageParserException */ public static PackageInfo generatePackageInfoFromApex(ApexInfo apexInfo, int flags) throws PackageParserException { PackageParser pp = new PackageParser(); File apexFile = new File(apexInfo.modulePath); 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.publicSourceDir = apexFile.getPath(); if (apexInfo.isFactory) { pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; } else { pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; } if (apexInfo.isActive) { pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED; } else { pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED; } pi.isApex = true; // Collect certificates if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) { collectCertificates(p, apexFile, false); // Keep legacy mechanism for handling signatures. While this is deprecated, it's // still part of the public API and needs to be maintained if (p.mSigningDetails.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] = p.mSigningDetails.pastSigningCertificates[0]; } else if (p.mSigningDetails.hasSignatures()) { // otherwise keep old behavior int numberOfSigs = p.mSigningDetails.signatures.length; pi.signatures = new Signature[numberOfSigs]; System.arraycopy(p.mSigningDetails.signatures, 0, pi.signatures, 0, numberOfSigs); } if (p.mSigningDetails != SigningDetails.UNKNOWN) { // only return a valid SigningInfo if there is signing information to report pi.signingInfo = new SigningInfo(p.mSigningDetails); } else { pi.signingInfo = null; } } return pi; } } }
core/tests/coretests/src/android/content/pm/PackageParserTest.java +6 −1 Original line number Original line Diff line number Diff line Loading @@ -520,7 +520,12 @@ public class PackageParserTest { apexInfo.modulePath = apexFile.getPath(); apexInfo.modulePath = apexFile.getPath(); apexInfo.versionCode = 191000070; apexInfo.versionCode = 191000070; int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexInfo, flags); PackageParser pp = new PackageParser(); Package p = pp.parsePackage(apexFile, flags, false); PackageParser.collectCertificates(p, false); PackageInfo pi = PackageParser.generatePackageInfo(p, apexInfo, flags); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName); assertTrue(pi.applicationInfo.enabled); assertTrue(pi.applicationInfo.enabled); assertEquals(28, pi.applicationInfo.targetSdkVersion); assertEquals(28, pi.applicationInfo.targetSdkVersion); Loading
services/core/java/com/android/server/pm/ApexManager.java +29 −20 Original line number Original line Diff line number Diff line Loading @@ -282,30 +282,39 @@ abstract class ApexManager { if ((new File(ai.modulePath)).isDirectory()) { if ((new File(ai.modulePath)).isDirectory()) { break; break; } } int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_SIGNATURES; PackageParser.Package pkg; try { try { final PackageInfo pkg = PackageParser.generatePackageInfoFromApex( File apexFile = new File(ai.modulePath); ai, PackageManager.GET_META_DATA PackageParser pp = new PackageParser(); | PackageManager.GET_SIGNING_CERTIFICATES); pkg = pp.parsePackage(apexFile, flags, false); mAllPackagesCache.add(pkg); PackageParser.collectCertificates(pkg, false); } catch (PackageParser.PackageParserException pe) { throw new IllegalStateException("Unable to parse: " + ai, pe); } final PackageInfo packageInfo = PackageParser.generatePackageInfo(pkg, ai, flags); mAllPackagesCache.add(packageInfo); if (ai.isActive) { if (ai.isActive) { if (activePackagesSet.contains(pkg.packageName)) { if (activePackagesSet.contains(packageInfo.packageName)) { throw new IllegalStateException( throw new IllegalStateException( "Two active packages have the same name: " "Two active packages have the same name: " + pkg.packageName); + packageInfo.packageName); } } activePackagesSet.add(pkg.packageName); activePackagesSet.add(packageInfo.packageName); } } if (ai.isFactory) { if (ai.isFactory) { if (factoryPackagesSet.contains(pkg.packageName)) { if (factoryPackagesSet.contains(packageInfo.packageName)) { throw new IllegalStateException( throw new IllegalStateException( "Two factory packages have the same name: " "Two factory packages have the same name: " + pkg.packageName); + packageInfo.packageName); } } factoryPackagesSet.add(pkg.packageName); factoryPackagesSet.add(packageInfo.packageName); } } catch (PackageParser.PackageParserException pe) { throw new IllegalStateException("Unable to parse: " + ai, pe); } } } } } catch (RemoteException re) { } catch (RemoteException re) { Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString()); Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString()); Loading
services/core/java/com/android/server/pm/StagingManager.java +13 −9 Original line number Original line Diff line number Diff line Loading @@ -160,25 +160,29 @@ public class StagingManager { final ApexInfoList apexInfoList = mApexManager.submitStagedSession(session.sessionId, final ApexInfoList apexInfoList = mApexManager.submitStagedSession(session.sessionId, childSessionsIds.toArray()); childSessionsIds.toArray()); final List<PackageInfo> result = new ArrayList<>(); final List<PackageInfo> result = new ArrayList<>(); for (ApexInfo newPackage : apexInfoList.apexInfos) { for (ApexInfo apexInfo : apexInfoList.apexInfos) { final PackageInfo pkg; final PackageInfo packageInfo; int flags = PackageManager.GET_META_DATA; PackageParser.Package pkg; try { try { pkg = PackageParser.generatePackageInfoFromApex(newPackage, File apexFile = new File(apexInfo.modulePath); PackageManager.GET_META_DATA); PackageParser pp = new PackageParser(); pkg = pp.parsePackage(apexFile, flags, false); } catch (PackageParserException e) { } catch (PackageParserException e) { throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, "Failed to parse APEX package " + newPackage.modulePath, e); "Failed to parse APEX package " + apexInfo.modulePath, e); } } final PackageInfo activePackage = mApexManager.getPackageInfo(pkg.packageName, packageInfo = PackageParser.generatePackageInfo(pkg, apexInfo, flags); final PackageInfo activePackage = mApexManager.getPackageInfo(packageInfo.packageName, ApexManager.MATCH_ACTIVE_PACKAGE); ApexManager.MATCH_ACTIVE_PACKAGE); if (activePackage == null) { if (activePackage == null) { Slog.w(TAG, "Attempting to install new APEX package " + pkg.packageName); Slog.w(TAG, "Attempting to install new APEX package " + packageInfo.packageName); throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, "It is forbidden to install new APEX packages."); "It is forbidden to install new APEX packages."); } } checkRequiredVersionCode(session, activePackage); checkRequiredVersionCode(session, activePackage); checkDowngrade(session, activePackage, pkg); checkDowngrade(session, activePackage, packageInfo); result.add(pkg); result.add(packageInfo); } } Slog.d(TAG, "Session " + session.sessionId + " has following APEX packages: [" Slog.d(TAG, "Session " + session.sessionId + " has following APEX packages: [" + result.stream().map(p -> p.packageName).collect(Collectors.joining(",")) + "]"); + result.stream().map(p -> p.packageName).collect(Collectors.joining(",")) + "]"); Loading