Add flag support to styles elements
Test: Automated
Bug: 329436914
Flag: EXEMPT Aconfig not supported on host tools
Change-Id: I3041ebbaf98a90527809b541df8885edfc70d035
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index fce6aa7..da092f4 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -1529,13 +1529,34 @@
ResolvePackage(parser, &maybe_key.value());
maybe_key.value().SetSource(source);
+ auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag"));
+
std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString);
if (!value) {
diag_->Error(android::DiagMessage(source) << "could not parse style item");
return false;
}
- style->entries.push_back(Style::Entry{std::move(maybe_key.value()), std::move(value)});
+ if (flag) {
+ 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;
+ }
+ std::string error;
+ auto flag_status = GetFlagStatus(flag, options_.feature_flag_values, &error);
+ if (flag_status) {
+ value->SetFlagStatus(flag_status.value());
+ value->SetFlag(std::move(flag));
+ } else {
+ diag_->Error(android::DiagMessage(source_.WithLine(parser->line_number())) << error);
+ return false;
+ }
+ }
+
+ if (value->GetFlagStatus() != FlagStatus::Disabled) {
+ style->entries.push_back(Style::Entry{std::move(maybe_key.value()), std::move(value)});
+ }
return true;
}
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index a0f60b6..fe9b4a8 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -302,6 +302,11 @@
Plural plural = 5;
MacroBody macro = 6;
}
+
+ // The status of the flag the value is behind if any
+ uint32 flag_status = 7;
+ bool flag_negated = 8;
+ string flag_name = 9;
}
// Message holding a boolean, so it can be optionally encoded.
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 8583cad..91ec348 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -551,11 +551,10 @@
return false;
}
- FeatureFlagAttribute flag;
- flag.name = pb_config_value.value().item().flag_name();
- flag.negated = pb_config_value.value().item().flag_negated();
- ResourceConfigValue* config_value =
- entry->FindOrCreateFlagDisabledValue(std::move(flag), config, pb_config.product());
+ ResourceConfigValue* config_value = entry->FindOrCreateFlagDisabledValue(
+ FeatureFlagAttribute{.name = pb_config_value.value().item().flag_name(),
+ .negated = pb_config_value.value().item().flag_negated()},
+ config, pb_config.product());
if (config_value->value != nullptr) {
*out_error = "duplicate configuration in resource table";
return false;
@@ -563,7 +562,6 @@
config_value->value = DeserializeValueFromPb(pb_config_value.value(), src_pool, config,
&out_table->string_pool, files, out_error);
-
if (config_value->value == nullptr) {
return false;
}
@@ -896,6 +894,9 @@
LOG(FATAL) << "unknown compound value: " << (int)pb_compound_value.value_case();
break;
}
+ value->SetFlagStatus((FlagStatus)pb_compound_value.flag_status());
+ value->SetFlag(FeatureFlagAttribute{.name = pb_compound_value.flag_name(),
+ .negated = pb_compound_value.flag_negated()});
} else {
LOG(FATAL) << "unknown value: " << (int)pb_value.value_case();
return {};
@@ -1052,10 +1053,8 @@
if (item) {
item->SetFlagStatus((FlagStatus)pb_item.flag_status());
if (!pb_item.flag_name().empty()) {
- FeatureFlagAttribute flag;
- flag.name = pb_item.flag_name();
- flag.negated = pb_item.flag_negated();
- item->SetFlag(std::move(flag));
+ item->SetFlag(
+ FeatureFlagAttribute{.name = pb_item.flag_name(), .negated = pb_item.flag_negated()});
}
}
return item;
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index d83fe91..fcc77d5 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -734,6 +734,13 @@
out_value->mutable_item()->set_flag_negated(flag->negated);
out_value->mutable_item()->set_flag_name(flag->name);
}
+ } else if (out_value->has_compound_value()) {
+ out_value->mutable_compound_value()->set_flag_status((uint32_t)value.GetFlagStatus());
+ if (value.GetFlag()) {
+ const auto& flag = value.GetFlag();
+ out_value->mutable_compound_value()->set_flag_negated(flag->negated);
+ out_value->mutable_compound_value()->set_flag_name(flag->name);
+ }
}
}
diff --git a/tools/aapt2/integration-tests/FlaggedResourcesTest/Android.bp b/tools/aapt2/integration-tests/FlaggedResourcesTest/Android.bp
index 7160b35..1b0f997 100644
--- a/tools/aapt2/integration-tests/FlaggedResourcesTest/Android.bp
+++ b/tools/aapt2/integration-tests/FlaggedResourcesTest/Android.bp
@@ -30,6 +30,7 @@
"res/values/bools2.xml",
"res/values/ints.xml",
"res/values/strings.xml",
+ "res/values/styles.xml",
"res/layout/layout1.xml",
"res/layout/layout3.xml",
"res/flag(test.package.falseFlag)/values/bools.xml",
@@ -50,6 +51,7 @@
"values_bools2.arsc.flat",
"values_ints.arsc.flat",
"values_strings.arsc.flat",
+ "values_styles.arsc.flat",
"layout_layout1.xml.flat",
"layout_layout2.(test.package.falseFlag).xml.flat",
"layout_layout3.xml.flat",
diff --git a/tools/aapt2/integration-tests/FlaggedResourcesTest/res/values/styles.xml b/tools/aapt2/integration-tests/FlaggedResourcesTest/res/values/styles.xml
new file mode 100644
index 0000000..604129c
--- /dev/null
+++ b/tools/aapt2/integration-tests/FlaggedResourcesTest/res/values/styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="style1">
+ <item name="android:windowIsTranslucent">true</item>
+ </style>
+ <style name="style1" android:featureFlag="test.package.falseFlag">
+ <item name="android:windowIsTranslucent">false</item>
+ </style>
+
+ <style name="style2">
+ <item name="android:windowIsTranslucent">false</item>
+ </style>
+ <style name="style2" android:featureFlag="test.package.trueFlag">
+ <item name="android:windowIsTranslucent">true</item>
+ </style>
+
+ <style name="style3">
+ <item name="android:windowIsTranslucent" android:featureFlag="!test.package.trueFlag">false</item>
+ <item name="android:windowIsTranslucent" android:featureFlag="test.package.trueFlag">true</item>
+ </style>
+</resources>
\ No newline at end of file