Merge "Fix an exception while scanning apex packages" into rvc-dev am: 2aab1a4d49
Change-Id: I2fb57d10566311020ca3b1c95076f371373289c7
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user