Clean up generatePackageInfoFromApex() API
This changes the API for generatePackageInfoFromApex in PackageParser in response to review suggestions made in ag/6701090. The method is renamed to generatePackageInfo with a PackageParser.Package parameter (as well as an ApexInfo and flags). The implementation is combined with the main generatePackageInfo method. Callers are changed to perform the parsing themselves, including the collection of certificates if necessary. Note: the method signature and implementation had already changed since ag/6701090, so the suggestions from that CL may not apply directly. Bug: 129261524 Test: atest PackageParserTest Test: atest CtsStagedInstallHostTestCases Change-Id: I495539679812110f89d5e3d93f2622ba2dab36c0
This commit is contained in:
@@ -620,21 +620,6 @@ public class PackageParser {
|
||||
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
|
||||
* explicitly wanted all uninstalled and hidden packages as well.
|
||||
@@ -661,8 +646,45 @@ public class PackageParser {
|
||||
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
|
||||
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,
|
||||
Set<String> grantedPermissions, PackageUserState state, int userId) {
|
||||
if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) {
|
||||
@@ -809,8 +831,27 @@ 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
|
||||
if ((flags&PackageManager.GET_SIGNATURES) != 0) {
|
||||
if ((flags & PackageManager.GET_SIGNATURES) != 0) {
|
||||
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.
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,7 +520,12 @@ public class PackageParserTest {
|
||||
apexInfo.modulePath = apexFile.getPath();
|
||||
apexInfo.versionCode = 191000070;
|
||||
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);
|
||||
assertTrue(pi.applicationInfo.enabled);
|
||||
assertEquals(28, pi.applicationInfo.targetSdkVersion);
|
||||
|
||||
@@ -282,30 +282,39 @@ abstract class ApexManager {
|
||||
if ((new File(ai.modulePath)).isDirectory()) {
|
||||
break;
|
||||
}
|
||||
int flags = PackageManager.GET_META_DATA
|
||||
| PackageManager.GET_SIGNING_CERTIFICATES
|
||||
| PackageManager.GET_SIGNATURES;
|
||||
PackageParser.Package pkg;
|
||||
try {
|
||||
final PackageInfo pkg = PackageParser.generatePackageInfoFromApex(
|
||||
ai, PackageManager.GET_META_DATA
|
||||
| PackageManager.GET_SIGNING_CERTIFICATES);
|
||||
mAllPackagesCache.add(pkg);
|
||||
if (ai.isActive) {
|
||||
if (activePackagesSet.contains(pkg.packageName)) {
|
||||
throw new IllegalStateException(
|
||||
"Two active packages have the same name: "
|
||||
+ pkg.packageName);
|
||||
}
|
||||
activePackagesSet.add(pkg.packageName);
|
||||
}
|
||||
if (ai.isFactory) {
|
||||
if (factoryPackagesSet.contains(pkg.packageName)) {
|
||||
throw new IllegalStateException(
|
||||
"Two factory packages have the same name: "
|
||||
+ pkg.packageName);
|
||||
}
|
||||
factoryPackagesSet.add(pkg.packageName);
|
||||
}
|
||||
File apexFile = new File(ai.modulePath);
|
||||
PackageParser pp = new PackageParser();
|
||||
pkg = pp.parsePackage(apexFile, flags, false);
|
||||
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 (activePackagesSet.contains(packageInfo.packageName)) {
|
||||
throw new IllegalStateException(
|
||||
"Two active packages have the same name: "
|
||||
+ packageInfo.packageName);
|
||||
}
|
||||
activePackagesSet.add(packageInfo.packageName);
|
||||
}
|
||||
if (ai.isFactory) {
|
||||
if (factoryPackagesSet.contains(packageInfo.packageName)) {
|
||||
throw new IllegalStateException(
|
||||
"Two factory packages have the same name: "
|
||||
+ packageInfo.packageName);
|
||||
}
|
||||
factoryPackagesSet.add(packageInfo.packageName);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
|
||||
|
||||
@@ -160,25 +160,29 @@ public class StagingManager {
|
||||
final ApexInfoList apexInfoList = mApexManager.submitStagedSession(session.sessionId,
|
||||
childSessionsIds.toArray());
|
||||
final List<PackageInfo> result = new ArrayList<>();
|
||||
for (ApexInfo newPackage : apexInfoList.apexInfos) {
|
||||
final PackageInfo pkg;
|
||||
for (ApexInfo apexInfo : apexInfoList.apexInfos) {
|
||||
final PackageInfo packageInfo;
|
||||
int flags = PackageManager.GET_META_DATA;
|
||||
PackageParser.Package pkg;
|
||||
try {
|
||||
pkg = PackageParser.generatePackageInfoFromApex(newPackage,
|
||||
PackageManager.GET_META_DATA);
|
||||
File apexFile = new File(apexInfo.modulePath);
|
||||
PackageParser pp = new PackageParser();
|
||||
pkg = pp.parsePackage(apexFile, flags, false);
|
||||
} catch (PackageParserException e) {
|
||||
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);
|
||||
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,
|
||||
"It is forbidden to install new APEX packages.");
|
||||
}
|
||||
checkRequiredVersionCode(session, activePackage);
|
||||
checkDowngrade(session, activePackage, pkg);
|
||||
result.add(pkg);
|
||||
checkDowngrade(session, activePackage, packageInfo);
|
||||
result.add(packageInfo);
|
||||
}
|
||||
Slog.d(TAG, "Session " + session.sessionId + " has following APEX packages: ["
|
||||
+ result.stream().map(p -> p.packageName).collect(Collectors.joining(",")) + "]");
|
||||
|
||||
Reference in New Issue
Block a user