From 4bdc698d9f8fb4f85464d554cabeb954104ec0a3 Mon Sep 17 00:00:00 2001 From: Jeremy Woods Date: Fri, 28 Feb 2020 19:42:38 -0800 Subject: [PATCH] Generate "keep" rules for android:name and class attributes We should keep classes that are in the android:name or class xml attributes. Test: m -j aapt2_tests Bug: 142601969 Change-Id: Ia67365bd702bae75d38b9572d68e9930e856e0f8 --- tools/aapt2/java/ProguardRules.cpp | 9 +--- tools/aapt2/java/ProguardRules_test.cpp | 55 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp index 806f4e37e22ac..ff7f5c12404c9 100644 --- a/tools/aapt2/java/ProguardRules.cpp +++ b/tools/aapt2/java/ProguardRules.cpp @@ -115,15 +115,10 @@ class LayoutVisitor : public BaseVisitor { void Visit(xml::Element* node) override { bool is_view = false; - bool is_fragment = false; if (node->namespace_uri.empty()) { if (node->name == "view") { is_view = true; - } else if (node->name == "fragment") { - is_fragment = true; } - } else if (node->namespace_uri == xml::kSchemaAndroid) { - is_fragment = node->name == "fragment"; } for (const auto& attr : node->attributes) { @@ -132,12 +127,12 @@ class LayoutVisitor : public BaseVisitor { if (is_view) { AddClass(node->line_number, attr.value, "android.content.Context, android.util.AttributeSet"); - } else if (is_fragment) { + } else { AddClass(node->line_number, attr.value, ""); } } } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name") { - if (is_fragment && util::IsJavaClassName(attr.value)) { + if (util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value, ""); } } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") { diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp index 25b55ab003b00..7c3cda089b404 100644 --- a/tools/aapt2/java/ProguardRules_test.cpp +++ b/tools/aapt2/java/ProguardRules_test.cpp @@ -131,6 +131,61 @@ TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { (); }")); } +TEST(ProguardRulesTest, FragmentContainerViewNameRuleIsEmitted) { + std::unique_ptr context = test::ContextBuilder().Build(); + std::unique_ptr layout = test::BuildXmlDom(R"( + )"); + layout->file.name = test::ParseNameOrDie("layout/foo"); + + proguard::KeepSet set; + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); + + std::string actual = GetKeepSetString(set, /** minimal_rules */ false); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { (...); }")); + + actual = GetKeepSetString(set, /** minimal_rules */ true); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { (); }")); +} + +TEST(ProguardRulesTest, FragmentContainerViewClassRuleIsEmitted) { + std::unique_ptr context = test::ContextBuilder().Build(); + std::unique_ptr layout = + test::BuildXmlDom(R"()"); + layout->file.name = test::ParseNameOrDie("layout/foo"); + + proguard::KeepSet set; + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); + + std::string actual = GetKeepSetString(set, /** minimal_rules */ false); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { (...); }")); + + actual = GetKeepSetString(set, /** minimal_rules */ true); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { (); }")); +} + +TEST(ProguardRulesTest, FragmentContainerViewNameAndClassRulesAreEmitted) { + std::unique_ptr context = test::ContextBuilder().Build(); + std::unique_ptr layout = test::BuildXmlDom(R"( + )"); + layout->file.name = test::ParseNameOrDie("layout/foo"); + + proguard::KeepSet set; + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); + + std::string actual = GetKeepSetString(set, /** minimal_rules */ false); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { (...); }")); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { (...); }")); + + actual = GetKeepSetString(set, /** minimal_rules */ true); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { (); }")); + EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { (); }")); +} + TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) { std::unique_ptr context = test::ContextBuilder() .SetCompilationPackage("com.base").Build();