summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rhed Jao <rhedjao@google.com> 2020-04-07 08:49:48 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-04-07 08:49:48 +0000
commit2aab1a4d49e72997aa22fe3b17c456b6b803c478 (patch)
tree494a9853ba79ca918612a9af1f707e27384cbdd8
parent1d26c937fd02ed02cb02934e587b5529cb296716 (diff)
parent269616bed2cc6bf91696c10c535cbeae7fb2c969 (diff)
Merge "Fix an exception while scanning apex packages" into rvc-dev
-rw-r--r--core/java/android/content/pm/PackageManager.java8
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackageUtils.java7
-rw-r--r--services/core/java/com/android/server/pm/ApexManager.java13
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java7
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java7
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java26
6 files changed, 52 insertions, 16 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f48d78ac9cc3..9a2e07e9cfbd 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -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,
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index 12328cf32fb3..c94d428f4475 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -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);
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index f06b50a9fdb0..1e4dc7bfe778 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -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 "
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 8ff7ea9d61dd..57908f3a4dac 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -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() {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ab3b2be46988..bc3a0352484b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -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) {
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 0b1b71a08660..8f6bd026a9bd 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -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) {