Fix long paths on Windows
util::mkdirs iteratively creates each directory of a specified path. For
windows, Calling mkdir on only the drive letter or on the extended path
prefix (\?\\) will result in an error. Start after the long path prefix
and the drive letter.
This also changes AAPT2 to use AssetMaanager2 to retrieve symbols from
the symbol table. AssetManager2's zip library uses _wopen to open
windows files.
Bug:123251200
Test: aapt2_tests.exe
Change-Id: I26169d83b22d441485de3c49d63a6c4ed710e292
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 66d8542..d7b84ff 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -356,6 +356,7 @@
ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_override,
bool /*stop_at_first_match*/,
+ bool ignore_configuration,
FindEntryResult* out_entry) const {
// Might use this if density_override != 0.
ResTable_config density_override_config;
@@ -399,7 +400,7 @@
// If desired_config is the same as the set configuration, then we can use our filtered list
// and we don't need to match the configurations, since they already matched.
- const bool use_fast_path = desired_config == &configuration_;
+ const bool use_fast_path = !ignore_configuration && desired_config == &configuration_;
for (size_t pi = 0; pi < package_count; pi++) {
const ConfiguredPackage& loaded_package_impl = package_group.packages_[pi];
@@ -475,21 +476,23 @@
// ResTable_config, we must copy it.
const auto iter_end = type_spec->types + type_spec->type_count;
for (auto iter = type_spec->types; iter != iter_end; ++iter) {
- ResTable_config this_config;
- this_config.copyFromDtoH((*iter)->config);
+ ResTable_config this_config{};
- if (!this_config.match(*desired_config)) {
- continue;
- }
+ if (!ignore_configuration) {
+ this_config.copyFromDtoH((*iter)->config);
+ if (!this_config.match(*desired_config)) {
+ continue;
+ }
- if (best_config == nullptr) {
- resolution_type = Resolution::Step::Type::INITIAL;
- } else if (this_config.isBetterThan(*best_config, desired_config)) {
- resolution_type = Resolution::Step::Type::BETTER_MATCH;
- } else if (package_is_overlay && this_config.compare(*best_config) == 0) {
- resolution_type = Resolution::Step::Type::OVERLAID;
- } else {
- continue;
+ if (best_config == nullptr) {
+ resolution_type = Resolution::Step::Type::INITIAL;
+ } else if (this_config.isBetterThan(*best_config, desired_config)) {
+ resolution_type = Resolution::Step::Type::BETTER_MATCH;
+ } else if (package_is_overlay && this_config.compare(*best_config) == 0) {
+ resolution_type = Resolution::Step::Type::OVERLAID;
+ } else {
+ continue;
+ }
}
// The configuration matches and is better than the previous selection.
@@ -506,6 +509,11 @@
best_config = &best_config_copy;
best_offset = offset;
+ if (ignore_configuration) {
+ // Any configuration will suffice, so break.
+ break;
+ }
+
if (resource_resolution_logging_enabled_) {
resolution_steps.push_back(Resolution::Step{resolution_type,
this_config.toString(),
@@ -622,8 +630,9 @@
bool AssetManager2::GetResourceName(uint32_t resid, ResourceName* out_name) const {
FindEntryResult entry;
- ApkAssetsCookie cookie =
- FindEntry(resid, 0u /* density_override */, true /* stop_at_first_match */, &entry);
+ ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */,
+ true /* stop_at_first_match */,
+ true /* ignore_configuration */, &entry);
if (cookie == kInvalidCookie) {
return false;
}
@@ -652,13 +661,14 @@
bool AssetManager2::GetResourceFlags(uint32_t resid, uint32_t* out_flags) const {
FindEntryResult entry;
- ApkAssetsCookie cookie =
- FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, &entry);
+ ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */,
+ false /* stop_at_first_match */,
+ true /* ignore_configuration */, &entry);
if (cookie != kInvalidCookie) {
*out_flags = entry.type_flags;
- return cookie;
+ return true;
}
- return kInvalidCookie;
+ return false;
}
ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag,
@@ -666,8 +676,8 @@
ResTable_config* out_selected_config,
uint32_t* out_flags) const {
FindEntryResult entry;
- ApkAssetsCookie cookie =
- FindEntry(resid, density_override, false /* stop_at_first_match */, &entry);
+ ApkAssetsCookie cookie = FindEntry(resid, density_override, false /* stop_at_first_match */,
+ false /* ignore_configuration */, &entry);
if (cookie == kInvalidCookie) {
return kInvalidCookie;
}
@@ -759,8 +769,10 @@
}
FindEntryResult entry;
- ApkAssetsCookie cookie =
- FindEntry(resid, 0u /* density_override */, false /* stop_at_first_match */, &entry);
+ ApkAssetsCookie cookie = FindEntry(resid, 0u /* density_override */,
+ false /* stop_at_first_match */,
+ false /* ignore_configuration */,
+ &entry);
if (cookie == kInvalidCookie) {
return nullptr;
}
@@ -1387,7 +1399,9 @@
// Find the cookie of the attribute resource id
FindEntryResult attribute_entry_result;
ApkAssetsCookie attribute_cookie =
- o.asset_manager_->FindEntry(make_resid(p, t, e), 0 /* density_override */ , false,
+ o.asset_manager_->FindEntry(make_resid(p, t, e), 0 /* density_override */ ,
+ true /* stop_at_first_match */,
+ true /* ignore_configuration */,
&attribute_entry_result);
// Determine the package id of the attribute in the destination AssetManager
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index fc5aa9c7..1e2b36cb1 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -257,11 +257,12 @@
// Creates a new Theme from this AssetManager.
std::unique_ptr<Theme> NewTheme();
- template <typename Func>
- void ForEachPackage(Func func) const {
+ void ForEachPackage(const std::function<bool(const std::string&, uint8_t)> func) const {
for (const PackageGroup& package_group : package_groups_) {
- func(package_group.packages_.front().loaded_package_->GetPackageName(),
- package_group.dynamic_ref_table.mAssignedPackageId);
+ if (!func(package_group.packages_.front().loaded_package_->GetPackageName(),
+ package_group.dynamic_ref_table.mAssignedPackageId)) {
+ return;
+ }
}
}
@@ -282,10 +283,13 @@
// care about the value. In this case, the value of `FindEntryResult::type_flags` is incomplete
// and should not be used.
//
+ // When `ignore_configuration` is true, FindEntry will return always select the first entry in
+ // for the type seen regardless of its configuration.
+ //
// NOTE: FindEntry takes care of ensuring that structs within FindEntryResult have been properly
// bounds-checked. Callers of FindEntry are free to trust the data if this method succeeds.
ApkAssetsCookie FindEntry(uint32_t resid, uint16_t density_override, bool stop_at_first_match,
- FindEntryResult* out_entry) const;
+ bool ignore_configuration, FindEntryResult* out_entry) const;
// Assigns package IDs to all shared library ApkAssets.
// Should be called whenever the ApkAssets are changed.