Merge "Fix an exception while scanning apex packages" into rvc-dev am: 2aab1a4d49

Change-Id: I2fb57d10566311020ca3b1c95076f371373289c7
This commit is contained in:
Rhed Jao
2020-04-07 09:05:32 +00:00
committed by Automerger Merge Worker
6 changed files with 52 additions and 16 deletions

View File

@@ -1542,6 +1542,14 @@ public abstract class PackageManager {
*/
public static final int INSTALL_FAILED_PROCESS_NOT_DEFINED = -122;
/**
* Installation parse return code: system is in a minimal boot state, and the parser only
* allows the package with {@code coreApp} manifest attribute to be a valid application.
*
* @hide
*/
public static final int INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED = -123;
/** @hide */
@IntDef(flag = true, prefix = { "DELETE_" }, value = {
DELETE_KEEP_DATA,

View File

@@ -22,6 +22,7 @@ import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
import static android.os.Build.VERSION_CODES.DONUT;
import static android.os.Build.VERSION_CODES.O;
@@ -229,7 +230,8 @@ public class ParsingPackageUtils {
final PackageParser.PackageLite lite = ApkLiteParseUtils.parseClusterPackageLite(packageDir,
0);
if (mOnlyCoreApps && !lite.coreApp) {
return input.error("Not a coreApp: " + packageDir);
return input.error(INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED,
"Not a coreApp: " + packageDir);
}
// Build the split dependency tree.
@@ -291,7 +293,8 @@ public class ParsingPackageUtils {
final PackageParser.PackageLite lite = ApkLiteParseUtils.parseMonolithicPackageLite(apkFile,
flags);
if (mOnlyCoreApps && !lite.coreApp) {
return input.error("Not a coreApp: " + apkFile);
return input.error(INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED,
"Not a coreApp: " + apkFile);
}
final SplitAssetLoader assetLoader = new DefaultSplitAssetLoader(lite, flags);

View File

@@ -30,7 +30,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
import android.os.Binder;
import android.os.Environment;
@@ -137,7 +137,8 @@ public abstract class ApexManager {
/**
* Called by package manager service to scan apex package files when device boots up.
*
* @param packageParser The package parser which supports caches.
* @param packageParser The package parser to support apex package parsing and caching parsed
* results.
* @param executorService An executor to support parallel package parsing.
*/
abstract void scanApexPackagesTraced(@NonNull PackageParser2 packageParser,
@@ -505,7 +506,13 @@ public abstract class ApexManager {
}
factoryPackagesSet.add(packageInfo.packageName);
}
} else if (throwable instanceof PackageParser.PackageParserException) {
} else if (throwable instanceof PackageParserException) {
final PackageParserException e = (PackageParserException) throwable;
// Skip parsing non-coreApp apex file if system is in minimal boot state.
if (e.error == PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED) {
Slog.w(TAG, "Scan apex failed, not a coreApp:" + ai.modulePath);
continue;
}
throw new IllegalStateException("Unable to parse: " + ai.modulePath, throwable);
} else {
throw new IllegalStateException("Unexpected exception occurred while parsing "

View File

@@ -82,6 +82,7 @@ import com.android.internal.util.ImageUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import libcore.io.IoUtils;
@@ -105,6 +106,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.function.IntPredicate;
import java.util.function.Supplier;
/** The service responsible for installing packages. */
public class PackageInstallerService extends IPackageInstaller.Stub implements
@@ -194,7 +196,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
};
public PackageInstallerService(Context context, PackageManagerService pm) {
public PackageInstallerService(Context context, PackageManagerService pm,
Supplier<PackageParser2> apexParserSupplier) {
mContext = context;
mPm = pm;
mPermissionManager = LocalServices.getService(PermissionManagerServiceInternal.class);
@@ -213,7 +216,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
mSessionsDir.mkdirs();
mApexManager = ApexManager.getInstance();
mStagingManager = new StagingManager(this, context);
mStagingManager = new StagingManager(this, context, apexParserSupplier);
}
boolean okToSendBroadcasts() {

View File

@@ -417,6 +417,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Keep track of all those APKs everywhere.
@@ -3571,7 +3572,11 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
mInstallerService = new PackageInstallerService(mContext, this);
// Prepare a supplier of package parser for the staging manager to parse apex file
// during the staging installation.
final Supplier<PackageParser2> apexParserSupplier = () -> new PackageParser2(
mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
mInstallerService = new PackageInstallerService(mContext, this, apexParserSupplier);
final Pair<ComponentName, String> instantAppResolverComponent =
getInstantAppResolverLPr();
if (instantAppResolverComponent != null) {

View File

@@ -35,11 +35,11 @@ import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageParser.SigningDetails;
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
import android.content.pm.ParceledListSlice;
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
import android.content.rollback.IRollbackManager;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
@@ -68,8 +68,10 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageHelper;
import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.rollback.WatchdogRollbackLogger;
import java.io.File;
@@ -80,6 +82,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* This class handles staged install sessions, i.e. install sessions that require packages to
@@ -94,6 +97,7 @@ public class StagingManager {
private final PowerManager mPowerManager;
private final Context mContext;
private final PreRebootVerificationHandler mPreRebootVerificationHandler;
private final Supplier<PackageParser2> mPackageParserSupplier;
@GuardedBy("mStagedSessions")
private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>();
@@ -105,9 +109,11 @@ public class StagingManager {
private final List<String> mFailedPackageNames = new ArrayList<>();
private String mNativeFailureReason;
StagingManager(PackageInstallerService pi, Context context) {
StagingManager(PackageInstallerService pi, Context context,
Supplier<PackageParser2> packageParserSupplier) {
mPi = pi;
mContext = context;
mPackageParserSupplier = packageParserSupplier;
mApexManager = ApexManager.getInstance();
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
@@ -223,17 +229,21 @@ public class StagingManager {
final List<String> apexPackageNames = new ArrayList<>();
for (ApexInfo apexInfo : apexInfoList.apexInfos) {
final PackageInfo packageInfo;
int flags = PackageManager.GET_META_DATA;
PackageParser.Package pkg;
try {
final int flags = PackageManager.GET_META_DATA;
try (PackageParser2 packageParser = mPackageParserSupplier.get()) {
File apexFile = new File(apexInfo.modulePath);
PackageParser pp = new PackageParser();
pkg = pp.parsePackage(apexFile, flags, false);
final ParsedPackage parsedPackage = packageParser.parsePackage(
apexFile, flags, false);
packageInfo = PackageInfoWithoutStateUtils.generate(parsedPackage, apexInfo, flags);
if (packageInfo == null) {
throw new PackageManagerException(
SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
"Unable to generate package info: " + apexInfo.modulePath);
}
} catch (PackageParserException e) {
throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
"Failed to parse APEX package " + apexInfo.modulePath, e);
}
packageInfo = PackageParser.generatePackageInfo(pkg, apexInfo, flags);
final PackageInfo activePackage = mApexManager.getPackageInfo(packageInfo.packageName,
ApexManager.MATCH_ACTIVE_PACKAGE);
if (activePackage == null) {