summaryrefslogtreecommitdiff
path: root/tools/aapt2/ResourceParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/ResourceParser.cpp')
-rw-r--r--tools/aapt2/ResourceParser.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 6af39b739e9b..a5aecc855707 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#include "ResourceParser.h"
#include <functional>
@@ -108,6 +107,7 @@ struct ParsedResource {
Visibility::Level visibility_level = Visibility::Level::kUndefined;
bool staged_api = false;
bool allow_new = false;
+ FlagStatus flag_status = FlagStatus::NoFlag;
std::optional<OverlayableItem> overlayable_item;
std::optional<StagedId> staged_alias;
@@ -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));
@@ -161,6 +162,8 @@ static bool AddResourcesToTable(ResourceTable* table, android::IDiagnostics* dia
res_builder.SetStagedId(res->staged_alias.value());
}
+ res_builder.SetFlagStatus(res->flag_status);
+
bool error = false;
if (!res->name.entry.empty()) {
if (!table->AddResource(res_builder.Build(), diag)) {
@@ -544,6 +547,11 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
});
std::string resource_type = parser->element_name();
+ auto flag_status = GetFlagStatus(parser);
+ if (!flag_status) {
+ return false;
+ }
+ out_resource->flag_status = flag_status.value();
// The value format accepted for this resource.
uint32_t resource_format = 0u;
@@ -725,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) {
@@ -1631,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));