Loading tools/aapt2/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ cc_library_host_static { "io/ZipArchive.cpp", "link/AutoVersioner.cpp", "link/FeatureFlagsFilter.cpp", "link/FlaggedXmlVersioner.cpp", "link/FlagDisabledResourceRemover.cpp", "link/ManifestFixer.cpp", "link/NoDefaultResourceRemover.cpp", Loading tools/aapt2/ResourceParser.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -547,7 +547,8 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, }); std::string_view resource_type = parser->element_name(); if (auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag"))) { if (auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, xml::kAttrFeatureFlag))) { 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"); Loading Loading @@ -1529,7 +1530,7 @@ bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) { ResolvePackage(parser, &maybe_key.value()); maybe_key.value().SetSource(source); auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag")); auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, xml::kAttrFeatureFlag)); std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString); if (!value) { Loading Loading @@ -1674,7 +1675,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 = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag")); auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, xml::kAttrFeatureFlag)); std::unique_ptr<Item> item = ParseXml(parser, typeMask, kNoRawString); if (!item) { diag_->Error(android::DiagMessage(item_source) << "could not parse array item"); Loading tools/aapt2/cmd/Link.cpp +11 −1 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ #include "java/ProguardRules.h" #include "link/FeatureFlagsFilter.h" #include "link/FlagDisabledResourceRemover.h" #include "link/FlaggedXmlVersioner.h" #include "link/Linkers.h" #include "link/ManifestFixer.h" #include "link/NoDefaultResourceRemover.h" Loading Loading @@ -503,10 +504,19 @@ std::vector<std::unique_ptr<xml::XmlResource>> ResourceFileFlattener::LinkAndVer const ConfigDescription& config = file_op->config; ResourceEntry* entry = file_op->entry; FlaggedXmlVersioner flagged_xml_versioner; auto flag_split_resources = flagged_xml_versioner.Process(context_, doc); std::vector<std::unique_ptr<xml::XmlResource>> final_resources; XmlCompatVersioner xml_compat_versioner(&rules_); const util::Range<ApiVersion> api_range{config.sdkVersion, FindNextApiVersionForConfig(entry, config)}; return xml_compat_versioner.Process(context_, doc, api_range); for (auto& split_res : flag_split_resources) { auto inner_resources = xml_compat_versioner.Process(context_, split_res.get(), api_range); final_resources.insert(final_resources.end(), std::make_move_iterator(inner_resources.begin()), std::make_move_iterator(inner_resources.end())); } return final_resources; } ResourceFile::Type XmlFileTypeForOutputFormat(OutputFormat format) { Loading tools/aapt2/link/FeatureFlagsFilter.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ class FlagsVisitor : public xml::Visitor { private: bool ShouldRemove(std::unique_ptr<xml::Node>& node) { if (auto* el = NodeCast<Element>(node.get())) { auto* attr = el->FindAttribute(xml::kSchemaAndroid, "featureFlag"); auto* attr = el->FindAttribute(xml::kSchemaAndroid, xml::kAttrFeatureFlag); if (attr == nullptr) { return false; } Loading @@ -76,7 +76,7 @@ class FlagsVisitor : public xml::Visitor { // Remove if flag==true && attr=="!flag" (negated) OR flag==false && attr=="flag" bool remove = *it->second.enabled == negated; if (!remove) { el->RemoveAttribute(xml::kSchemaAndroid, "featureFlag"); el->RemoveAttribute(xml::kSchemaAndroid, xml::kAttrFeatureFlag); } return remove; } Loading tools/aapt2/link/FlaggedResources_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ TEST_F(FlaggedResourcesTest, EnabledXmlELementAttributeRemoved) { auto loaded_apk = LoadedApk::LoadApkFromPath(apk_path, &noop_diag); std::string output; DumpXmlTreeToString(loaded_apk.get(), "res/layout-v22/layout1.xml", &output); DumpXmlTreeToString(loaded_apk.get(), "res/layout-v36/layout1.xml", &output); ASSERT_FALSE(output.contains("test.package.trueFlag")); ASSERT_TRUE(output.contains("FIND_ME")); ASSERT_TRUE(output.contains("test.package.readWriteFlag")); Loading Loading
tools/aapt2/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,7 @@ cc_library_host_static { "io/ZipArchive.cpp", "link/AutoVersioner.cpp", "link/FeatureFlagsFilter.cpp", "link/FlaggedXmlVersioner.cpp", "link/FlagDisabledResourceRemover.cpp", "link/ManifestFixer.cpp", "link/NoDefaultResourceRemover.cpp", Loading
tools/aapt2/ResourceParser.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -547,7 +547,8 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser, }); std::string_view resource_type = parser->element_name(); if (auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag"))) { if (auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, xml::kAttrFeatureFlag))) { 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"); Loading Loading @@ -1529,7 +1530,7 @@ bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) { ResolvePackage(parser, &maybe_key.value()); maybe_key.value().SetSource(source); auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag")); auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, xml::kAttrFeatureFlag)); std::unique_ptr<Item> value = ParseXml(parser, 0, kAllowRawString); if (!value) { Loading Loading @@ -1674,7 +1675,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 = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, "featureFlag")); auto flag = ParseFlag(xml::FindAttribute(parser, xml::kSchemaAndroid, xml::kAttrFeatureFlag)); std::unique_ptr<Item> item = ParseXml(parser, typeMask, kNoRawString); if (!item) { diag_->Error(android::DiagMessage(item_source) << "could not parse array item"); Loading
tools/aapt2/cmd/Link.cpp +11 −1 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ #include "java/ProguardRules.h" #include "link/FeatureFlagsFilter.h" #include "link/FlagDisabledResourceRemover.h" #include "link/FlaggedXmlVersioner.h" #include "link/Linkers.h" #include "link/ManifestFixer.h" #include "link/NoDefaultResourceRemover.h" Loading Loading @@ -503,10 +504,19 @@ std::vector<std::unique_ptr<xml::XmlResource>> ResourceFileFlattener::LinkAndVer const ConfigDescription& config = file_op->config; ResourceEntry* entry = file_op->entry; FlaggedXmlVersioner flagged_xml_versioner; auto flag_split_resources = flagged_xml_versioner.Process(context_, doc); std::vector<std::unique_ptr<xml::XmlResource>> final_resources; XmlCompatVersioner xml_compat_versioner(&rules_); const util::Range<ApiVersion> api_range{config.sdkVersion, FindNextApiVersionForConfig(entry, config)}; return xml_compat_versioner.Process(context_, doc, api_range); for (auto& split_res : flag_split_resources) { auto inner_resources = xml_compat_versioner.Process(context_, split_res.get(), api_range); final_resources.insert(final_resources.end(), std::make_move_iterator(inner_resources.begin()), std::make_move_iterator(inner_resources.end())); } return final_resources; } ResourceFile::Type XmlFileTypeForOutputFormat(OutputFormat format) { Loading
tools/aapt2/link/FeatureFlagsFilter.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ class FlagsVisitor : public xml::Visitor { private: bool ShouldRemove(std::unique_ptr<xml::Node>& node) { if (auto* el = NodeCast<Element>(node.get())) { auto* attr = el->FindAttribute(xml::kSchemaAndroid, "featureFlag"); auto* attr = el->FindAttribute(xml::kSchemaAndroid, xml::kAttrFeatureFlag); if (attr == nullptr) { return false; } Loading @@ -76,7 +76,7 @@ class FlagsVisitor : public xml::Visitor { // Remove if flag==true && attr=="!flag" (negated) OR flag==false && attr=="flag" bool remove = *it->second.enabled == negated; if (!remove) { el->RemoveAttribute(xml::kSchemaAndroid, "featureFlag"); el->RemoveAttribute(xml::kSchemaAndroid, xml::kAttrFeatureFlag); } return remove; } Loading
tools/aapt2/link/FlaggedResources_test.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -163,7 +163,7 @@ TEST_F(FlaggedResourcesTest, EnabledXmlELementAttributeRemoved) { auto loaded_apk = LoadedApk::LoadApkFromPath(apk_path, &noop_diag); std::string output; DumpXmlTreeToString(loaded_apk.get(), "res/layout-v22/layout1.xml", &output); DumpXmlTreeToString(loaded_apk.get(), "res/layout-v36/layout1.xml", &output); ASSERT_FALSE(output.contains("test.package.trueFlag")); ASSERT_TRUE(output.contains("FIND_ME")); ASSERT_TRUE(output.contains("test.package.readWriteFlag")); Loading