Merge "Clean up generatePackageInfoFromApex() API"
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