Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a55dc2ed authored by Ryan Mitchell's avatar Ryan Mitchell
Browse files

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
parent de19d80f
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -343,7 +343,9 @@ static jobject NativeGetOverlayableMap(JNIEnv* env, jclass /*clazz*/, jlong ptr,
  assetmanager->ForEachPackage([&](const std::string& this_package_name, uint8_t package_id) {
    if (this_package_name == std_package_name) {
      map = assetmanager->GetOverlayableMapForPackage(package_id);
      return false;
    }
    return true;
  });

  if (map == nullptr) {
@@ -521,15 +523,16 @@ static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/
    return nullptr;
  }

  assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) {
  assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) -> bool {
    jstring jpackage_name = env->NewStringUTF(package_name.c_str());
    if (jpackage_name == nullptr) {
      // An exception is pending.
      return;
      return false;
    }

    env->CallVoidMethod(sparse_array, gSparseArrayOffsets.put, static_cast<jint>(package_id),
                        jpackage_name);
    return true;
  });
  return sparse_array;
}
+39 −25
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ std::unique_ptr<Asset> AssetManager2::OpenNonAsset(const std::string& filename,

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 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri

  // 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,9 +476,10 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri
      // 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 (!ignore_configuration) {
          this_config.copyFromDtoH((*iter)->config);
          if (!this_config.match(*desired_config)) {
            continue;
          }
@@ -491,6 +493,7 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri
          } else {
            continue;
          }
        }

        // The configuration matches and is better than the previous selection.
        // Find the entry value if it exists for this configuration.
@@ -506,6 +509,11 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri
        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 @@ std::string AssetManager2::GetLastResourceResolution() const {

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::GetResourceName(uint32_t resid, ResourceName* out_name) cons

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 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag,
                                           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 @@ const ResolvedBag* AssetManager2::GetBag(uint32_t resid, std::vector<uint32_t>&
  }

  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 @@ void Theme::SetTo(const Theme& o) {
            // 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
+9 −5
Original line number Diff line number Diff line
@@ -257,11 +257,12 @@ class AssetManager2 {
  // 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 @@ class AssetManager2 {
  // 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.
+36 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ constexpr int32_t kNonBreakingSpace = 0xa0;

Maybe<ResourceName> ToResourceName(
    const android::ResTable::resource_name& name_in) {
  // TODO: Remove this when ResTable and AssetManager(1) are removed from AAPT2
  ResourceName name_out;
  if (!name_in.package) {
    return {};
@@ -79,6 +80,41 @@ Maybe<ResourceName> ToResourceName(
  return name_out;
}

Maybe<ResourceName> ToResourceName(const android::AssetManager2::ResourceName& name_in) {
  ResourceName name_out;
  if (!name_in.package) {
    return {};
  }

  name_out.package = std::string(name_in.package, name_in.package_len);

  const ResourceType* type;
  if (name_in.type16) {
    type = ParseResourceType(
        util::Utf16ToUtf8(StringPiece16(name_in.type16, name_in.type_len)));
  } else if (name_in.type) {
    type = ParseResourceType(StringPiece(name_in.type, name_in.type_len));
  } else {
    return {};
  }

  if (!type) {
    return {};
  }

  name_out.type = *type;

  if (name_in.entry16) {
    name_out.entry =
        util::Utf16ToUtf8(StringPiece16(name_in.entry16, name_in.entry_len));
  } else if (name_in.entry) {
    name_out.entry = std::string(name_in.entry, name_in.entry_len);
  } else {
    return {};
  }
  return name_out;
}

bool ParseResourceName(const StringPiece& str, ResourceNameRef* out_ref,
                       bool* out_private) {
  if (str.empty()) {
+7 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <functional>
#include <memory>

#include "androidfw/AssetManager2.h"
#include "androidfw/ConfigDescription.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/StringPiece.h"
@@ -77,6 +78,12 @@ bool IsAttributeReference(const android::StringPiece& str);
Maybe<ResourceName> ToResourceName(
    const android::ResTable::resource_name& name);

/**
 * Convert an android::AssetManager2::ResourceName to an aapt::ResourceName struct.
 */
Maybe<ResourceName> ToResourceName(
    const android::AssetManager2::ResourceName& name_in);

/**
 * Returns a boolean value if the string is equal to TRUE, true, True, FALSE,
 * false, or False.
Loading