Expose `optimizePackage` and fix API lint errors.
Changes:
1. Rename `OptimizeOptions` to `OptimizeParams` (enforced by
https://cs.android.com/android/platform/superproject/+/master:tools/metalava/src/main/java/com/android/tools/metalava/ApiLint.kt;l=2405;drc=26ec88f1d22ddd33c30aec46b1a5a50339e3c159)
2. Change the backing type of `PriorityClass` from `byte` to `int`.
3. Duplicate the keys of `PriorityClass` as `PriorityClassApi` to be
exposed as API.
4. Use a bit field `OptimizeParams.mFlags` instead of booleans and
change flag handling.
Bug: 229268202
Test: m update-api
Ignore-AOSP-First: ART Services
Change-Id: I12e497c46ec68f347b76b34920ba2f7405263aa9
diff --git a/artd/binder/com/android/server/art/PriorityClass.aidl b/artd/binder/com/android/server/art/PriorityClass.aidl
index 38adfc7..abea3f3 100644
--- a/artd/binder/com/android/server/art/PriorityClass.aidl
+++ b/artd/binder/com/android/server/art/PriorityClass.aidl
@@ -17,22 +17,14 @@
package com.android.server.art;
/**
- * Indicates the priority of an operation. The value affects the resource usage and the process
- * priority. A higher value may result in faster execution but may consume more resources and
- * compete for resources with other processes.
+ * Keep in sync with {@link ArtFlags.PriorityClassApi}.
*
* @hide
*/
+@Backing(type="int")
enum PriorityClass {
- /** Indicates that the operation blocks boot. */
BOOT = 100,
- /**
- * Indicates that a human is waiting on the result and the operation is more latency sensitive
- * than usual.
- */
INTERACTIVE_FAST = 80,
- /** Indicates that a human is waiting on the result. */
INTERACTIVE = 60,
- /** Indicates that the operation runs in background. */
BACKGROUND = 40,
}
diff --git a/libartservice/service/api/system-server-current.txt b/libartservice/service/api/system-server-current.txt
index 1e8711b..ad988c2 100644
--- a/libartservice/service/api/system-server-current.txt
+++ b/libartservice/service/api/system-server-current.txt
@@ -9,6 +9,7 @@
method @NonNull public com.android.server.art.model.OptimizationStatus getOptimizationStatus(@NonNull com.android.server.pm.snapshot.PackageDataSnapshot, @NonNull String);
method @NonNull public com.android.server.art.model.OptimizationStatus getOptimizationStatus(@NonNull com.android.server.pm.snapshot.PackageDataSnapshot, @NonNull String, int);
method public int handleShellCommand(@NonNull android.os.Binder, @NonNull android.os.ParcelFileDescriptor, @NonNull android.os.ParcelFileDescriptor, @NonNull android.os.ParcelFileDescriptor, @NonNull String[]);
+ method @NonNull public com.android.server.art.model.OptimizeResult optimizePackage(@NonNull com.android.server.pm.snapshot.PackageDataSnapshot, @NonNull String, @NonNull com.android.server.art.model.OptimizeParams);
}
}
@@ -18,8 +19,16 @@
public class ArtFlags {
method public static int defaultDeleteFlags();
method public static int defaultGetStatusFlags();
+ method public static int defaultOptimizeFlags();
+ field public static final int FLAG_FORCE = 16; // 0x10
field public static final int FLAG_FOR_PRIMARY_DEX = 1; // 0x1
field public static final int FLAG_FOR_SECONDARY_DEX = 2; // 0x2
+ field public static final int FLAG_SHOULD_DOWNGRADE = 8; // 0x8
+ field public static final int FLAG_SHOULD_INCLUDE_DEPENDENCIES = 4; // 0x4
+ field public static final int PRIORITY_BACKGROUND = 40; // 0x28
+ field public static final int PRIORITY_BOOT = 100; // 0x64
+ field public static final int PRIORITY_INTERACTIVE = 60; // 0x3c
+ field public static final int PRIORITY_INTERACTIVE_FAST = 80; // 0x50
}
public class DeleteResult {
@@ -38,5 +47,44 @@
method @NonNull public String getLocationDebugString();
}
+ public class OptimizeParams {
+ method @NonNull public String getCompilerFilter();
+ method public int getFlags();
+ method public int getPriorityClass();
+ method @NonNull public String getReason();
+ field public static final String COMPILER_FILTER_NOOP = "skip";
+ }
+
+ public static final class OptimizeParams.Builder {
+ ctor public OptimizeParams.Builder(@NonNull String);
+ ctor public OptimizeParams.Builder(@NonNull String, int);
+ method @NonNull public com.android.server.art.model.OptimizeParams build();
+ method @NonNull public com.android.server.art.model.OptimizeParams.Builder setCompilerFilter(@NonNull String);
+ method @NonNull public com.android.server.art.model.OptimizeParams.Builder setFlags(int);
+ method @NonNull public com.android.server.art.model.OptimizeParams.Builder setFlags(int, int);
+ method @NonNull public com.android.server.art.model.OptimizeParams.Builder setPriorityClass(int);
+ method @NonNull public com.android.server.art.model.OptimizeParams.Builder setReason(@NonNull String);
+ }
+
+ public class OptimizeResult {
+ ctor public OptimizeResult(@NonNull String, @NonNull String, @NonNull String, @NonNull java.util.List<com.android.server.art.model.OptimizeResult.DexFileOptimizeResult>);
+ method @NonNull public java.util.List<com.android.server.art.model.OptimizeResult.DexFileOptimizeResult> getDexFileOptimizeResults();
+ method public int getFinalStatus();
+ method @NonNull public String getPackageName();
+ method @NonNull public String getReason();
+ method @NonNull public String getRequestedCompilerFilter();
+ field public static final int OPTIMIZE_CANCELLED = 40; // 0x28
+ field public static final int OPTIMIZE_FAILED = 30; // 0x1e
+ field public static final int OPTIMIZE_PERFORMED = 20; // 0x14
+ field public static final int OPTIMIZE_SKIPPED = 10; // 0xa
+ }
+
+ public static class OptimizeResult.DexFileOptimizeResult {
+ method @NonNull public String getActualCompilerFilter();
+ method @NonNull public String getDexFile();
+ method @NonNull public String getInstructionSet();
+ method public int getStatus();
+ }
+
}
diff --git a/libartservice/service/java/com/android/server/art/ArtManagerLocal.java b/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
index 594b89e..1f47afb 100644
--- a/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
+++ b/libartservice/service/java/com/android/server/art/ArtManagerLocal.java
@@ -37,7 +37,7 @@
import com.android.server.art.model.ArtFlags;
import com.android.server.art.model.DeleteResult;
import com.android.server.art.model.OptimizationStatus;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.OptimizeParams;
import com.android.server.art.model.OptimizeResult;
import com.android.server.art.wrapper.AndroidPackageApi;
import com.android.server.art.wrapper.PackageManagerLocal;
@@ -105,6 +105,8 @@
/**
* Deletes optimized artifacts of a package.
*
+ * Uses the default flags ({@link ArtFlags#defaultDeleteFlags()}).
+ *
* @throws IllegalArgumentException if the package is not found or the flags are illegal
* @throws IllegalStateException if an internal error occurs
*/
@@ -162,6 +164,8 @@
/**
* Returns the optimization status of a package.
*
+ * Uses the default flags ({@link ArtFlags#defaultGetStatusFlags()}).
+ *
* @throws IllegalArgumentException if the package is not found or the flags are illegal
* @throws IllegalStateException if an internal error occurs
*/
@@ -224,11 +228,11 @@
}
}
- /** @hide */
@NonNull
public OptimizeResult optimizePackage(@NonNull PackageDataSnapshot snapshot,
- @NonNull String packageName, @NonNull OptimizeOptions options) {
- if (!options.isForPrimaryDex() && !options.isForSecondaryDex()) {
+ @NonNull String packageName, @NonNull OptimizeParams params) {
+ if ((params.getFlags() & ArtFlags.FLAG_FOR_PRIMARY_DEX) == 0
+ && (params.getFlags() & ArtFlags.FLAG_FOR_SECONDARY_DEX) == 0) {
throw new IllegalArgumentException("Nothing to optimize");
}
@@ -236,7 +240,7 @@
AndroidPackageApi pkg = getPackageOrThrow(pkgState);
try {
- return mInjector.getDexOptHelper().dexopt(snapshot, pkgState, pkg, options);
+ return mInjector.getDexOptHelper().dexopt(snapshot, pkgState, pkg, params);
} catch (RemoteException e) {
throw new IllegalStateException("An error occurred when calling artd", e);
}
diff --git a/libartservice/service/java/com/android/server/art/ArtShellCommand.java b/libartservice/service/java/com/android/server/art/ArtShellCommand.java
index 1146aa0..c207fc4 100644
--- a/libartservice/service/java/com/android/server/art/ArtShellCommand.java
+++ b/libartservice/service/java/com/android/server/art/ArtShellCommand.java
@@ -16,6 +16,7 @@
package com.android.server.art;
+import static com.android.server.art.model.ArtFlags.OptimizeFlags;
import static com.android.server.art.model.OptimizationStatus.DexFileOptimizationStatus;
import android.os.Binder;
@@ -25,7 +26,7 @@
import com.android.server.art.model.ArtFlags;
import com.android.server.art.model.DeleteResult;
import com.android.server.art.model.OptimizationStatus;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.OptimizeParams;
import com.android.server.art.model.OptimizeResult;
import com.android.server.art.wrapper.PackageManagerLocal;
import com.android.server.pm.snapshot.PackageDataSnapshot;
@@ -75,15 +76,15 @@
return 0;
}
case "optimize-package": {
- var optionsBuilder = new OptimizeOptions.Builder("cmdline");
+ var paramsBuilder = new OptimizeParams.Builder("cmdline");
String opt;
while ((opt = getNextOption()) != null) {
switch (opt) {
case "-m":
- optionsBuilder.setCompilerFilter(getNextArgRequired());
+ paramsBuilder.setCompilerFilter(getNextArgRequired());
break;
case "-f":
- optionsBuilder.setForce(true);
+ paramsBuilder.setFlags(ArtFlags.FLAG_FORCE, ArtFlags.FLAG_FORCE);
break;
default:
pw.println("Error: Unknown option: " + opt);
@@ -91,7 +92,7 @@
}
}
OptimizeResult result = mArtManagerLocal.optimizePackage(
- snapshot, getNextArgRequired(), optionsBuilder.build());
+ snapshot, getNextArgRequired(), paramsBuilder.build());
switch (result.getFinalStatus()) {
case OptimizeResult.OPTIMIZE_SKIPPED:
pw.println("SKIPPED");
diff --git a/libartservice/service/java/com/android/server/art/DexOptHelper.java b/libartservice/service/java/com/android/server/art/DexOptHelper.java
index f6df0c3..e73abcb 100644
--- a/libartservice/service/java/com/android/server/art/DexOptHelper.java
+++ b/libartservice/service/java/com/android/server/art/DexOptHelper.java
@@ -28,7 +28,8 @@
import android.os.WorkSource;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.ArtFlags;
+import com.android.server.art.model.OptimizeParams;
import com.android.server.art.model.OptimizeResult;
import com.android.server.art.wrapper.AndroidPackageApi;
import com.android.server.art.wrapper.PackageState;
@@ -67,16 +68,16 @@
/**
* DO NOT use this method directly. Use {@link
- * ArtManagerLocal#optimizePackage(PackageDataSnapshot, String, OptimizeOptions)}.
+ * ArtManagerLocal#optimizePackage(PackageDataSnapshot, String, OptimizeParams)}.
*/
@NonNull
public OptimizeResult dexopt(@NonNull PackageDataSnapshot snapshot,
@NonNull PackageState pkgState, @NonNull AndroidPackageApi pkg,
- @NonNull OptimizeOptions options) throws RemoteException {
+ @NonNull OptimizeParams params) throws RemoteException {
List<DexFileOptimizeResult> results = new ArrayList<>();
Supplier<OptimizeResult> createResult = ()
- -> new OptimizeResult(pkgState.getPackageName(), options.getCompilerFilter(),
- options.getReason(), results);
+ -> new OptimizeResult(pkgState.getPackageName(), params.getCompilerFilter(),
+ params.getReason(), results);
if (!canOptimizePackage(pkgState, pkg)) {
return createResult.get();
@@ -96,17 +97,17 @@
wakeLock.acquire(WAKE_LOCK_TIMEOUT_MS);
}
- if (options.isForPrimaryDex()) {
- results.addAll(mInjector.getPrimaryDexOptimizer().dexopt(pkgState, pkg, options));
+ if ((params.getFlags() & ArtFlags.FLAG_FOR_PRIMARY_DEX) != 0) {
+ results.addAll(mInjector.getPrimaryDexOptimizer().dexopt(pkgState, pkg, params));
}
- if (options.isForSecondaryDex()) {
+ if ((params.getFlags() & ArtFlags.FLAG_FOR_SECONDARY_DEX) != 0) {
// TODO(jiakaiz): Implement this.
throw new UnsupportedOperationException(
"Optimizing secondary dex'es is not implemented yet");
}
- if (options.getIncludesDependencies()) {
+ if ((params.getFlags() & ArtFlags.FLAG_SHOULD_INCLUDE_DEPENDENCIES) != 0) {
// TODO(jiakaiz): Implement this.
throw new UnsupportedOperationException(
"Optimizing dependencies is not implemented yet");
diff --git a/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java b/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
index 49708b3..7d51df2 100644
--- a/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
+++ b/libartservice/service/java/com/android/server/art/PrimaryDexOptimizer.java
@@ -34,7 +34,8 @@
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.ArtFlags;
+import com.android.server.art.model.OptimizeParams;
import com.android.server.art.model.OptimizeResult;
import com.android.server.art.wrapper.AndroidPackageApi;
import com.android.server.art.wrapper.PackageState;
@@ -61,17 +62,16 @@
/**
* DO NOT use this method directly. Use {@link
- * ArtManagerLocal#optimizePackage(PackageDataSnapshot, String, OptimizeOptions)}.
+ * ArtManagerLocal#optimizePackage(PackageDataSnapshot, String, OptimizeParams)}.
*/
@NonNull
public List<DexFileOptimizeResult> dexopt(@NonNull PackageState pkgState,
- @NonNull AndroidPackageApi pkg, @NonNull OptimizeOptions options)
- throws RemoteException {
+ @NonNull AndroidPackageApi pkg, @NonNull OptimizeParams params) throws RemoteException {
List<DexFileOptimizeResult> results = new ArrayList<>();
- String targetCompilerFilter = adjustCompilerFilter(
- pkgState, pkg, options.getCompilerFilter(), options.getReason());
- if (targetCompilerFilter.equals(OptimizeOptions.COMPILER_FILTER_NOOP)) {
+ String targetCompilerFilter =
+ adjustCompilerFilter(pkgState, pkg, params.getCompilerFilter(), params.getReason());
+ if (targetCompilerFilter.equals(OptimizeParams.COMPILER_FILTER_NOOP)) {
return results;
}
@@ -94,13 +94,15 @@
PermissionSettings permissionSettings =
getPermissionSettings(pkgState, pkg, true /* canBePublic */);
- DexoptOptions dexoptOptions = getDexoptOptions(pkgState, pkg, options);
+ DexoptOptions dexoptOptions = getDexoptOptions(pkgState, pkg, params);
for (String isa : Utils.getAllIsas(pkgState)) {
@OptimizeResult.OptimizeStatus int status = OptimizeResult.OPTIMIZE_SKIPPED;
try {
- GetDexoptNeededResult getDexoptNeededResult = getDexoptNeeded(dexInfo, isa,
- compilerFilter, options.getShouldDowngrade(), options.getForce());
+ GetDexoptNeededResult getDexoptNeededResult =
+ getDexoptNeeded(dexInfo, isa, compilerFilter,
+ (params.getFlags() & ArtFlags.FLAG_SHOULD_DOWNGRADE) != 0,
+ (params.getFlags() & ArtFlags.FLAG_FORCE) != 0);
if (!getDexoptNeededResult.isDexoptNeeded) {
continue;
@@ -110,7 +112,7 @@
status = dexoptFile(dexInfo, isa, isInDalvikCache, compilerFilter,
inputProfile, getDexoptNeededResult, permissionSettings,
- options.getPriorityClass(), dexoptOptions);
+ params.getPriorityClass(), dexoptOptions);
} catch (ServiceSpecificException e) {
// Log the error and continue.
Log.e(TAG,
@@ -198,9 +200,9 @@
@NonNull
private DexoptOptions getDexoptOptions(@NonNull PackageState pkgState,
- @NonNull AndroidPackageApi pkg, @NonNull OptimizeOptions options) {
+ @NonNull AndroidPackageApi pkg, @NonNull OptimizeParams params) {
DexoptOptions dexoptOptions = new DexoptOptions();
- dexoptOptions.compilationReason = options.getReason();
+ dexoptOptions.compilationReason = params.getReason();
dexoptOptions.targetSdkVersion = pkg.getTargetSdkVersion();
dexoptOptions.debuggable = pkg.isDebuggable() || isAlwaysDebuggable();
dexoptOptions.generateAppImage = false;
@@ -260,7 +262,7 @@
private @OptimizeResult.OptimizeStatus int dexoptFile(@NonNull DetailedPrimaryDexInfo dexInfo,
@NonNull String isa, boolean isInDalvikCache, @NonNull String compilerFilter,
@Nullable ProfilePath profile, @NonNull GetDexoptNeededResult getDexoptNeededResult,
- @NonNull PermissionSettings permissionSettings, @PriorityClass byte priorityClass,
+ @NonNull PermissionSettings permissionSettings, @PriorityClass int priorityClass,
@NonNull DexoptOptions dexoptOptions) throws RemoteException {
OutputArtifacts outputArtifacts = AidlUtils.buildOutputArtifacts(
dexInfo.dexPath(), isa, isInDalvikCache, permissionSettings);
diff --git a/libartservice/service/java/com/android/server/art/ReasonMapping.java b/libartservice/service/java/com/android/server/art/ReasonMapping.java
index 6e9f56f..107f7dc 100644
--- a/libartservice/service/java/com/android/server/art/ReasonMapping.java
+++ b/libartservice/service/java/com/android/server/art/ReasonMapping.java
@@ -16,10 +16,14 @@
package com.android.server.art;
+import static com.android.server.art.model.ArtFlags.PriorityClassApi;
+
import android.annotation.NonNull;
import android.os.SystemProperties;
import android.text.TextUtils;
+import com.android.server.art.model.ArtFlags;
+
import dalvik.system.DexFile;
/**
@@ -98,27 +102,27 @@
* Returns the priority for the given reason.
*
* @throws IllegalArgumentException if the reason is invalid
- * @see PriorityClass
+ * @see PriorityClassApi
*
* @hide
*/
- public static @PriorityClass byte getPriorityClassForReason(@NonNull String reason) {
+ public static @PriorityClassApi byte getPriorityClassForReason(@NonNull String reason) {
switch (reason) {
case REASON_FIRST_BOOT:
case REASON_BOOT_AFTER_OTA:
- return PriorityClass.BOOT;
+ return ArtFlags.PRIORITY_BOOT;
case REASON_INSTALL_FAST:
- return PriorityClass.INTERACTIVE_FAST;
+ return ArtFlags.PRIORITY_INTERACTIVE_FAST;
case REASON_INSTALL:
case REASON_CMDLINE:
- return PriorityClass.INTERACTIVE;
+ return ArtFlags.PRIORITY_INTERACTIVE;
case REASON_BG_DEXOPT:
case REASON_INACTIVE:
case REASON_INSTALL_BULK:
case REASON_INSTALL_BULK_SECONDARY:
case REASON_INSTALL_BULK_DOWNGRADED:
case REASON_INSTALL_BULK_SECONDARY_DOWNGRADED:
- return PriorityClass.BACKGROUND;
+ return ArtFlags.PRIORITY_BACKGROUND;
default:
throw new IllegalArgumentException("No priority class for reason '" + reason + "'");
}
diff --git a/libartservice/service/java/com/android/server/art/Utils.java b/libartservice/service/java/com/android/server/art/Utils.java
index 68cdf07..9e44760 100644
--- a/libartservice/service/java/com/android/server/art/Utils.java
+++ b/libartservice/service/java/com/android/server/art/Utils.java
@@ -22,7 +22,7 @@
import android.util.SparseArray;
import com.android.server.art.ArtifactsPath;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.OptimizeParams;
import com.android.server.art.wrapper.PackageManagerLocal;
import com.android.server.art.wrapper.PackageState;
@@ -77,7 +77,7 @@
/** Returns true if the given string is a valid compiler filter. */
public static boolean isValidArtServiceCompilerFilter(@NonNull String compilerFilter) {
- if (compilerFilter.equals(OptimizeOptions.COMPILER_FILTER_NOOP)) {
+ if (compilerFilter.equals(OptimizeParams.COMPILER_FILTER_NOOP)) {
return true;
}
return DexFile.isValidCompilerFilter(compilerFilter);
diff --git a/libartservice/service/java/com/android/server/art/model/ArtFlags.java b/libartservice/service/java/com/android/server/art/model/ArtFlags.java
index 0ecad74..8accfc3 100644
--- a/libartservice/service/java/com/android/server/art/model/ArtFlags.java
+++ b/libartservice/service/java/com/android/server/art/model/ArtFlags.java
@@ -19,17 +19,37 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import com.android.server.art.PriorityClass;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** @hide */
@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
public class ArtFlags {
+ // Common flags.
+
/** Whether the operation is applied for primary dex'es. */
public static final int FLAG_FOR_PRIMARY_DEX = 1 << 0;
/** Whether the operation is applied for secondary dex'es. */
public static final int FLAG_FOR_SECONDARY_DEX = 1 << 1;
+ // Flags specific to `optimizePackage`.
+
+ /** Whether to optimize dependency libraries as well. */
+ public static final int FLAG_SHOULD_INCLUDE_DEPENDENCIES = 1 << 2;
+ /**
+ * Whether the intention is to downgrade the compiler filter. If true, the optimization will
+ * be skipped if the target compiler filter is better than or equal to the compiler filter
+ * of the existing optimized artifacts, or optimized artifacts do not exist.
+ */
+ public static final int FLAG_SHOULD_DOWNGRADE = 1 << 3;
+ /**
+ * Whether to force optimization. If true, the optimization will be performed regardless of
+ * any existing optimized artifacts.
+ */
+ public static final int FLAG_FORCE = 1 << 4;
+
/**
* Flags for {@link ArtManagerLocal#deleteOptimizedArtifacts(PackageDataSnapshot, String, int)}.
*
@@ -76,5 +96,70 @@
return FLAG_FOR_PRIMARY_DEX;
}
+ /**
+ * Flags for {@link OptimizeParams}.
+ *
+ * @hide
+ */
+ // clang-format off
+ @IntDef(flag = true, prefix = "FLAG_", value = {
+ FLAG_FOR_PRIMARY_DEX,
+ FLAG_FOR_SECONDARY_DEX,
+ FLAG_SHOULD_INCLUDE_DEPENDENCIES,
+ FLAG_SHOULD_DOWNGRADE,
+ FLAG_FORCE,
+ })
+ // clang-format on
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface OptimizeFlags {}
+
+ /**
+ * Default flags that are used when
+ * {@link OptimizeParams.Builder#Builder(String)} is called.
+ * Value: {@link #FLAG_FOR_PRIMARY_DEX}.
+ */
+ public static @OptimizeFlags int defaultOptimizeFlags() {
+ return FLAG_FOR_PRIMARY_DEX;
+ }
+
+ // Keep in sync with `PriorityClass` except for `PRIORITY_NONE`.
+
+ /**
+ * Initial value. Not expected.
+ *
+ * @hide
+ */
+ public static final int PRIORITY_NONE = -1;
+ /** Indicates that the operation blocks boot. */
+ public static final int PRIORITY_BOOT = PriorityClass.BOOT;
+ /**
+ * Indicates that a human is waiting on the result and the operation is more latency sensitive
+ * than usual.
+ */
+ public static final int PRIORITY_INTERACTIVE_FAST = PriorityClass.INTERACTIVE_FAST;
+ /** Indicates that a human is waiting on the result. */
+ public static final int PRIORITY_INTERACTIVE = PriorityClass.INTERACTIVE;
+ /** Indicates that the operation runs in background. */
+ public static final int PRIORITY_BACKGROUND = PriorityClass.BACKGROUND;
+
+ /**
+ * Indicates the priority of an operation. The value affects the resource usage and the process
+ * priority. A higher value may result in faster execution but may consume more resources and
+ * compete for resources with other processes.
+ *
+ * @hide
+ */
+ // clang-format off
+ @IntDef(prefix = "PRIORITY_", value = {
+ PRIORITY_NONE,
+ PRIORITY_BOOT,
+ PRIORITY_INTERACTIVE_FAST,
+ PRIORITY_INTERACTIVE,
+ PRIORITY_BACKGROUND,
+ })
+ // clang-format on
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PriorityClassApi {}
+
private ArtFlags() {}
}
diff --git a/libartservice/service/java/com/android/server/art/model/OptimizeOptions.java b/libartservice/service/java/com/android/server/art/model/OptimizeOptions.java
deleted file mode 100644
index 6e897ec..0000000
--- a/libartservice/service/java/com/android/server/art/model/OptimizeOptions.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.art.model;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.text.TextUtils;
-
-import com.android.server.art.PriorityClass;
-import com.android.server.art.ReasonMapping;
-import com.android.server.art.Utils;
-
-/** @hide */
-public class OptimizeOptions {
- public static final class Builder {
- private OptimizeOptions mOptions = new OptimizeOptions();
-
- /**
- * Creates a builder.
- *
- * @param reason See {@link #setReason(String)}.
- */
- public Builder(@NonNull String reason) {
- setReason(reason);
- }
-
- /** Whether to generate optimized artifacts for primary dex'es. Default: true. */
- public Builder setForPrimaryDex(boolean value) {
- mOptions.mIsForPrimaryDex = value;
- return this;
- }
-
- /** Whether to generate optimized artifacts for secondary dex'es. Default: false. */
- public Builder setForSecondaryDex(boolean value) {
- mOptions.mIsForSecondaryDex = value;
- return this;
- }
-
- /** Whether to optimize dependency packages as well. Default: false. */
- public Builder setIncludesDependencies(boolean value) {
- mOptions.mIncludesDependencies = value;
- return this;
- }
-
- /**
- * The target compiler filter. Note that the compiler filter might be adjusted before the
- * execution based on factors like whether the profile is available or whether the app is
- * used by other apps. If not set, the default compiler filter for the given reason will be
- * used.
- */
- public Builder setCompilerFilter(@NonNull String value) {
- mOptions.mCompilerFilter = value;
- return this;
- }
-
- /**
- * The priority of the operation. If not set, the default priority class for the given
- * reason will be used.
- *
- * @see PriorityClass
- */
- public Builder setPriorityClass(@PriorityClass byte value) {
- mOptions.mPriorityClass = value;
- return this;
- }
-
- /**
- * Compilation reason. Can be a string defined in {@link ReasonMapping} or a custom string.
- *
- * If the value is a string defined in {@link ReasonMapping}, it determines the compiler
- * filter and/or the priority class, if those values are not explicitly set.
- *
- * If the value is a custom string, the priority class and the compiler filter must be
- * explicitly set.
- */
- public Builder setReason(@NonNull String value) {
- mOptions.mReason = value;
- return this;
- }
-
- /**
- * Whether the intention is to downgrade the compiler filter. If true, the compilation will
- * be skipped if the target compiler filter is better than or equal to the compiler filter
- * of the existing optimized artifacts, or optimized artifacts do not exist.
- */
- public Builder setShouldDowngrade(boolean value) {
- mOptions.mShouldDowngrade = value;
- return this;
- }
-
- /**
- * Whether to force compilation. If true, the compilation will be performed regardless of
- * any existing optimized artifacts.
- */
- public Builder setForce(boolean value) {
- mOptions.mForce = value;
- return this;
- }
-
- /**
- * Returns the built object.
- *
- * @throws IllegalArgumentException if the built options would be invalid
- */
- public OptimizeOptions build() {
- if (mOptions.mReason.isEmpty()) {
- throw new IllegalArgumentException("Reason must not be empty");
- }
-
- if (mOptions.mCompilerFilter.isEmpty()) {
- mOptions.mCompilerFilter =
- ReasonMapping.getCompilerFilterForReason(mOptions.mReason);
- } else if (!Utils.isValidArtServiceCompilerFilter(mOptions.mCompilerFilter)) {
- throw new IllegalArgumentException(
- "Invalid compiler filter '" + mOptions.mCompilerFilter + "'");
- }
-
- if (mOptions.mPriorityClass == -1) {
- mOptions.mPriorityClass = ReasonMapping.getPriorityClassForReason(mOptions.mReason);
- } else if (mOptions.mPriorityClass < 0 || mOptions.mPriorityClass > 100) {
- throw new IllegalArgumentException("Invalid priority class "
- + mOptions.mPriorityClass + ". Must be between 0 and 100");
- }
-
- return mOptions;
- }
- }
-
- /**
- * A value indicating that dexopt shouldn't be run. This value is consumed by ART Services and
- * is not propagated to dex2oat.
- */
- public static final String COMPILER_FILTER_NOOP = "skip";
-
- private boolean mIsForPrimaryDex = true;
- private boolean mIsForSecondaryDex = false;
- private boolean mIncludesDependencies = false;
- private @NonNull String mCompilerFilter = "";
- private @PriorityClass byte mPriorityClass = -1;
- private @NonNull String mReason = "";
- private boolean mShouldDowngrade = false;
- private boolean mForce = false;
-
- private OptimizeOptions() {}
-
- /** Whether to generate optimized artifacts for primary dex'es. */
- public boolean isForPrimaryDex() {
- return mIsForPrimaryDex;
- }
-
- /** Whether to generate optimized artifacts for secondary dex'es. */
- public boolean isForSecondaryDex() {
- return mIsForSecondaryDex;
- }
-
- /** Whether to optimize dependency packages as well. */
- public boolean getIncludesDependencies() {
- return mIncludesDependencies;
- }
-
- /** The target compiler filter. */
- public @NonNull String getCompilerFilter() {
- return mCompilerFilter;
- }
-
- /** The priority class. */
- public @PriorityClass byte getPriorityClass() {
- return mPriorityClass;
- }
-
- /**
- * The compilation reason.
- *
- * DO NOT directly use the string value to determine the resource usage and the process
- * priority. Use {@link #getPriorityClass}.
- */
- public @NonNull String getReason() {
- return mReason;
- }
-
- /** Whether the intention is to downgrade the compiler filter. */
- public boolean getShouldDowngrade() {
- return mShouldDowngrade;
- }
-
- /** Whether to force compilation. */
- public boolean getForce() {
- return mForce;
- }
-}
diff --git a/libartservice/service/java/com/android/server/art/model/OptimizeParams.java b/libartservice/service/java/com/android/server/art/model/OptimizeParams.java
new file mode 100644
index 0000000..672aebb
--- /dev/null
+++ b/libartservice/service/java/com/android/server/art/model/OptimizeParams.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.art.model;
+
+import static com.android.server.art.model.ArtFlags.OptimizeFlags;
+import static com.android.server.art.model.ArtFlags.PriorityClassApi;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.text.TextUtils;
+
+import com.android.server.art.ReasonMapping;
+import com.android.server.art.Utils;
+
+/** @hide */
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+public class OptimizeParams {
+ public static final class Builder {
+ private OptimizeParams mParams = new OptimizeParams();
+
+ /**
+ * Creates a builder.
+ *
+ * Uses default flags ({@link ArtFlags#defaultOptimizeFlags()}).
+ *
+ * @param reason See {@link #setReason(String)}.
+ */
+ public Builder(@NonNull String reason) {
+ this(reason, ArtFlags.defaultOptimizeFlags());
+ }
+
+ /**
+ * Same as above, but allows to specify flags.
+ */
+ public Builder(@NonNull String reason, @OptimizeFlags int flags) {
+ setReason(reason);
+ setFlags(flags);
+ }
+
+ /** Replaces all flags with the given value. */
+ @NonNull
+ public Builder setFlags(@OptimizeFlags int value) {
+ mParams.mFlags = value;
+ return this;
+ }
+
+ /** Replaces the flags specified by the mask with the given value. */
+ @NonNull
+ public Builder setFlags(@OptimizeFlags int value, @OptimizeFlags int mask) {
+ mParams.mFlags = (mParams.mFlags & ~mask) | (value & mask);
+ return this;
+ }
+
+ /**
+ * The target compiler filter. Note that the compiler filter might be adjusted before the
+ * execution based on factors like whether the profile is available or whether the app is
+ * used by other apps. If not set, the default compiler filter for the given reason will be
+ * used.
+ */
+ @NonNull
+ public Builder setCompilerFilter(@NonNull String value) {
+ mParams.mCompilerFilter = value;
+ return this;
+ }
+
+ /**
+ * The priority of the operation. If not set, the default priority class for the given
+ * reason will be used.
+ *
+ * @see PriorityClassApi
+ */
+ @NonNull
+ public Builder setPriorityClass(@PriorityClassApi int value) {
+ mParams.mPriorityClass = value;
+ return this;
+ }
+
+ /**
+ * Compilation reason. Can be a string defined in {@link ReasonMapping} or a custom string.
+ *
+ * If the value is a string defined in {@link ReasonMapping}, it determines the compiler
+ * filter and/or the priority class, if those values are not explicitly set.
+ *
+ * If the value is a custom string, the priority class and the compiler filter must be
+ * explicitly set.
+ */
+ @NonNull
+ public Builder setReason(@NonNull String value) {
+ mParams.mReason = value;
+ return this;
+ }
+
+ /**
+ * Returns the built object.
+ *
+ * @throws IllegalArgumentException if the built options would be invalid
+ */
+ @NonNull
+ public OptimizeParams build() {
+ if (mParams.mReason.isEmpty()) {
+ throw new IllegalArgumentException("Reason must not be empty");
+ }
+
+ if (mParams.mCompilerFilter.isEmpty()) {
+ mParams.mCompilerFilter = ReasonMapping.getCompilerFilterForReason(mParams.mReason);
+ } else if (!Utils.isValidArtServiceCompilerFilter(mParams.mCompilerFilter)) {
+ throw new IllegalArgumentException(
+ "Invalid compiler filter '" + mParams.mCompilerFilter + "'");
+ }
+
+ if (mParams.mPriorityClass == ArtFlags.PRIORITY_NONE) {
+ mParams.mPriorityClass = ReasonMapping.getPriorityClassForReason(mParams.mReason);
+ } else if (mParams.mPriorityClass < 0 || mParams.mPriorityClass > 100) {
+ throw new IllegalArgumentException("Invalid priority class "
+ + mParams.mPriorityClass + ". Must be between 0 and 100");
+ }
+
+ return mParams;
+ }
+ }
+
+ /**
+ * A value indicating that dexopt shouldn't be run. This value is consumed by ART Services and
+ * is not propagated to dex2oat.
+ */
+ public static final String COMPILER_FILTER_NOOP = "skip";
+
+ private @OptimizeFlags int mFlags = 0;
+ private @NonNull String mCompilerFilter = "";
+ private @PriorityClassApi int mPriorityClass = ArtFlags.PRIORITY_NONE;
+ private @NonNull String mReason = "";
+
+ private OptimizeParams() {}
+
+ /** Returns all flags. */
+ public @OptimizeFlags int getFlags() {
+ return mFlags;
+ }
+
+ /** The target compiler filter. */
+ public @NonNull String getCompilerFilter() {
+ return mCompilerFilter;
+ }
+
+ /** The priority class. */
+ public @PriorityClassApi int getPriorityClass() {
+ return mPriorityClass;
+ }
+
+ /**
+ * The compilation reason.
+ *
+ * DO NOT directly use the string value to determine the resource usage and the process
+ * priority. Use {@link #getPriorityClass}.
+ */
+ public @NonNull String getReason() {
+ return mReason;
+ }
+}
diff --git a/libartservice/service/java/com/android/server/art/model/OptimizeResult.java b/libartservice/service/java/com/android/server/art/model/OptimizeResult.java
index efebbf2..d6fdf28 100644
--- a/libartservice/service/java/com/android/server/art/model/OptimizeResult.java
+++ b/libartservice/service/java/com/android/server/art/model/OptimizeResult.java
@@ -18,12 +18,16 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.SystemApi;
import com.android.internal.annotations.Immutable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.List;
/** @hide */
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
@Immutable
public class OptimizeResult {
// Possible values of {@link #OptimizeStatus}.
@@ -35,8 +39,15 @@
public static final int OPTIMIZE_CANCELLED = 40;
/** @hide */
- @IntDef(prefix = {"OPTIMIZE_"},
- value = {OPTIMIZE_SKIPPED, OPTIMIZE_FAILED, OPTIMIZE_PERFORMED, OPTIMIZE_CANCELLED})
+ // clang-format off
+ @IntDef(prefix = {"OPTIMIZE_"}, value = {
+ OPTIMIZE_SKIPPED,
+ OPTIMIZE_FAILED,
+ OPTIMIZE_PERFORMED,
+ OPTIMIZE_CANCELLED,
+ })
+ // clang-format on
+ @Retention(RetentionPolicy.SOURCE)
public @interface OptimizeStatus {}
private final @NonNull String mPackageName;
diff --git a/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java b/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java
index ded89c9..bb1b26d 100644
--- a/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java
+++ b/libartservice/service/javatests/com/android/server/art/ArtManagerLocalTest.java
@@ -38,7 +38,7 @@
import com.android.server.art.model.DeleteResult;
import com.android.server.art.model.OptimizationStatus;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.OptimizeParams;
import com.android.server.art.model.OptimizeResult;
import com.android.server.art.wrapper.AndroidPackageApi;
import com.android.server.art.wrapper.PackageManagerLocal;
@@ -219,14 +219,14 @@
@Test
public void testOptimizePackage() throws Exception {
- var options = new OptimizeOptions.Builder("install").build();
+ var params = new OptimizeParams.Builder("install").build();
var result = mock(OptimizeResult.class);
- when(mDexOptHelper.dexopt(any(), same(mPkgState), same(mPkg), same(options)))
+ when(mDexOptHelper.dexopt(any(), same(mPkgState), same(mPkg), same(params)))
.thenReturn(result);
- assertThat(mArtManagerLocal.optimizePackage(
- mock(PackageDataSnapshot.class), PKG_NAME, options))
+ assertThat(
+ mArtManagerLocal.optimizePackage(mock(PackageDataSnapshot.class), PKG_NAME, params))
.isSameInstanceAs(result);
}
@@ -235,7 +235,7 @@
when(mPackageManagerLocal.getPackageState(any(), anyInt(), eq(PKG_NAME))).thenReturn(null);
mArtManagerLocal.optimizePackage(mock(PackageDataSnapshot.class), PKG_NAME,
- new OptimizeOptions.Builder("install").build());
+ new OptimizeParams.Builder("install").build());
}
@Test(expected = IllegalArgumentException.class)
@@ -243,7 +243,7 @@
when(mPkgState.getAndroidPackage()).thenReturn(null);
mArtManagerLocal.optimizePackage(mock(PackageDataSnapshot.class), PKG_NAME,
- new OptimizeOptions.Builder("install").build());
+ new OptimizeParams.Builder("install").build());
}
private AndroidPackageApi createPackage() {
diff --git a/libartservice/service/javatests/com/android/server/art/DexOptHelperTest.java b/libartservice/service/javatests/com/android/server/art/DexOptHelperTest.java
index e68f21b..1b9c852 100644
--- a/libartservice/service/javatests/com/android/server/art/DexOptHelperTest.java
+++ b/libartservice/service/javatests/com/android/server/art/DexOptHelperTest.java
@@ -36,7 +36,7 @@
import androidx.test.filters.SmallTest;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.OptimizeParams;
import com.android.server.art.model.OptimizeResult;
import com.android.server.art.testing.OnSuccessRule;
import com.android.server.art.wrapper.AndroidPackageApi;
@@ -71,8 +71,8 @@
verifyNoMoreInteractions(mPrimaryDexOptimizer);
});
- private final OptimizeOptions mOptions =
- new OptimizeOptions.Builder("install").setCompilerFilter("speed-profile").build();
+ private final OptimizeParams mParams =
+ new OptimizeParams.Builder("install").setCompilerFilter("speed-profile").build();
private final List<DexFileOptimizeResult> mPrimaryResults =
List.of(new DexFileOptimizeResult("/data/app/foo/base.apk", "arm64", "verify",
OptimizeResult.OPTIMIZE_PERFORMED),
@@ -95,11 +95,11 @@
@Test
public void testDexopt() throws Exception {
- when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mOptions)))
+ when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mParams)))
.thenReturn(mPrimaryResults);
OptimizeResult result =
- mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mOptions);
+ mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mParams);
assertThat(result.getPackageName()).isEqualTo(PKG_NAME);
assertThat(result.getRequestedCompilerFilter()).isEqualTo("speed-profile");
@@ -113,7 +113,7 @@
when(mPkg.isHasCode()).thenReturn(false);
OptimizeResult result =
- mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mOptions);
+ mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mParams);
assertThat(result.getFinalStatus()).isEqualTo(OptimizeResult.OPTIMIZE_SKIPPED);
assertThat(result.getDexFileOptimizeResults()).isEmpty();
@@ -125,11 +125,11 @@
lenient().when(mAhm.isHibernatingGlobally(PKG_NAME)).thenReturn(false);
lenient().when(mAhm.isOatArtifactDeletionEnabled()).thenReturn(true);
- when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mOptions)))
+ when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mParams)))
.thenReturn(mPrimaryResults);
OptimizeResult result =
- mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mOptions);
+ mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mParams);
assertThat(result.getDexFileOptimizeResults()).containsExactlyElementsIn(mPrimaryResults);
}
@@ -141,7 +141,7 @@
lenient().when(mAhm.isOatArtifactDeletionEnabled()).thenReturn(true);
OptimizeResult result =
- mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mOptions);
+ mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mParams);
assertThat(result.getFinalStatus()).isEqualTo(OptimizeResult.OPTIMIZE_SKIPPED);
assertThat(result.getDexFileOptimizeResults()).isEmpty();
@@ -153,11 +153,11 @@
lenient().when(mAhm.isHibernatingGlobally(PKG_NAME)).thenReturn(true);
lenient().when(mAhm.isOatArtifactDeletionEnabled()).thenReturn(false);
- when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mOptions)))
+ when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mParams)))
.thenReturn(mPrimaryResults);
OptimizeResult result =
- mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mOptions);
+ mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mParams);
assertThat(result.getDexFileOptimizeResults()).containsExactlyElementsIn(mPrimaryResults);
}
@@ -169,11 +169,11 @@
when(mPowerManager.newWakeLock(eq(PowerManager.PARTIAL_WAKE_LOCK), any()))
.thenReturn(wakeLock);
- when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mOptions)))
+ when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mParams)))
.thenReturn(mPrimaryResults);
OptimizeResult result =
- mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mOptions);
+ mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mParams);
InOrder inOrder = inOrder(mPrimaryDexOptimizer, wakeLock);
inOrder.verify(wakeLock).acquire(anyLong());
@@ -188,12 +188,12 @@
when(mPowerManager.newWakeLock(eq(PowerManager.PARTIAL_WAKE_LOCK), any()))
.thenReturn(wakeLock);
- when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mOptions)))
+ when(mPrimaryDexOptimizer.dexopt(same(mPkgState), same(mPkg), same(mParams)))
.thenThrow(IllegalStateException.class);
try {
- OptimizeResult result = mDexOptHelper.dexopt(
- mock(PackageDataSnapshot.class), mPkgState, mPkg, mOptions);
+ OptimizeResult result =
+ mDexOptHelper.dexopt(mock(PackageDataSnapshot.class), mPkgState, mPkg, mParams);
} catch (Exception e) {
}
diff --git a/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerParameterizedTest.java b/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerParameterizedTest.java
index d1eba96..c7c779e 100644
--- a/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerParameterizedTest.java
+++ b/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerParameterizedTest.java
@@ -40,7 +40,8 @@
import androidx.test.filters.SmallTest;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.ArtFlags;
+import com.android.server.art.model.OptimizeParams;
import com.android.server.art.model.OptimizeResult;
import com.android.server.art.testing.OnSuccessRule;
import com.android.server.art.testing.TestingUtils;
@@ -65,7 +66,7 @@
verifyNoMoreInteractions(mArtd);
});
- private OptimizeOptions mOptions;
+ private OptimizeParams mOptimizeParams;
@Parameter(0) public Params mParams;
@@ -176,12 +177,14 @@
lenient().when(mPkgState.isSystem()).thenReturn(mParams.mIsSystem);
lenient().when(mPkgState.isUpdatedSystemApp()).thenReturn(mParams.mIsUpdatedSystemApp);
- mOptions = new OptimizeOptions.Builder("install")
- .setCompilerFilter(mParams.mRequestedCompilerFilter)
- .setPriorityClass(PriorityClass.INTERACTIVE)
- .setForce(mParams.mForce)
- .setShouldDowngrade(mParams.mShouldDowngrade)
- .build();
+ mOptimizeParams =
+ new OptimizeParams.Builder("install")
+ .setCompilerFilter(mParams.mRequestedCompilerFilter)
+ .setPriorityClass(ArtFlags.PRIORITY_INTERACTIVE)
+ .setFlags(mParams.mForce ? ArtFlags.FLAG_FORCE : 0, ArtFlags.FLAG_FORCE)
+ .setFlags(mParams.mShouldDowngrade ? ArtFlags.FLAG_SHOULD_DOWNGRADE : 0,
+ ArtFlags.FLAG_SHOULD_DOWNGRADE)
+ .build();
}
@Test
@@ -242,7 +245,7 @@
eq(mParams.mExpectedCompilerFilter), isNull() /* profile */,
isNull() /* inputVdex */, eq(PriorityClass.INTERACTIVE), deepEq(dexoptOptions));
- assertThat(mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptions))
+ assertThat(mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptimizeParams))
.comparingElementsUsing(TestingUtils.<DexFileOptimizeResult>deepEquality())
.containsExactly(
new DexFileOptimizeResult("/data/app/foo/base.apk", "arm64",
diff --git a/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java b/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
index 594d054..8db3032 100644
--- a/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
+++ b/libartservice/service/javatests/com/android/server/art/PrimaryDexOptimizerTest.java
@@ -20,7 +20,6 @@
import static com.android.server.art.testing.TestingUtils.deepEq;
import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyByte;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
@@ -29,7 +28,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.server.art.model.OptimizeOptions;
+import com.android.server.art.model.OptimizeParams;
import org.junit.Before;
import org.junit.Test;
@@ -38,13 +37,13 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class PrimaryDexOptimizerTest extends PrimaryDexOptimizerTestBase {
- private OptimizeOptions mOptions;
+ private OptimizeParams mOptimizeParams;
@Before
public void setUp() throws Exception {
super.setUp();
- mOptions = new OptimizeOptions.Builder("install").setCompilerFilter("verify").build();
+ mOptimizeParams = new OptimizeParams.Builder("install").setCompilerFilter("verify").build();
}
@Test
@@ -54,7 +53,7 @@
.when(mArtd)
.getDexoptNeeded(eq("/data/app/foo/base.apk"), eq("arm64"), any(), any(), anyInt());
doReturn(true).when(mArtd).dexopt(any(), eq("/data/app/foo/base.apk"), eq("arm64"), any(),
- any(), any(), isNull(), anyByte(), any());
+ any(), any(), isNull(), anyInt(), any());
// ArtifactsPath, isInDalvikCache=true.
doReturn(dexoptIsNeeded(ArtifactsLocation.DALVIK_CACHE))
@@ -64,7 +63,7 @@
any(), any(),
deepEq(VdexPath.artifactsPath(AidlUtils.buildArtifactsPath(
"/data/app/foo/base.apk", "arm", true /* isInDalvikCache */))),
- anyByte(), any());
+ anyInt(), any());
// ArtifactsPath, isInDalvikCache=false.
doReturn(dexoptIsNeeded(ArtifactsLocation.NEXT_TO_DEX))
@@ -75,7 +74,7 @@
any(), any(), any(),
deepEq(VdexPath.artifactsPath(AidlUtils.buildArtifactsPath(
"/data/app/foo/split_0.apk", "arm64", false /* isInDalvikCache */))),
- anyByte(), any());
+ anyInt(), any());
// DexMetadataPath.
doReturn(dexoptIsNeeded(ArtifactsLocation.DM))
@@ -86,8 +85,8 @@
any(), any(),
deepEq(VdexPath.dexMetadataPath(
AidlUtils.buildDexMetadataPath("/data/app/foo/split_0.apk"))),
- anyByte(), any());
+ anyInt(), any());
- mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptions);
+ mPrimaryDexOptimizer.dexopt(mPkgState, mPkg, mOptimizeParams);
}
}
diff --git a/libartservice/service/javatests/com/android/server/art/ReasonMappingTest.java b/libartservice/service/javatests/com/android/server/art/ReasonMappingTest.java
index 776cb0f..ea1226e 100644
--- a/libartservice/service/javatests/com/android/server/art/ReasonMappingTest.java
+++ b/libartservice/service/javatests/com/android/server/art/ReasonMappingTest.java
@@ -25,6 +25,7 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.art.model.ArtFlags;
import com.android.server.art.testing.StaticMockitoRule;
import org.junit.After;
@@ -73,7 +74,7 @@
@Test
public void testGetPriorityClassForReason() throws Exception {
assertThat(ReasonMapping.getPriorityClassForReason("install"))
- .isEqualTo(PriorityClass.INTERACTIVE);
+ .isEqualTo(ArtFlags.PRIORITY_INTERACTIVE);
}
@Test(expected = IllegalArgumentException.class)
diff --git a/libartservice/service/javatests/com/android/server/art/model/OptimizeOptionsTest.java b/libartservice/service/javatests/com/android/server/art/model/OptimizeParamsTest.java
similarity index 72%
rename from libartservice/service/javatests/com/android/server/art/model/OptimizeOptionsTest.java
rename to libartservice/service/javatests/com/android/server/art/model/OptimizeParamsTest.java
index 47515c7..200bbc4 100644
--- a/libartservice/service/javatests/com/android/server/art/model/OptimizeOptionsTest.java
+++ b/libartservice/service/javatests/com/android/server/art/model/OptimizeParamsTest.java
@@ -21,49 +21,49 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.server.art.PriorityClass;
-
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class OptimizeOptionsTest {
+public class OptimizeParamsTest {
@Test
public void testBuild() {
- new OptimizeOptions.Builder("install").build();
+ new OptimizeParams.Builder("install").build();
}
@Test(expected = IllegalArgumentException.class)
public void testBuildEmptyReason() {
- new OptimizeOptions.Builder("").build();
+ new OptimizeParams.Builder("").build();
}
@Test(expected = IllegalArgumentException.class)
public void testBuildInvalidCompilerFilter() {
- new OptimizeOptions.Builder("install").setCompilerFilter("invalid").build();
+ new OptimizeParams.Builder("install").setCompilerFilter("invalid").build();
}
@Test(expected = IllegalArgumentException.class)
public void testBuildInvalidPriorityClass() {
- new OptimizeOptions.Builder("install").setPriorityClass((byte) 101).build();
+ new OptimizeParams.Builder("install").setPriorityClass(101).build();
}
@Test
public void testBuildCustomReason() {
- new OptimizeOptions.Builder("custom")
+ new OptimizeParams.Builder("custom")
.setCompilerFilter("speed")
- .setPriorityClass((byte) 90)
+ .setPriorityClass(90)
.build();
}
@Test(expected = IllegalArgumentException.class)
public void testBuildCustomReasonEmptyCompilerFilter() {
- new OptimizeOptions.Builder("custom").setPriorityClass(PriorityClass.INTERACTIVE).build();
+ new OptimizeParams.Builder("custom")
+ .setPriorityClass(ArtFlags.PRIORITY_INTERACTIVE)
+ .build();
}
@Test(expected = IllegalArgumentException.class)
public void testBuildCustomReasonEmptyPriorityClass() {
- new OptimizeOptions.Builder("custom").setCompilerFilter("speed").build();
+ new OptimizeParams.Builder("custom").setCompilerFilter("speed").build();
}
}