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

Commit ccd5ca9b authored by Ryan Mitchell's avatar Ryan Mitchell Committed by Automerger Merge Worker
Browse files

Set resource id correctly when resolve fails am: e7ab6272 am: 9e78098e

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1519910

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I25318a316ae24d3f587009c688f7e830b7c00c2b
parents c85f2160 9e78098e
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -975,19 +975,23 @@ base::expected<std::monostate, NullOrIOError> AssetManager2::ResolveReference(
  for (uint32_t i = 0U;; i++) {
  for (uint32_t i = 0U;; i++) {
    auto result = GetResource(resolve_resid, true /*may_be_bag*/);
    auto result = GetResource(resolve_resid, true /*may_be_bag*/);
    if (!result.has_value()) {
    if (!result.has_value()) {
      value.resid = resolve_resid;
      return base::unexpected(result.error());
      return base::unexpected(result.error());
    }
    }


    // If resource resolution fails, the value should be set to the last reference that was able to
    // be resolved successfully.
    value = *result;
    value.flags |= combined_flags;

    if (result->type != Res_value::TYPE_REFERENCE ||
    if (result->type != Res_value::TYPE_REFERENCE ||
        result->data == Res_value::DATA_NULL_UNDEFINED ||
        result->data == Res_value::DATA_NULL_UNDEFINED ||
        result->data == resolve_resid || i == kMaxIterations) {
        result->data == resolve_resid || i == kMaxIterations) {
      // This reference can't be resolved, so exit now and let the caller deal with it.
      // This reference can't be resolved, so exit now and let the caller deal with it.
      value = *result;
      value.flags |= combined_flags;
      return {};
      return {};
    }
    }


    combined_flags |= result->flags;
    combined_flags = result->flags;
    resolve_resid = result->data;
    resolve_resid = result->data;
  }
  }
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -265,7 +265,7 @@ base::expected<std::monostate, IOError> ApplyStyle(Theme* theme, ResXMLParser* x
    const size_t xml_attr_idx = xml_attr_finder.Find(cur_ident);
    const size_t xml_attr_idx = xml_attr_finder.Find(cur_ident);
    if (xml_attr_idx != xml_attr_finder.end()) {
    if (xml_attr_idx != xml_attr_finder.end()) {
      // We found the attribute we were looking for.
      // We found the attribute we were looking for.
      Res_value attribute_value;
      Res_value attribute_value{};
      xml_parser->getAttributeValue(xml_attr_idx, &attribute_value);
      xml_parser->getAttributeValue(xml_attr_idx, &attribute_value);
      value.type = attribute_value.dataType;
      value.type = attribute_value.dataType;
      value.data = attribute_value.data;
      value.data = attribute_value.data;
@@ -377,7 +377,7 @@ base::expected<std::monostate, IOError> RetrieveAttributes(AssetManager2* assetm


    // Retrieve the current XML attribute if it matches, and step to next.
    // Retrieve the current XML attribute if it matches, and step to next.
    if (ix < xml_attr_count && cur_ident == cur_xml_attr) {
    if (ix < xml_attr_count && cur_ident == cur_xml_attr) {
      Res_value attribute_value;
      Res_value attribute_value{};
      xml_parser->getAttributeValue(ix, &attribute_value);
      xml_parser->getAttributeValue(ix, &attribute_value);
      value.type = attribute_value.dataType;
      value.type = attribute_value.dataType;
      value.data = attribute_value.data;
      value.data = attribute_value.data;
+35 −3
Original line number Original line Diff line number Diff line
@@ -446,9 +446,6 @@ TEST_F(AssetManager2Test, KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved)
  AssetManager2 assetmanager;
  AssetManager2 assetmanager;
  assetmanager.SetApkAssets({basic_assets_.get()});
  assetmanager.SetApkAssets({basic_assets_.get()});


  ResTable_config selected_config;
  memset(&selected_config, 0, sizeof(selected_config));

  // Create some kind of value that is NOT a reference.
  // Create some kind of value that is NOT a reference.
  AssetManager2::SelectedValue value{};
  AssetManager2::SelectedValue value{};
  value.cookie = 1;
  value.cookie = 1;
@@ -461,6 +458,41 @@ TEST_F(AssetManager2Test, KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved)
  EXPECT_EQ(basic::R::string::test1, value.resid);
  EXPECT_EQ(basic::R::string::test1, value.resid);
}
}


TEST_F(AssetManager2Test, ResolveReferenceMissingResource) {
  AssetManager2 assetmanager;
  assetmanager.SetApkAssets({basic_assets_.get()});

  const uint32_t kMissingResId = 0x8001ffff;
  AssetManager2::SelectedValue value{};
  value.type = Res_value::TYPE_REFERENCE;
  value.data = kMissingResId;

  auto result = assetmanager.ResolveReference(value);
  ASSERT_FALSE(result.has_value());
  EXPECT_EQ(Res_value::TYPE_REFERENCE, value.type);
  EXPECT_EQ(kMissingResId, value.data);
  EXPECT_EQ(kMissingResId, value.resid);
  EXPECT_EQ(-1, value.cookie);
  EXPECT_EQ(0, value.flags);
}

TEST_F(AssetManager2Test, ResolveReferenceMissingResourceLib) {
  AssetManager2 assetmanager;
  assetmanager.SetApkAssets({libclient_assets_.get()});

  AssetManager2::SelectedValue value{};
  value.type = Res_value::TYPE_REFERENCE;
  value.data = libclient::R::string::foo_one;

  auto result = assetmanager.ResolveReference(value);
  ASSERT_TRUE(result.has_value());
  EXPECT_EQ(Res_value::TYPE_DYNAMIC_REFERENCE, value.type);
  EXPECT_EQ(lib_one::R::string::foo, value.data);
  EXPECT_EQ(libclient::R::string::foo_one, value.resid);
  EXPECT_EQ(0, value.cookie);
  EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), value.flags);
}

static bool IsConfigurationPresent(const std::set<ResTable_config>& configurations,
static bool IsConfigurationPresent(const std::set<ResTable_config>& configurations,
                                   const ResTable_config& configuration) {
                                   const ResTable_config& configuration) {
  return configurations.count(configuration) > 0;
  return configurations.count(configuration) > 0;