diff options
8 files changed, 55 insertions, 19 deletions
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 821034aaf204..c673d5846d5d 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -2797,6 +2797,8 @@ public class PackageInstaller { public int developmentInstallFlags = 0; /** {@hide} */ public int unarchiveId = -1; + /** {@hide} */ + public @Nullable String dexoptCompilerFilter = null; private final ArrayMap<String, Integer> mPermissionStates; @@ -2850,6 +2852,7 @@ public class PackageInstaller { applicationEnabledSettingPersistent = source.readBoolean(); developmentInstallFlags = source.readInt(); unarchiveId = source.readInt(); + dexoptCompilerFilter = source.readString(); } /** {@hide} */ @@ -2885,6 +2888,7 @@ public class PackageInstaller { ret.applicationEnabledSettingPersistent = applicationEnabledSettingPersistent; ret.developmentInstallFlags = developmentInstallFlags; ret.unarchiveId = unarchiveId; + ret.dexoptCompilerFilter = dexoptCompilerFilter; return ret; } @@ -3564,6 +3568,11 @@ public class PackageInstaller { } /** @hide */ + public void setDexoptCompilerFilter(@Nullable String dexoptCompilerFilter) { + this.dexoptCompilerFilter = dexoptCompilerFilter; + } + + /** @hide */ @NonNull public ArrayMap<String, Integer> getPermissionStates() { return mPermissionStates; @@ -3622,6 +3631,7 @@ public class PackageInstaller { applicationEnabledSettingPersistent); pw.printHexPair("developmentInstallFlags", developmentInstallFlags); pw.printPair("unarchiveId", unarchiveId); + pw.printPair("dexoptCompilerFilter", dexoptCompilerFilter); pw.println(); } @@ -3667,6 +3677,7 @@ public class PackageInstaller { dest.writeBoolean(applicationEnabledSettingPersistent); dest.writeInt(developmentInstallFlags); dest.writeInt(unarchiveId); + dest.writeString(dexoptCompilerFilter); } public static final Parcelable.Creator<SessionParams> diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java index 209cbb7f591e..e34bdc60cfdb 100644 --- a/services/core/java/com/android/server/pm/DexOptHelper.java +++ b/services/core/java/com/android/server/pm/DexOptHelper.java @@ -728,7 +728,14 @@ public final class DexOptHelper { final int compilationReason = dexManager.getCompilationReasonForInstallScenario( installRequest.getInstallScenario()); - return new DexoptOptions(packageName, compilationReason, dexoptFlags); + final AndroidPackage pkg = ps.getPkg(); + var options = new DexoptOptions(packageName, compilationReason, dexoptFlags); + if (installRequest.getDexoptCompilerFilter() != null) { + options = options.overrideCompilerFilter(installRequest.getDexoptCompilerFilter()); + } else if (pkg != null && pkg.isDebuggable()) { + options = options.overrideCompilerFilter(DexoptParams.COMPILER_FILTER_NOOP); + } + return options; } /** @@ -772,12 +779,12 @@ public final class DexOptHelper { && 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 - && !pkg.isDebuggable() && (!onIncremental) - && dexoptOptions.isCompilationEnabled() && !isApex && performDexOptForRollback; } diff --git a/services/core/java/com/android/server/pm/InstallArgs.java b/services/core/java/com/android/server/pm/InstallArgs.java index 46f9732a88e1..80016151a42e 100644 --- a/services/core/java/com/android/server/pm/InstallArgs.java +++ b/services/core/java/com/android/server/pm/InstallArgs.java @@ -58,6 +58,8 @@ final class InstallArgs { final int mDataLoaderType; final int mPackageSource; final boolean mApplicationEnabledSettingPersistent; + @Nullable + final String mDexoptCompilerFilter; // The list of instruction sets supported by this app. This is currently // only used during the rmdex() phase to clean up resources. We can get rid of this @@ -73,7 +75,7 @@ final class InstallArgs { int autoRevokePermissionsMode, String traceMethod, int traceCookie, SigningDetails signingDetails, int installReason, int installScenario, boolean forceQueryableOverride, int dataLoaderType, int packageSource, - boolean applicationEnabledSettingPersistent) { + boolean applicationEnabledSettingPersistent, String dexoptCompilerFilter) { mOriginInfo = originInfo; mMoveInfo = moveInfo; mInstallFlags = installFlags; @@ -96,5 +98,6 @@ final class InstallArgs { mDataLoaderType = dataLoaderType; mPackageSource = packageSource; mApplicationEnabledSettingPersistent = applicationEnabledSettingPersistent; + mDexoptCompilerFilter = dexoptCompilerFilter; } } diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java index 8f51e3696108..dd2583a0db1d 100644 --- a/services/core/java/com/android/server/pm/InstallRequest.java +++ b/services/core/java/com/android/server/pm/InstallRequest.java @@ -174,13 +174,13 @@ final class InstallRequest { mUserId = params.getUser().getIdentifier(); mInstallArgs = new InstallArgs(params.mOriginInfo, params.mMoveInfo, params.mObserver, params.mInstallFlags, params.mDevelopmentInstallFlags, params.mInstallSource, - params.mVolumeUuid, params.getUser(), null /*instructionSets*/, + params.mVolumeUuid, params.getUser(), null /*instructionSets*/, params.mPackageAbiOverride, params.mPermissionStates, params.mAllowlistedRestrictedPermissions, params.mAutoRevokePermissionsMode, params.mTraceMethod, params.mTraceCookie, params.mSigningDetails, params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride, params.mDataLoaderType, params.mPackageSource, - params.mApplicationEnabledSettingPersistent); + params.mApplicationEnabledSettingPersistent, params.mDexoptCompilerFilter); mPackageLite = params.mPackageLite; mPackageMetrics = new PackageMetrics(this); mIsInstallInherit = params.mIsInherit; @@ -709,6 +709,11 @@ final class InstallRequest { return mWarnings; } + @Nullable + public String getDexoptCompilerFilter() { + return mInstallArgs != null ? mInstallArgs.mDexoptCompilerFilter : null; + } + public void setScanFlags(int scanFlags) { mScanFlags = scanFlags; } diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java index d3a18f9fe75a..ccc117566989 100644 --- a/services/core/java/com/android/server/pm/InstallingSession.java +++ b/services/core/java/com/android/server/pm/InstallingSession.java @@ -102,6 +102,7 @@ class InstallingSession { @Nullable final DomainSet mPreVerifiedDomains; final boolean mHasAppMetadataFile; + @Nullable final String mDexoptCompilerFilter; // For move install InstallingSession(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer, @@ -136,6 +137,7 @@ class InstallingSession { mApplicationEnabledSettingPersistent = false; mPreVerifiedDomains = null; mHasAppMetadataFile = false; + mDexoptCompilerFilter = null; } InstallingSession(int sessionId, File stagedDir, IPackageInstallObserver2 observer, @@ -172,6 +174,7 @@ class InstallingSession { mApplicationEnabledSettingPersistent = sessionParams.applicationEnabledSettingPersistent; mPreVerifiedDomains = preVerifiedDomains; mHasAppMetadataFile = hasAppMetadatafile; + mDexoptCompilerFilter = sessionParams.dexoptCompilerFilter; } @Override diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java index e2ddba5188fa..819a75c8c128 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java @@ -18,7 +18,7 @@ package com.android.server.pm; import android.os.SystemProperties; -import com.android.server.pm.dex.DexoptOptions; +import com.android.server.art.model.DexoptParams; import dalvik.system.DexFile; @@ -71,7 +71,7 @@ public class PackageManagerServiceCompilerMapping { private static String getAndCheckValidity(int reason) { String sysPropValue = SystemProperties.get(getSystemPropertyName(reason)); if (sysPropValue == null || sysPropValue.isEmpty() - || !(sysPropValue.equals(DexoptOptions.COMPILER_FILTER_NOOP) + || !(sysPropValue.equals(DexoptParams.COMPILER_FILTER_NOOP) || DexFile.isValidCompilerFilter(sysPropValue))) { throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid " + "(reason " + REASON_STRINGS[reason] + ")"); diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index a8766163297b..7a53fe78c1bf 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -121,6 +121,8 @@ import com.android.server.LocalManagerRegistry; import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.android.server.art.ArtManagerLocal; +import com.android.server.art.ReasonMapping; +import com.android.server.art.model.DexoptParams; import com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.pm.permission.PermissionAllowlist; @@ -3589,6 +3591,14 @@ class PackageManagerShellCommand extends ShellCommand { case "--package-source": sessionParams.setPackageSource(Integer.parseInt(getNextArg())); break; + case "--dexopt-compiler-filter": + sessionParams.dexoptCompilerFilter = getNextArgRequired(); + // An early check that throws IllegalArgumentException if the compiler filter is + // invalid. + new DexoptParams.Builder(ReasonMapping.REASON_INSTALL) + .setCompilerFilter(sessionParams.dexoptCompilerFilter) + .build(); + break; default: throw new IllegalArgumentException("Unknown option " + opt); } @@ -4735,6 +4745,7 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]"); pw.println(" [--apex] [--non-staged] [--force-non-staged]"); pw.println(" [--staged-ready-timeout TIMEOUT] [--ignore-dexopt-profile]"); + pw.println(" [--dexopt-compiler-filter FILTER]"); pw.println(" [PATH [SPLIT...]|-]"); pw.println(" Install an application. Must provide the apk data to install, either as"); pw.println(" file path(s) or '-' to read from stdin. Options are:"); @@ -4781,13 +4792,19 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" milliseconds for pre-reboot verification to complete when"); pw.println(" performing staged install. This flag is used to alter the waiting"); pw.println(" time. You can skip the waiting time by specifying a TIMEOUT of '0'"); - pw.println(" --ignore-dexopt-profile: If set, all profiles are ignored by dexopt"); + pw.println(" --ignore-dexopt-profile: if set, all profiles are ignored by dexopt"); pw.println(" during the installation, including the profile in the DM file and"); pw.println(" the profile embedded in the APK file. If an invalid profile is"); pw.println(" provided during installation, no warning will be reported by `adb"); pw.println(" install`."); pw.println(" This option does not affect later dexopt operations (e.g.,"); pw.println(" background dexopt and manual `pm compile` invocations)."); + pw.println(" --dexopt-compiler-filter: the target compiler filter for dexopt during"); + pw.println(" the installation. The filter actually used may be different."); + pw.println(" Valid values: one of the values documented in"); + pw.println(" https://source.android.com/docs/core/runtime/configure" + + "#compiler_filters"); + pw.println(" or 'skip'"); pw.println(""); pw.println(" install-existing [--user USER_ID|all|current]"); pw.println(" [--instant] [--full] [--wait] [--restrict-permissions] PACKAGE"); diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java index fcdc0080811b..8cf248d9b19b 100644 --- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java +++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java @@ -73,12 +73,6 @@ public final class DexoptOptions { // or device setup and should be scheduled appropriately. public static final int DEXOPT_FOR_RESTORE = 1 << 11; // TODO(b/135202722): remove - /** - * A value indicating that dexopt shouldn't be run. This string is only used when loading - * filters from the `pm.dexopt.install*` properties and is not propagated to dex2oat. - */ - public static final String COMPILER_FILTER_NOOP = "skip"; - // The name of package to optimize. private final String mPackageName; @@ -186,10 +180,6 @@ public final class DexoptOptions { return mCompilationReason; } - public boolean isCompilationEnabled() { - return !mCompilerFilter.equals(COMPILER_FILTER_NOOP); - } - /** * Creates a new set of DexoptOptions which are the same with the exception of the compiler * filter (set to the given value). |