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

Commit 3dabeaba authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Flag support for bag resource types" into main

parents d6a41391 d52bd685
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -68,6 +68,16 @@ public class ResourceFlaggingTest {
        assertThat(getBoolean("res3")).isTrue();
    }

    @Test
    public void testFlagDisabledStringArrayElement() {
        assertThat(getStringArray("strarr1")).isEqualTo(new String[]{"one", "two", "three"});
    }

    @Test
    public void testFlagDisabledIntArrayElement() {
        assertThat(getIntArray("intarr1")).isEqualTo(new int[]{1, 2, 3});
    }

    private boolean getBoolean(String name) {
        int resId = mResources.getIdentifier(
                name,
@@ -77,13 +87,22 @@ public class ResourceFlaggingTest {
        return mResources.getBoolean(resId);
    }

    private String getString(String name) {
    private String[] getStringArray(String name) {
        int resId = mResources.getIdentifier(
                name,
                "array",
                "com.android.intenal.flaggedresources");
        assertThat(resId).isNotEqualTo(0);
        return mResources.getStringArray(resId);
    }

    private int[] getIntArray(String name) {
        int resId = mResources.getIdentifier(
                name,
                "string",
                "array",
                "com.android.intenal.flaggedresources");
        assertThat(resId).isNotEqualTo(0);
        return mResources.getString(resId);
        return mResources.getIntArray(resId);
    }

    private String extractApkAndGetPath(int id) throws Exception {
+38 −23
Original line number Diff line number Diff line
@@ -151,6 +151,7 @@ static bool AddResourcesToTable(ResourceTable* table, android::IDiagnostics* dia
  }

  if (res->value != nullptr) {
    res->value->SetFlagStatus(res->flag_status);
    // Attach the comment, source and config to the value.
    res->value->SetComment(std::move(res->comment));
    res->value->SetSource(std::move(res->source));
@@ -546,30 +547,11 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
  });

  std::string resource_type = parser->element_name();
  std::optional<StringPiece> flag =
      xml::FindAttribute(parser, "http://schemas.android.com/apk/res/android", "featureFlag");
  out_resource->flag_status = FlagStatus::NoFlag;
  if (flag) {
    auto flag_it = options_.feature_flag_values.find(flag.value());
    if (flag_it == options_.feature_flag_values.end()) {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "Resource flag value undefined");
      return false;
    }
    const auto& flag_properties = flag_it->second;
    if (!flag_properties.read_only) {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "Only read only flags may be used with resources");
  auto flag_status = GetFlagStatus(parser);
  if (!flag_status) {
    return false;
  }
    if (!flag_properties.enabled.has_value()) {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "Only flags with a value may be used with resources");
      return false;
    }
    out_resource->flag_status =
        flag_properties.enabled.value() ? FlagStatus::Enabled : FlagStatus::Disabled;
  }
  out_resource->flag_status = flag_status.value();

  // The value format accepted for this resource.
  uint32_t resource_format = 0u;
@@ -751,6 +733,33 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
  return false;
}

std::optional<FlagStatus> ResourceParser::GetFlagStatus(xml::XmlPullParser* parser) {
  auto flag_status = FlagStatus::NoFlag;

  std::optional<StringPiece> flag = xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag");
  if (flag) {
    auto flag_it = options_.feature_flag_values.find(flag.value());
    if (flag_it == options_.feature_flag_values.end()) {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "Resource flag value undefined");
      return {};
    }
    const auto& flag_properties = flag_it->second;
    if (!flag_properties.read_only) {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "Only read only flags may be used with resources");
      return {};
    }
    if (!flag_properties.enabled.has_value()) {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "Only flags with a value may be used with resources");
      return {};
    }
    flag_status = flag_properties.enabled.value() ? FlagStatus::Enabled : FlagStatus::Disabled;
  }
  return flag_status;
}

bool ResourceParser::ParseItem(xml::XmlPullParser* parser,
                               ParsedResource* out_resource,
                               const uint32_t format) {
@@ -1657,12 +1666,18 @@ bool ResourceParser::ParseArrayImpl(xml::XmlPullParser* parser,
    const std::string& element_namespace = parser->element_namespace();
    const std::string& element_name = parser->element_name();
    if (element_namespace.empty() && element_name == "item") {
      auto flag_status = GetFlagStatus(parser);
      if (!flag_status) {
        error = true;
        continue;
      }
      std::unique_ptr<Item> item = ParseXml(parser, typeMask, kNoRawString);
      if (!item) {
        diag_->Error(android::DiagMessage(item_source) << "could not parse array item");
        error = true;
        continue;
      }
      item->SetFlagStatus(flag_status.value());
      item->SetSource(item_source);
      array->elements.emplace_back(std::move(item));

+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ class ResourceParser {
 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceParser);

  std::optional<FlagStatus> GetFlagStatus(xml::XmlPullParser* parser);

  std::optional<FlattenedXmlSubTree> CreateFlattenSubTree(xml::XmlPullParser* parser);

  // Parses the XML subtree as a StyleString (flattened XML representation for strings with
+3 −4
Original line number Diff line number Diff line
@@ -605,11 +605,11 @@ bool ResourceTable::AddResource(NewResource&& res, android::IDiagnostics* diag)
    if (!config_value->value) {
      // Resource does not exist, add it now.
      config_value->value = std::move(res.value);
      config_value->flag_status = res.flag_status;
    } else {
      // When validation is enabled, ensure that a resource cannot have multiple values defined for
      // the same configuration unless protected by flags.
      auto result = validate ? ResolveFlagCollision(config_value->flag_status, res.flag_status)
      auto result =
          validate ? ResolveFlagCollision(config_value->value->GetFlagStatus(), res.flag_status)
                   : CollisionResult::kKeepBoth;
      if (result == CollisionResult::kConflict) {
        result = ResolveValueCollision(config_value->value.get(), res.value.get());
@@ -619,7 +619,6 @@ bool ResourceTable::AddResource(NewResource&& res, android::IDiagnostics* diag)
          // Insert the value ignoring for duplicate configurations
          entry->values.push_back(util::make_unique<ResourceConfigValue>(res.config, res.product));
          entry->values.back()->value = std::move(res.value);
          entry->values.back()->flag_status = res.flag_status;
          break;

        case CollisionResult::kTakeNew:
+0 −2
Original line number Diff line number Diff line
@@ -104,8 +104,6 @@ class ResourceConfigValue {
  // The actual Value.
  std::unique_ptr<Value> value;

  FlagStatus flag_status = FlagStatus::NoFlag;

  ResourceConfigValue(const android::ConfigDescription& config, android::StringPiece product)
      : config(config), product(product) {
  }
Loading