diff options
author | Ryan Mitchell <rtmitchell@google.com> | 2018-05-23 14:23:18 -0700 |
---|---|---|
committer | Ryan Mitchell <rtmitchell@google.com> | 2018-05-24 09:58:27 -0700 |
commit | 9a2f6e60c6a8aba61dadc66c20f13d00327dca46 (patch) | |
tree | eaff99a6c0e3e4db0e9a2f6da0af767038314b8d | |
parent | 5cfe061ed5644de4addbf43775963c5c5306ef20 (diff) |
AAPT2: Add Proguard rules for nav fragments
Adds generation of proguard rules for fragments in res/navigation. All
android:name attributes have keep rules generated for the classes they
reference.
Bug: 69929974
Test: aapt2_tests
Change-Id: I05a87484ab357ea5629b73caad8488182f474e1f
-rw-r--r-- | tools/aapt2/cmd/Link.cpp | 2 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules.cpp | 31 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules.h | 2 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules_test.cpp | 48 |
4 files changed, 70 insertions, 13 deletions
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index 74edf6e80364..ab2aab247cbf 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -500,7 +500,7 @@ std::vector<std::unique_ptr<xml::XmlResource>> ResourceFileFlattener::LinkAndVer return {}; } - if (options_.update_proguard_spec && !proguard::CollectProguardRules(doc, keep_set_)) { + if (options_.update_proguard_spec && !proguard::CollectProguardRules(context_, doc, keep_set_)) { return {}; } diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp index ffcef8966654..2857d5a2d90e 100644 --- a/tools/aapt2/java/ProguardRules.cpp +++ b/tools/aapt2/java/ProguardRules.cpp @@ -189,6 +189,29 @@ class XmlResourceVisitor : public BaseVisitor { DISALLOW_COPY_AND_ASSIGN(XmlResourceVisitor); }; +class NavigationVisitor : public BaseVisitor { + public: + NavigationVisitor(const ResourceFile& file, KeepSet* keep_set, const std::string& package) + : BaseVisitor(file, keep_set), package_(package) { + } + + void Visit(xml::Element* node) override { + const auto& attr = node->FindAttribute(xml::kSchemaAndroid, "name"); + if (attr != nullptr && !attr->value.empty()) { + std::string name = (attr->value[0] == '.') ? package_ + attr->value : attr->value; + if (util::IsJavaClassName(name)) { + AddClass(node->line_number, name); + } + } + + BaseVisitor::Visit(node); + } + + private: + DISALLOW_COPY_AND_ASSIGN(NavigationVisitor); + const std::string package_; +}; + class TransitionVisitor : public BaseVisitor { public: TransitionVisitor(const ResourceFile& file, KeepSet* keep_set) : BaseVisitor(file, keep_set) { @@ -291,7 +314,7 @@ bool CollectProguardRulesForManifest(xml::XmlResource* res, KeepSet* keep_set, b return false; } -bool CollectProguardRules(xml::XmlResource* res, KeepSet* keep_set) { +bool CollectProguardRules(IAaptContext* context_, xml::XmlResource* res, KeepSet* keep_set) { if (!res->root) { return false; } @@ -309,6 +332,12 @@ bool CollectProguardRules(xml::XmlResource* res, KeepSet* keep_set) { break; } + case ResourceType::kNavigation: { + NavigationVisitor visitor(res->file, keep_set, context_->GetCompilationPackage()); + res->root->Accept(&visitor); + break; + } + case ResourceType::kTransition: { TransitionVisitor visitor(res->file, keep_set); res->root->Accept(&visitor); diff --git a/tools/aapt2/java/ProguardRules.h b/tools/aapt2/java/ProguardRules.h index 46827ee7cf93..343272e4362a 100644 --- a/tools/aapt2/java/ProguardRules.h +++ b/tools/aapt2/java/ProguardRules.h @@ -79,7 +79,7 @@ class KeepSet { bool CollectProguardRulesForManifest(xml::XmlResource* res, KeepSet* keep_set, bool main_dex_only = false); -bool CollectProguardRules(xml::XmlResource* res, KeepSet* keep_set); +bool CollectProguardRules(IAaptContext* context, xml::XmlResource* res, KeepSet* keep_set); bool CollectResourceReferences(IAaptContext* context, ResourceTable* table, KeepSet* keep_set); diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp index 37d1a5fbaeb8..876c7a76d3f5 100644 --- a/tools/aapt2/java/ProguardRules_test.cpp +++ b/tools/aapt2/java/ProguardRules_test.cpp @@ -42,7 +42,7 @@ TEST(ProguardRulesTest, FragmentNameRuleIsEmitted) { layout->file.name = test::ParseNameOrDie("layout/foo"); proguard::KeepSet set; - ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); std::string actual = GetKeepSetString(set); @@ -56,7 +56,7 @@ TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) { layout->file.name = test::ParseNameOrDie("layout/foo"); proguard::KeepSet set; - ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); std::string actual = GetKeepSetString(set); @@ -72,7 +72,7 @@ TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { layout->file.name = test::ParseNameOrDie("layout/foo"); proguard::KeepSet set; - ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); std::string actual = GetKeepSetString(set); @@ -80,6 +80,34 @@ TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { EXPECT_THAT(actual, HasSubstr("com.foo.Baz")); } +TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .SetCompilationPackage("com.base").Build(); + std::unique_ptr<xml::XmlResource> navigation = test::BuildXmlDom(R"( + <navigation + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <custom android:id="@id/foo" + android:name="com.package.Foo"/> + <fragment android:id="@id/bar" + android:name="com.package.Bar"> + <nested android:id="@id/nested" + android:name=".Nested"/> + </fragment> + </navigation> + )"); + + navigation->file.name = test::ParseNameOrDie("navigation/graph.xml"); + + proguard::KeepSet set; + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), navigation.get(), &set)); + + std::string actual = GetKeepSetString(set); + EXPECT_THAT(actual, HasSubstr("com.package.Foo")); + EXPECT_THAT(actual, HasSubstr("com.package.Bar")); + EXPECT_THAT(actual, HasSubstr("com.base.Nested")); +} + TEST(ProguardRulesTest, CustomViewRulesAreEmitted) { std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"( @@ -89,7 +117,7 @@ TEST(ProguardRulesTest, CustomViewRulesAreEmitted) { layout->file.name = test::ParseNameOrDie("layout/foo"); proguard::KeepSet set; - ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); std::string actual = GetKeepSetString(set); @@ -125,8 +153,8 @@ TEST(ProguardRulesTest, IncludedLayoutRulesAreConditional) { ASSERT_TRUE(xml_linker.Consume(context.get(), foo_layout.get())); proguard::KeepSet set = proguard::KeepSet(true); - ASSERT_TRUE(proguard::CollectProguardRules(bar_layout.get(), &set)); - ASSERT_TRUE(proguard::CollectProguardRules(foo_layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), bar_layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), foo_layout.get(), &set)); std::string actual = GetKeepSetString(set); @@ -147,7 +175,7 @@ TEST(ProguardRulesTest, AliasedLayoutRulesAreConditional) { proguard::KeepSet set = proguard::KeepSet(true); set.AddReference({test::ParseNameOrDie("layout/bar"), {}}, layout->file.name); - ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); std::string actual = GetKeepSetString(set); @@ -168,7 +196,7 @@ TEST(ProguardRulesTest, NonLayoutReferencesAreUnconditional) { proguard::KeepSet set = proguard::KeepSet(true); set.AddReference({test::ParseNameOrDie("style/MyStyle"), {}}, layout->file.name); - ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); std::string actual = GetKeepSetString(set); @@ -184,7 +212,7 @@ TEST(ProguardRulesTest, ViewOnClickRuleIsEmitted) { layout->file.name = test::ParseNameOrDie("layout/foo"); proguard::KeepSet set; - ASSERT_TRUE(proguard::CollectProguardRules(layout.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set)); std::string actual = GetKeepSetString(set); @@ -203,7 +231,7 @@ TEST(ProguardRulesTest, MenuRulesAreEmitted) { menu->file.name = test::ParseNameOrDie("menu/foo"); proguard::KeepSet set; - ASSERT_TRUE(proguard::CollectProguardRules(menu.get(), &set)); + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), menu.get(), &set)); std::string actual = GetKeepSetString(set); |