summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/pm/DexOptHelper.java141
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java4
2 files changed, 54 insertions, 91 deletions
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index 764a22c3b94d..1fc0c66c5e13 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -712,11 +712,9 @@ public final class DexOptHelper {
}
}
- /**
- * Returns DexoptOptions by the given InstallRequest.
- */
- static DexoptOptions getDexoptOptionsByInstallRequest(InstallRequest installRequest,
- DexManager dexManager) {
+ /** Returns DexoptOptions by the given InstallRequest. */
+ private static DexoptOptions getDexoptOptionsByInstallRequest(
+ InstallRequest installRequest, DexManager dexManager) {
final PackageSetting ps = installRequest.getScannedPackageSetting();
final String packageName = ps.getPackageName();
final boolean isBackupOrRestore =
@@ -734,80 +732,38 @@ public final class DexOptHelper {
var options = new DexoptOptions(packageName, compilationReason, dexoptFlags);
if (installRequest.getDexoptCompilerFilter() != null) {
options = options.overrideCompilerFilter(installRequest.getDexoptCompilerFilter());
- } else if (pkg != null && pkg.isDebuggable()) {
+ } else if (shouldSkipDexopt(installRequest)) {
options = options.overrideCompilerFilter(DexoptParams.COMPILER_FILTER_NOOP);
}
return options;
}
- /**
- * Perform dexopt if needed for the installation
- */
- static void performDexoptIfNeeded(InstallRequest installRequest, DexManager dexManager,
- Context context, PackageManagerTracedLock.RawLock installLock) {
-
- // Construct the DexoptOptions early to see if we should skip running dexopt.
- //
- // Do not run PackageDexOptimizer through the local performDexOpt
- // method because `pkg` may not be in `mPackages` yet.
- //
- // Also, don't fail application installs if the dexopt step fails.
- DexoptOptions dexoptOptions = getDexoptOptionsByInstallRequest(installRequest, dexManager);
- // Check whether we need to dexopt the app.
- //
- // NOTE: it is IMPORTANT to call dexopt:
- // - after doRename which will sync the package data from AndroidPackage and
- // its corresponding ApplicationInfo.
- // - after installNewPackageLIF or replacePackageLIF which will update result with the
- // uid of the application (pkg.applicationInfo.uid).
- // This update happens in place!
- //
- // We only need to dexopt if the package meets ALL of the following conditions:
- // 1) it is not an instant app or if it is then dexopt is enabled via gservices.
- // 2) it is not debuggable.
- // 3) it is not on Incremental File System.
- //
- // Note that we do not dexopt instant apps by default. dexopt can take some time to
- // complete, so we skip this step during installation. Instead, we'll take extra time
- // the first time the instant app starts. It's preferred to do it this way to provide
- // continuous progress to the useur instead of mysteriously blocking somewhere in the
- // middle of running an instant app. The default behaviour can be overridden
- // via gservices.
- //
- // Furthermore, dexopt may be skipped, depending on the install scenario and current
- // state of the device.
- //
- // TODO(b/174695087): instantApp and onIncremental should be removed and their install
- // path moved to SCENARIO_FAST.
-
- final boolean performDexopt = DexOptHelper.shouldPerformDexopt(installRequest,
- dexoptOptions, context);
- if (performDexopt) {
- // dexopt can take long, and ArtService doesn't require installd, so we release
- // the lock here and re-acquire the lock after dexopt is finished.
+ /** Perform dexopt if needed for the installation */
+ static void performDexoptIfNeeded(
+ InstallRequest installRequest,
+ DexManager dexManager,
+ PackageManagerTracedLock.RawLock installLock) {
+ if (!shouldCallArtService(installRequest)) {
+ return;
+ }
+
+ // dexopt can take long, and ArtService doesn't require installd, so we release the lock
+ // here and re-acquire the lock after dexopt is finished.
+ if (installLock != null) {
+ installLock.unlock();
+ }
+ try {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
+ DexoptOptions dexoptOptions =
+ getDexoptOptionsByInstallRequest(installRequest, dexManager);
+ // Don't fail application installs if the dexopt step fails.
+ DexoptResult dexOptResult =
+ DexOptHelper.dexoptPackageUsingArtService(installRequest, dexoptOptions);
+ installRequest.onDexoptFinished(dexOptResult);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
if (installLock != null) {
- installLock.unlock();
- }
- try {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
-
- // This mirrors logic from commitReconciledScanResultLocked, where the library
- // files needed for dexopt are assigned.
- PackageSetting realPkgSetting = installRequest.getRealPackageSetting();
- // Unfortunately, the updated system app flag is only tracked on this
- // PackageSetting
- boolean isUpdatedSystemApp =
- installRequest.getScannedPackageSetting().isUpdatedSystemApp();
- realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
-
- DexoptResult dexOptResult = DexOptHelper.dexoptPackageUsingArtService(
- installRequest, dexoptOptions);
- installRequest.onDexoptFinished(dexOptResult);
- } finally {
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- if (installLock != null) {
- installLock.lock();
- }
+ installLock.lock();
}
}
}
@@ -838,29 +794,36 @@ public final class DexOptHelper {
}
}
+ private static boolean shouldSkipDexopt(InstallRequest installRequest) {
+ PackageSetting ps = installRequest.getScannedPackageSetting();
+ AndroidPackage pkg = ps.getPkg();
+ return pkg == null || pkg.isDebuggable();
+ }
+
/**
- * Returns whether to perform dexopt by the given InstallRequest.
+ * Returns whether to call ART Service to perform dexopt for the given InstallRequest. Note that
+ * ART Service may still skip dexopt, depending on the specified compiler filter, compilation
+ * reason, and other conditions.
*/
- static boolean shouldPerformDexopt(InstallRequest installRequest, DexoptOptions dexoptOptions,
- Context context) {
+ private static boolean shouldCallArtService(InstallRequest installRequest) {
final boolean isApex = ((installRequest.getScanFlags() & SCAN_AS_APEX) != 0);
+ // Historically, we did not dexopt instant apps, and we have no plan to do so in the
+ // future, so there is no need to call into ART Service.
final boolean instantApp = ((installRequest.getScanFlags() & SCAN_AS_INSTANT_APP) != 0);
final PackageSetting ps = installRequest.getScannedPackageSetting();
final AndroidPackage pkg = ps.getPkg();
final boolean onIncremental = isIncrementalPath(ps.getPathString());
- final boolean performDexOptForRollback = Flags.recoverabilityDetection()
- ? !(installRequest.isRollback()
- && installRequest.getInstallSource().mInitiatingPackageName.equals("android"))
- : true;
-
- // Don't skip the dexopt call if the compiler filter is "skip". Instead, call dexopt with
- // the "skip" filter so that ART Service gets notified and skips dexopt itself.
- return (!instantApp || Global.getInt(context.getContentResolver(),
- Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
- && pkg != null
- && (!onIncremental)
- && !isApex
- && performDexOptForRollback;
+ final boolean performDexOptForRollback =
+ !(installRequest.isRollback()
+ && installRequest
+ .getInstallSource()
+ .mInitiatingPackageName
+ .equals("android"));
+
+ // THINK TWICE when you add a new condition here. You probably want to add a condition to
+ // `shouldSkipDexopt` instead. In that way, ART Service will be called with the "skip"
+ // compiler filter and it will have the chance to decide whether to skip dexopt.
+ return !instantApp && pkg != null && !onIncremental && !isApex && performDexOptForRollback;
}
private static class StagedApexObserver extends IStagedApexObserver.Stub {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index d4efb5c2951e..1d95c770ab91 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -2638,8 +2638,8 @@ final class InstallPackageHelper {
pkg.getBaseApkPath(), pkg.getSplitCodePaths());
}
- DexOptHelper.performDexoptIfNeeded(installRequest, mDexManager, mContext,
- mPm.mInstallLock.getRawLock());
+ DexOptHelper.performDexoptIfNeeded(
+ installRequest, mDexManager, mPm.mInstallLock.getRawLock());
}
PackageManagerServiceUtils.waitForNativeBinariesExtractionForIncremental(
incrementalStorages);