First pass at flagged resources
This gets the main parts of resource flagging in place and the basic use
case of flagging with an xml attribute working.
Test: Automated
Bug: 329436914
Flag: EXEMPT Aconfig not supported on host tools
Change-Id: Id2b5ba450d05da00a922e98ca204b6e5aa6c6c24
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index a3b0b45..1cdb715 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -231,6 +231,47 @@
return false;
}
+ResourceTable::CollisionResult ResourceTable::ResolveFlagCollision(FlagStatus existing,
+ FlagStatus incoming) {
+ switch (existing) {
+ case FlagStatus::NoFlag:
+ switch (incoming) {
+ case FlagStatus::NoFlag:
+ return CollisionResult::kConflict;
+ case FlagStatus::Disabled:
+ return CollisionResult::kKeepOriginal;
+ case FlagStatus::Enabled:
+ return CollisionResult::kTakeNew;
+ default:
+ return CollisionResult::kConflict;
+ }
+ case FlagStatus::Disabled:
+ switch (incoming) {
+ case FlagStatus::NoFlag:
+ return CollisionResult::kTakeNew;
+ case FlagStatus::Disabled:
+ return CollisionResult::kKeepOriginal;
+ case FlagStatus::Enabled:
+ return CollisionResult::kTakeNew;
+ default:
+ return CollisionResult::kConflict;
+ }
+ case FlagStatus::Enabled:
+ switch (incoming) {
+ case FlagStatus::NoFlag:
+ return CollisionResult::kKeepOriginal;
+ case FlagStatus::Disabled:
+ return CollisionResult::kKeepOriginal;
+ case FlagStatus::Enabled:
+ return CollisionResult::kConflict;
+ default:
+ return CollisionResult::kConflict;
+ }
+ default:
+ return CollisionResult::kConflict;
+ }
+}
+
// The default handler for collisions.
//
// Typically, a weak value will be overridden by a strong value. An existing weak
@@ -564,16 +605,21 @@
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.
- auto result = validate ? ResolveValueCollision(config_value->value.get(), res.value.get())
+ // the same configuration unless protected by flags.
+ auto result = validate ? ResolveFlagCollision(config_value->flag_status, res.flag_status)
: CollisionResult::kKeepBoth;
+ if (result == CollisionResult::kConflict) {
+ result = ResolveValueCollision(config_value->value.get(), res.value.get());
+ }
switch (result) {
case CollisionResult::kKeepBoth:
// 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:
@@ -735,6 +781,11 @@
return *this;
}
+NewResourceBuilder& NewResourceBuilder::SetFlagStatus(FlagStatus flag_status) {
+ res_.flag_status = flag_status;
+ return *this;
+}
+
NewResource NewResourceBuilder::Build() {
return std::move(res_);
}