Make ArtDexFileLoader accept an zip file with no dex code.
We pass config split APKs as part of the class loader context to
OatFileAssistant, in both the legacy dexopt code path and the new ART
Services code path. Those config split APKs eventually go to
ArtDexFileLoader. Therefore, ArtDexFileLoader should not regard this as
an error.
Before this change, this was regarded as an error. The legacy dexopt
code path could work because it uses the legacy
`DexFile.GetDexOptNeeded` Java API, which doesn't check the result of
opening dex files. The new ART Services code path couldn't work because
it checks the result.
Bug: 229268202
Test: m test-art-host-gtest
Test: (on internal master) -
1. Run `pm art optimize-package` for a split APK that depends on a
config split APK.
2. See dexopt being successful.
Change-Id: I08a2a5ad7bea82c3f534ed4de2935fc400652361
diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h
index 2d0a150..33708ce 100644
--- a/runtime/oat_file_assistant.h
+++ b/runtime/oat_file_assistant.h
@@ -284,8 +284,8 @@
const std::string& dex_location,
std::vector<std::unique_ptr<const DexFile>>* out_dex_files);
- // Returns whether this is an apk/zip wit a classes.dex entry.
- bool HasDexFiles();
+ // Returns whether this is an apk/zip wit a classes.dex entry, or nullopt if an error occurred.
+ std::optional<bool> HasDexFiles(std::string* error_msg);
// If the dex file has been installed with a compiled oat file alongside
// it, the compiled oat file will have the extension .odex, and is referred
@@ -489,12 +489,10 @@
OatStatus GivenOatFileStatus(const OatFile& file);
// Gets the dex checksums required for an up-to-date oat file.
- // Returns cached_required_dex_checksums if the required checksums were
- // located. Returns null if the required checksums were not found. The
- // caller shouldn't clean up or free the returned pointer. This sets the
- // has_original_dex_files_ field to true if the checksums were found for the
- // dex_location_ dex file.
- const std::vector<uint32_t>* GetRequiredDexChecksums();
+ // Returns cached_required_dex_checksums if the required checksums were located. Returns an empty
+ // list if `dex_location_` refers to a zip and there is no dex file in it. Returns nullptr if an
+ // error occurred. The caller shouldn't clean up or free the returned pointer.
+ const std::vector<uint32_t>* GetRequiredDexChecksums(std::string* error_msg);
// Returns whether there is at least one boot image usable.
bool IsPrimaryBootImageUsable();
@@ -547,10 +545,9 @@
// Cached value of the required dex checksums.
// This should be accessed only by the GetRequiredDexChecksums() method.
- std::vector<uint32_t> cached_required_dex_checksums_;
+ std::optional<std::vector<uint32_t>> cached_required_dex_checksums_;
+ std::string cached_required_dex_checksums_error_;
bool required_dex_checksums_attempted_ = false;
- bool required_dex_checksums_found_;
- bool has_original_dex_files_;
// The AOT-compiled file of an app when the APK of the app is in /data.
OatFileInfo odex_;