Merge "Fix an exception while scanning apex packages" into rvc-dev am: 2aab1a4d49 am: c74e158db3
Change-Id: I97b8cd8071348d40531373b2a0c1a77164eb5594
This commit is contained in:
@@ -1542,6 +1542,14 @@ public abstract class PackageManager {
|
|||||||
*/
|
*/
|
||||||
public static final int INSTALL_FAILED_PROCESS_NOT_DEFINED = -122;
|
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 */
|
/** @hide */
|
||||||
@IntDef(flag = true, prefix = { "DELETE_" }, value = {
|
@IntDef(flag = true, prefix = { "DELETE_" }, value = {
|
||||||
DELETE_KEEP_DATA,
|
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_BAD_MANIFEST;
|
||||||
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
|
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_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.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
|
||||||
import static android.os.Build.VERSION_CODES.DONUT;
|
import static android.os.Build.VERSION_CODES.DONUT;
|
||||||
import static android.os.Build.VERSION_CODES.O;
|
import static android.os.Build.VERSION_CODES.O;
|
||||||
@@ -229,7 +230,8 @@ public class ParsingPackageUtils {
|
|||||||
final PackageParser.PackageLite lite = ApkLiteParseUtils.parseClusterPackageLite(packageDir,
|
final PackageParser.PackageLite lite = ApkLiteParseUtils.parseClusterPackageLite(packageDir,
|
||||||
0);
|
0);
|
||||||
if (mOnlyCoreApps && !lite.coreApp) {
|
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.
|
// Build the split dependency tree.
|
||||||
@@ -291,7 +293,8 @@ public class ParsingPackageUtils {
|
|||||||
final PackageParser.PackageLite lite = ApkLiteParseUtils.parseMonolithicPackageLite(apkFile,
|
final PackageParser.PackageLite lite = ApkLiteParseUtils.parseMonolithicPackageLite(apkFile,
|
||||||
flags);
|
flags);
|
||||||
if (mOnlyCoreApps && !lite.coreApp) {
|
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);
|
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.PackageInfo;
|
||||||
import android.content.pm.PackageInstaller;
|
import android.content.pm.PackageInstaller;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageParser;
|
import android.content.pm.PackageParser.PackageParserException;
|
||||||
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
|
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Environment;
|
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.
|
* 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.
|
* @param executorService An executor to support parallel package parsing.
|
||||||
*/
|
*/
|
||||||
abstract void scanApexPackagesTraced(@NonNull PackageParser2 packageParser,
|
abstract void scanApexPackagesTraced(@NonNull PackageParser2 packageParser,
|
||||||
@@ -505,7 +506,13 @@ public abstract class ApexManager {
|
|||||||
}
|
}
|
||||||
factoryPackagesSet.add(packageInfo.packageName);
|
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);
|
throw new IllegalStateException("Unable to parse: " + ai.modulePath, throwable);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Unexpected exception occurred while parsing "
|
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.internal.util.IndentingPrintWriter;
|
||||||
import com.android.server.IoThread;
|
import com.android.server.IoThread;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
|
import com.android.server.pm.parsing.PackageParser2;
|
||||||
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
import com.android.server.pm.permission.PermissionManagerServiceInternal;
|
||||||
|
|
||||||
import libcore.io.IoUtils;
|
import libcore.io.IoUtils;
|
||||||
@@ -105,6 +106,7 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.function.IntPredicate;
|
import java.util.function.IntPredicate;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/** The service responsible for installing packages. */
|
/** The service responsible for installing packages. */
|
||||||
public class PackageInstallerService extends IPackageInstaller.Stub implements
|
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;
|
mContext = context;
|
||||||
mPm = pm;
|
mPm = pm;
|
||||||
mPermissionManager = LocalServices.getService(PermissionManagerServiceInternal.class);
|
mPermissionManager = LocalServices.getService(PermissionManagerServiceInternal.class);
|
||||||
@@ -213,7 +216,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
|||||||
mSessionsDir.mkdirs();
|
mSessionsDir.mkdirs();
|
||||||
|
|
||||||
mApexManager = ApexManager.getInstance();
|
mApexManager = ApexManager.getInstance();
|
||||||
mStagingManager = new StagingManager(this, context);
|
mStagingManager = new StagingManager(this, context, apexParserSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean okToSendBroadcasts() {
|
boolean okToSendBroadcasts() {
|
||||||
|
|||||||
@@ -417,6 +417,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of all those APKs everywhere.
|
* 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 =
|
final Pair<ComponentName, String> instantAppResolverComponent =
|
||||||
getInstantAppResolverLPr();
|
getInstantAppResolverLPr();
|
||||||
if (instantAppResolverComponent != null) {
|
if (instantAppResolverComponent != null) {
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ import android.content.pm.PackageInstaller;
|
|||||||
import android.content.pm.PackageInstaller.SessionInfo;
|
import android.content.pm.PackageInstaller.SessionInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManagerInternal;
|
import android.content.pm.PackageManagerInternal;
|
||||||
import android.content.pm.PackageParser;
|
|
||||||
import android.content.pm.PackageParser.PackageParserException;
|
import android.content.pm.PackageParser.PackageParserException;
|
||||||
import android.content.pm.PackageParser.SigningDetails;
|
import android.content.pm.PackageParser.SigningDetails;
|
||||||
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
|
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
|
||||||
import android.content.pm.ParceledListSlice;
|
import android.content.pm.ParceledListSlice;
|
||||||
|
import android.content.pm.parsing.PackageInfoWithoutStateUtils;
|
||||||
import android.content.rollback.IRollbackManager;
|
import android.content.rollback.IRollbackManager;
|
||||||
import android.content.rollback.RollbackInfo;
|
import android.content.rollback.RollbackInfo;
|
||||||
import android.content.rollback.RollbackManager;
|
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.content.PackageHelper;
|
||||||
import com.android.internal.os.BackgroundThread;
|
import com.android.internal.os.BackgroundThread;
|
||||||
import com.android.server.LocalServices;
|
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.AndroidPackage;
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
|
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
|
||||||
|
import com.android.server.pm.parsing.pkg.ParsedPackage;
|
||||||
import com.android.server.rollback.WatchdogRollbackLogger;
|
import com.android.server.rollback.WatchdogRollbackLogger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -80,6 +82,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles staged install sessions, i.e. install sessions that require packages to
|
* 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 PowerManager mPowerManager;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final PreRebootVerificationHandler mPreRebootVerificationHandler;
|
private final PreRebootVerificationHandler mPreRebootVerificationHandler;
|
||||||
|
private final Supplier<PackageParser2> mPackageParserSupplier;
|
||||||
|
|
||||||
@GuardedBy("mStagedSessions")
|
@GuardedBy("mStagedSessions")
|
||||||
private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>();
|
private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>();
|
||||||
@@ -105,9 +109,11 @@ public class StagingManager {
|
|||||||
private final List<String> mFailedPackageNames = new ArrayList<>();
|
private final List<String> mFailedPackageNames = new ArrayList<>();
|
||||||
private String mNativeFailureReason;
|
private String mNativeFailureReason;
|
||||||
|
|
||||||
StagingManager(PackageInstallerService pi, Context context) {
|
StagingManager(PackageInstallerService pi, Context context,
|
||||||
|
Supplier<PackageParser2> packageParserSupplier) {
|
||||||
mPi = pi;
|
mPi = pi;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mPackageParserSupplier = packageParserSupplier;
|
||||||
|
|
||||||
mApexManager = ApexManager.getInstance();
|
mApexManager = ApexManager.getInstance();
|
||||||
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||||
@@ -223,17 +229,21 @@ public class StagingManager {
|
|||||||
final List<String> apexPackageNames = new ArrayList<>();
|
final List<String> apexPackageNames = new ArrayList<>();
|
||||||
for (ApexInfo apexInfo : apexInfoList.apexInfos) {
|
for (ApexInfo apexInfo : apexInfoList.apexInfos) {
|
||||||
final PackageInfo packageInfo;
|
final PackageInfo packageInfo;
|
||||||
int flags = PackageManager.GET_META_DATA;
|
final int flags = PackageManager.GET_META_DATA;
|
||||||
PackageParser.Package pkg;
|
try (PackageParser2 packageParser = mPackageParserSupplier.get()) {
|
||||||
try {
|
|
||||||
File apexFile = new File(apexInfo.modulePath);
|
File apexFile = new File(apexInfo.modulePath);
|
||||||
PackageParser pp = new PackageParser();
|
final ParsedPackage parsedPackage = packageParser.parsePackage(
|
||||||
pkg = pp.parsePackage(apexFile, flags, false);
|
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) {
|
} catch (PackageParserException e) {
|
||||||
throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
|
throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
|
||||||
"Failed to parse APEX package " + apexInfo.modulePath, e);
|
"Failed to parse APEX package " + apexInfo.modulePath, e);
|
||||||
}
|
}
|
||||||
packageInfo = PackageParser.generatePackageInfo(pkg, apexInfo, flags);
|
|
||||||
final PackageInfo activePackage = mApexManager.getPackageInfo(packageInfo.packageName,
|
final PackageInfo activePackage = mApexManager.getPackageInfo(packageInfo.packageName,
|
||||||
ApexManager.MATCH_ACTIVE_PACKAGE);
|
ApexManager.MATCH_ACTIVE_PACKAGE);
|
||||||
if (activePackage == null) {
|
if (activePackage == null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user