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

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

Merge changes I9f2b6b15,I5e1e341e into main

* changes:
  Add support for flagging xml and png files
  Add support for flag in resource directory names
parents de5b025b e08e0379
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -103,6 +104,26 @@ public class ResourceFlaggingTest {
        assertThat(mResources.getIntArray(R.array.intarr1)).isEqualTo(new int[]{1, 2, 3});
    }

    @Test
    public void testDirectoryEnabledFlag() {
        assertThat(mResources.getBoolean(R.bool.bool8)).isTrue();
    }

    @Test
    public void testDirectoryDisabledFlag() {
        assertThat(mResources.getBoolean(R.bool.bool7)).isTrue();
    }

    @Test
    public void testDirectoryNegatedEnabledFlag() {
        assertThat(mResources.getBoolean(R.bool.bool9)).isTrue();
    }

    @Test
    public void testDirectoryNegatedDisabledFlag() {
        assertThat(mResources.getBoolean(R.bool.bool10)).isTrue();
    }

    @Test
    public void testLayoutWithDisabledElements() {
        LinearLayout ll = (LinearLayout) getLayoutInflater().inflate(R.layout.layout1, null);
@@ -112,6 +133,24 @@ public class ResourceFlaggingTest {
        assertThat((View) ll.findViewById(R.id.text2)).isNotNull();
    }

    @Test
    public void testEnabledFlagLayoutOverrides() {
        LinearLayout ll = (LinearLayout) getLayoutInflater().inflate(R.layout.layout3, null);
        assertThat(ll).isNotNull();
        assertThat((View) ll.findViewById(R.id.text1)).isNotNull();
        assertThat(((TextView) ll.findViewById(R.id.text1)).getText()).isEqualTo("foobar");
    }

    @Test(expected = Resources.NotFoundException.class)
    public void testDisabledLayout() {
        getLayoutInflater().inflate(R.layout.layout2, null);
    }

    @Test(expected = Resources.NotFoundException.class)
    public void testDisabledDrawable() {
        mResources.getDrawable(R.drawable.removedpng);
    }

    private LayoutInflater getLayoutInflater() {
        ContextWrapper c = new ContextWrapper(mContext) {
            private LayoutInflater mInflater;
+6 −0
Original line number Diff line number Diff line
@@ -243,6 +243,12 @@ struct ResourceFile {

  // Exported symbols
  std::vector<SourcedResourceName> exported_symbols;

  // Flag status
  FlagStatus flag_status = FlagStatus::NoFlag;

  // Flag
  std::optional<FeatureFlagAttribute> flag;
};

/**
+22 −28
Original line number Diff line number Diff line
@@ -546,8 +546,14 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
      {"symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
  });

  std::string resource_type = parser->element_name();
  out_resource->flag = GetFlag(parser);
  std::string_view resource_type = parser->element_name();
  if (auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag"))) {
    if (options_.flag) {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "Resource flag are not allowed both in the path and in the file");
      return false;
    }
    out_resource->flag = std::move(flag);
    std::string error;
    auto flag_status = GetFlagStatus(out_resource->flag, options_.feature_flag_values, &error);
    if (flag_status) {
@@ -556,6 +562,10 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) << error);
      return false;
    }
  } else if (options_.flag) {
    out_resource->flag = options_.flag;
    out_resource->flag_status = options_.flag_status;
  }

  // The value format accepted for this resource.
  uint32_t resource_format = 0u;
@@ -571,7 +581,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,

    // Items have their type encoded in the type attribute.
    if (std::optional<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
      resource_type = std::string(maybe_type.value());
      resource_type = maybe_type.value();
    } else {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "<item> must have a 'type' attribute");
@@ -594,7 +604,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,

    // Bags have their type encoded in the type attribute.
    if (std::optional<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
      resource_type = std::string(maybe_type.value());
      resource_type = maybe_type.value();
    } else {
      diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number()))
                   << "<bag> must have a 'type' attribute");
@@ -737,22 +747,6 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
  return false;
}

std::optional<FeatureFlagAttribute> ResourceParser::GetFlag(xml::XmlPullParser* parser) {
  auto name = xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag");
  if (name) {
    FeatureFlagAttribute flag;
    if (name->starts_with('!')) {
      flag.negated = true;
      flag.name = name->substr(1);
    } else {
      flag.name = name.value();
    }
    return flag;
  } else {
    return {};
  }
}

bool ResourceParser::ParseItem(xml::XmlPullParser* parser,
                               ParsedResource* out_resource,
                               const uint32_t format) {
@@ -1659,7 +1653,7 @@ 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 = GetFlag(parser);
      auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag"));
      std::unique_ptr<Item> item = ParseXml(parser, typeMask, kNoRawString);
      if (!item) {
        diag_->Error(android::DiagMessage(item_source) << "could not parse array item");
+5 −2
Original line number Diff line number Diff line
@@ -57,6 +57,11 @@ struct ResourceParserOptions {
  std::optional<Visibility::Level> visibility;

  FeatureFlagValues feature_flag_values;

  // The flag that should be applied to all resources parsed
  std::optional<FeatureFlagAttribute> flag;

  FlagStatus flag_status = FlagStatus::NoFlag;
};

struct FlattenedXmlSubTree {
@@ -85,8 +90,6 @@ class ResourceParser {
 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceParser);

  std::optional<FeatureFlagAttribute> GetFlag(xml::XmlPullParser* parser);

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

  // Parses the XML subtree as a StyleString (flattened XML representation for strings with
+5 −0
Original line number Diff line number Diff line
@@ -49,4 +49,9 @@ message CompiledFile {

  // Any symbols this file auto-generates/exports (eg. @+id/foo in an XML file).
  repeated Symbol exported_symbol = 5;

  // The status of the flag the file is behind if any
  uint32 flag_status = 6;
  bool flag_negated = 7;
  string flag_name = 8;
}
Loading