Merge "Clean up generatePackageInfoFromApex() API"

This commit is contained in:
Oli Lan
2019-08-12 10:07:44 +00:00
committed by Android (Google) Code Review
4 changed files with 105 additions and 103 deletions

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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());

View File

@@ -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(",")) + "]");