Expose extra status codes and external profile errors as APIs.
Bug: 278080573
Test: m
Change-Id: Ib0ee9d2407a86c4f32b3b0ad2f8b18ac1f1d9004
Merged-In: Ib0ee9d2407a86c4f32b3b0ad2f8b18ac1f1d9004
diff --git a/libartservice/service/api/system-server-current.txt b/libartservice/service/api/system-server-current.txt
index a9cd65a..f885980 100644
--- a/libartservice/service/api/system-server-current.txt
+++ b/libartservice/service/api/system-server-current.txt
@@ -142,6 +142,9 @@
field public static final int DEXOPT_FAILED = 30; // 0x1e
field public static final int DEXOPT_PERFORMED = 20; // 0x14
field public static final int DEXOPT_SKIPPED = 10; // 0xa
+ field public static final int EXTRA_BAD_EXTERNAL_PROFILE = 4; // 0x4
+ field public static final int EXTRA_SKIPPED_NO_DEX_CODE = 2; // 0x2
+ field public static final int EXTRA_SKIPPED_STORAGE_LOW = 1; // 0x1
}
public abstract static class DexoptResult.DexContainerFileDexoptResult {
@@ -150,6 +153,8 @@
method public abstract long getDex2oatCpuTimeMillis();
method public abstract long getDex2oatWallTimeMillis();
method @NonNull public abstract String getDexContainerFile();
+ method @NonNull public abstract java.util.List<java.lang.String> getExternalProfileErrors();
+ method public abstract int getExtraStatuses();
method public abstract long getSizeBeforeBytes();
method public abstract long getSizeBytes();
method public abstract int getStatus();
diff --git a/libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java b/libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java
index 533e340..c87e9f7 100644
--- a/libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java
+++ b/libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java
@@ -51,7 +51,7 @@
.filter(packageResult
-> packageResult.getDexContainerFileDexoptResults().stream().anyMatch(
fileResult
- -> (fileResult.getExtraStatus()
+ -> (fileResult.getExtraStatuses()
& DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
== 0))
.collect(Collectors.toList());
@@ -75,7 +75,7 @@
.flatMap(packageResult
-> packageResult.getDexContainerFileDexoptResults().stream())
.anyMatch(fileResult
- -> (fileResult.getExtraStatus()
+ -> (fileResult.getExtraStatuses()
& DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
!= 0);
if (isSkippedDueToStorageLow) {
diff --git a/libartservice/service/java/com/android/server/art/model/DexoptResult.java b/libartservice/service/java/com/android/server/art/model/DexoptResult.java
index 55298af..45704e8 100644
--- a/libartservice/service/java/com/android/server/art/model/DexoptResult.java
+++ b/libartservice/service/java/com/android/server/art/model/DexoptResult.java
@@ -63,11 +63,26 @@
public @interface DexoptResultStatus {}
// Possible values of {@link #DexoptResultExtraStatus}.
- /** @hide */
+ /** Dexopt is skipped because the remaining storage space is low. */
public static final int EXTRA_SKIPPED_STORAGE_LOW = 1 << 0;
- /** @hide */
+ /**
+ * Dexopt is skipped because the dex container file has no dex code while the manifest declares
+ * that it does.
+ *
+ * Note that this flag doesn't apply to dex container files that are not declared to have code.
+ * Instead, those files are not listed in {@link
+ * PackageDexoptResult#getDexContainerFileDexoptResults} in the first place.
+ */
public static final int EXTRA_SKIPPED_NO_DEX_CODE = 1 << 1;
- /** @hide */
+ /**
+ * Dexopt encountered errors when processing the profiles that are external to the device,
+ * including the profile in the DM file and the profile embedded in the dex container file.
+ * Details of the errors can be found in {@link
+ * DexContainerFileDexoptResult#getExternalProfileErrors}.
+ *
+ * This is not a critical error. Dexopt may still have succeeded after ignoring the bad external
+ * profiles.
+ */
public static final int EXTRA_BAD_EXTERNAL_PROFILE = 1 << 2;
/** @hide */
@@ -301,10 +316,26 @@
*/
public abstract long getSizeBeforeBytes();
- /** @hide */
- public abstract @DexoptResultExtraStatus int getExtraStatus();
+ /**
+ * A bitfield of the extended status flags.
+ *
+ * Flags that starts with `EXTRA_SKIPPED_` are a subset of the reasons why dexopt is
+ * skipped. Note that they don't cover all possible reasons. At most one `EXTRA_SKIPPED_`
+ * flag will be set, even if the situation meets multiple `EXTRA_SKIPPED_` flags. The order
+ * of precedence of those flags is undefined.
+ */
+ public abstract @DexoptResultExtraStatus int getExtraStatuses();
- /** @hide */
+ /**
+ * Details of errors occurred when processing external profiles, one error per profile file
+ * that the dexopter tried to read.
+ *
+ * If the same dex container file is dexopted for multiple ABIs, the same profile errors
+ * will be repeated for each ABI in the {@link DexContainerFileDexoptResult}s of the same
+ * dex container file.
+ *
+ * @see #EXTRA_BAD_EXTERNAL_PROFILE.
+ */
public abstract @NonNull List<String> getExternalProfileErrors();
@Override
@@ -325,7 +356,7 @@
DexoptResult.dexoptResultStatusToString(getStatus()),
getDex2oatWallTimeMillis(), getDex2oatCpuTimeMillis(), getSizeBytes(),
getSizeBeforeBytes(),
- DexoptResult.dexoptResultExtraStatusToString(getExtraStatus()));
+ DexoptResult.dexoptResultExtraStatusToString(getExtraStatuses()));
}
}
}
diff --git a/libartservice/service/javatests/com/android/server/art/PrimaryDexopterTest.java b/libartservice/service/javatests/com/android/server/art/PrimaryDexopterTest.java
index aa5203d..3fce031 100644
--- a/libartservice/service/javatests/com/android/server/art/PrimaryDexopterTest.java
+++ b/libartservice/service/javatests/com/android/server/art/PrimaryDexopterTest.java
@@ -401,11 +401,11 @@
List<DexContainerFileDexoptResult> results = mPrimaryDexopter.dexopt();
assertThat(results.get(0).getStatus()).isEqualTo(DexoptResult.DEXOPT_PERFORMED);
- assertThat(results.get(0).getExtraStatus() & DexoptResult.EXTRA_BAD_EXTERNAL_PROFILE)
+ assertThat(results.get(0).getExtraStatuses() & DexoptResult.EXTRA_BAD_EXTERNAL_PROFILE)
.isNotEqualTo(0);
assertThat(results.get(0).getExternalProfileErrors()).containsExactly("error_msg");
assertThat(results.get(1).getStatus()).isEqualTo(DexoptResult.DEXOPT_PERFORMED);
- assertThat(results.get(1).getExtraStatus() & DexoptResult.EXTRA_BAD_EXTERNAL_PROFILE)
+ assertThat(results.get(1).getExtraStatuses() & DexoptResult.EXTRA_BAD_EXTERNAL_PROFILE)
.isNotEqualTo(0);
assertThat(results.get(1).getExternalProfileErrors()).containsExactly("error_msg");
}
@@ -648,16 +648,16 @@
List<DexContainerFileDexoptResult> results = mPrimaryDexopter.dexopt();
assertThat(results.get(0).getStatus()).isEqualTo(DexoptResult.DEXOPT_PERFORMED);
- assertThat(results.get(0).getExtraStatus() & DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
+ assertThat(results.get(0).getExtraStatuses() & DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
.isEqualTo(0);
assertThat(results.get(1).getStatus()).isEqualTo(DexoptResult.DEXOPT_SKIPPED);
- assertThat(results.get(1).getExtraStatus() & DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
+ assertThat(results.get(1).getExtraStatuses() & DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
.isNotEqualTo(0);
assertThat(results.get(2).getStatus()).isEqualTo(DexoptResult.DEXOPT_SKIPPED);
- assertThat(results.get(2).getExtraStatus() & DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
+ assertThat(results.get(2).getExtraStatuses() & DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
.isNotEqualTo(0);
assertThat(results.get(3).getStatus()).isEqualTo(DexoptResult.DEXOPT_PERFORMED);
- assertThat(results.get(3).getExtraStatus() & DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
+ assertThat(results.get(3).getExtraStatuses() & DexoptResult.EXTRA_SKIPPED_STORAGE_LOW)
.isEqualTo(0);
verify(mArtd, times(2))
@@ -682,16 +682,16 @@
List<DexContainerFileDexoptResult> results = mPrimaryDexopter.dexopt();
assertThat(results.get(0).getStatus()).isEqualTo(DexoptResult.DEXOPT_SKIPPED);
- assertThat(results.get(0).getExtraStatus() & DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
+ assertThat(results.get(0).getExtraStatuses() & DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
.isNotEqualTo(0);
assertThat(results.get(1).getStatus()).isEqualTo(DexoptResult.DEXOPT_SKIPPED);
- assertThat(results.get(1).getExtraStatus() & DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
+ assertThat(results.get(1).getExtraStatuses() & DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
.isNotEqualTo(0);
assertThat(results.get(2).getStatus()).isEqualTo(DexoptResult.DEXOPT_SKIPPED);
- assertThat(results.get(2).getExtraStatus() & DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
+ assertThat(results.get(2).getExtraStatuses() & DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
.isEqualTo(0);
assertThat(results.get(3).getStatus()).isEqualTo(DexoptResult.DEXOPT_PERFORMED);
- assertThat(results.get(3).getExtraStatus() & DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
+ assertThat(results.get(3).getExtraStatuses() & DexoptResult.EXTRA_SKIPPED_NO_DEX_CODE)
.isEqualTo(0);
}
@@ -744,7 +744,7 @@
private void verifyStatusAllOk(List<DexContainerFileDexoptResult> results) {
for (DexContainerFileDexoptResult result : results) {
assertThat(result.getStatus()).isEqualTo(DexoptResult.DEXOPT_PERFORMED);
- assertThat(result.getExtraStatus()).isEqualTo(0);
+ assertThat(result.getExtraStatuses()).isEqualTo(0);
assertThat(result.getExternalProfileErrors()).isEmpty();
}
}