Loading tools/aapt2/java/ProguardRules.cpp +39 −27 Original line number Diff line number Diff line Loading @@ -50,11 +50,11 @@ class BaseVisitor : public xml::Visitor { // This is a custom view, let's figure out the class name from this. std::string package = maybe_package.value().package + "." + node->name; if (util::IsJavaClassName(package)) { AddClass(node->line_number, package); AddClass(node->line_number, package, "..."); } } } else if (util::IsJavaClassName(node->name)) { AddClass(node->line_number, node->name); AddClass(node->line_number, node->name, "..."); } for (const auto& child : node->children) { Loading @@ -75,8 +75,10 @@ class BaseVisitor : public xml::Visitor { ResourceFile file_; KeepSet* keep_set_; virtual void AddClass(size_t line_number, const std::string& class_name) { keep_set_->AddConditionalClass({file_.name, file_.source.WithLine(line_number)}, class_name); virtual void AddClass(size_t line_number, const std::string& class_name, const std::string& ctor_signature) { keep_set_->AddConditionalClass({file_.name, file_.source.WithLine(line_number)}, {class_name, ctor_signature}); } void AddMethod(size_t line_number, const std::string& method_name, Loading Loading @@ -106,27 +108,33 @@ class LayoutVisitor : public BaseVisitor { } void Visit(xml::Element* node) override { bool check_class = false; bool check_name = false; bool is_view = false; bool is_fragment = false; if (node->namespace_uri.empty()) { if (node->name == "view") { check_class = true; is_view = true; } else if (node->name == "fragment") { check_class = check_name = true; is_fragment = true; } } else if (node->namespace_uri == xml::kSchemaAndroid) { check_name = node->name == "fragment"; is_fragment = node->name == "fragment"; } for (const auto& attr : node->attributes) { if (check_class && attr.namespace_uri.empty() && attr.name == "class" && util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value); } else if (check_name && attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name" && util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value); } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") { if (attr.namespace_uri.empty() && attr.name == "class") { if (util::IsJavaClassName(attr.value)) { if (is_view) { AddClass(node->line_number, attr.value, "android.content.Context, android.util.AttributeSet"); } else if (is_fragment) { AddClass(node->line_number, attr.value, ""); } } } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name") { if (is_fragment && util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value, ""); } } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") { AddMethod(node->line_number, attr.value, "android.view.View"); } } Loading @@ -149,7 +157,7 @@ class MenuVisitor : public BaseVisitor { if (attr.namespace_uri == xml::kSchemaAndroid) { if ((attr.name == "actionViewClass" || attr.name == "actionProviderClass") && util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value); AddClass(node->line_number, attr.value, "android.content.Context"); } else if (attr.name == "onClick") { AddMethod(node->line_number, attr.value, "android.view.MenuItem"); } Loading Loading @@ -180,7 +188,7 @@ class XmlResourceVisitor : public BaseVisitor { xml::Attribute* attr = node->FindAttribute(xml::kSchemaAndroid, "fragment"); if (attr && util::IsJavaClassName(attr->value)) { AddClass(node->line_number, attr->value); AddClass(node->line_number, attr->value, ""); } } Loading @@ -202,7 +210,7 @@ class NavigationVisitor : public BaseVisitor { 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); AddClass(node->line_number, name, "..."); } } Loading @@ -225,7 +233,8 @@ class TransitionVisitor : public BaseVisitor { if (check_class) { xml::Attribute* attr = node->FindAttribute({}, "class"); if (attr && util::IsJavaClassName(attr->value)) { AddClass(node->line_number, attr->value); AddClass(node->line_number, attr->value, "android.content.Context, android.util.AttributeSet"); } } Loading Loading @@ -256,14 +265,14 @@ class ManifestVisitor : public BaseVisitor { if (attr) { Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value); if (result) { AddClass(node->line_number, result.value()); AddClass(node->line_number, result.value(), ""); } } attr = node->FindAttribute(xml::kSchemaAndroid, "appComponentFactory"); if (attr) { Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value); if (result) { AddClass(node->line_number, result.value()); AddClass(node->line_number, result.value(), ""); } } if (main_dex_only_) { Loading Loading @@ -294,7 +303,7 @@ class ManifestVisitor : public BaseVisitor { if (get_name) { Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value); if (result) { AddClass(node->line_number, result.value()); AddClass(node->line_number, result.value(), ""); } } } Loading @@ -302,7 +311,8 @@ class ManifestVisitor : public BaseVisitor { BaseVisitor::Visit(node); } virtual void AddClass(size_t line_number, const std::string& class_name) override { virtual void AddClass(size_t line_number, const std::string& class_name, const std::string& ctor_signature) override { keep_set_->AddManifestClass({file_.name, file_.source.WithLine(line_number)}, class_name); } Loading Loading @@ -390,13 +400,15 @@ void WriteKeepSet(const KeepSet& keep_set, OutputStream* out) { printer.Print("-if class **.R$layout { int ") .Print(JavaClassGenerator::TransformToFieldName(location.name.entry)) .Println("; }"); printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }"); printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(") .Print(entry.first.signature).Println("); }"); } } else { for (const UsageLocation& location : entry.second) { printer.Print("# Referenced at ").Println(location.source.to_string()); } printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }"); printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(") .Print(entry.first.signature).Println("); }"); } printer.Println(); } Loading tools/aapt2/java/ProguardRules.h +4 −3 Original line number Diff line number Diff line Loading @@ -56,8 +56,9 @@ class KeepSet { manifest_class_set_[class_name].insert(file); } inline void AddConditionalClass(const UsageLocation& file, const std::string& class_name) { conditional_class_set_[class_name].insert(file); inline void AddConditionalClass(const UsageLocation& file, const NameAndSignature& class_and_signature) { conditional_class_set_[class_and_signature].insert(file); } inline void AddMethod(const UsageLocation& file, const NameAndSignature& name_and_signature) { Loading @@ -77,7 +78,7 @@ class KeepSet { bool conditional_keep_rules_ = false; std::map<std::string, std::set<UsageLocation>> manifest_class_set_; std::map<NameAndSignature, std::set<UsageLocation>> method_set_; std::map<std::string, std::set<UsageLocation>> conditional_class_set_; std::map<NameAndSignature, std::set<UsageLocation>> conditional_class_set_; std::map<ResourceName, std::set<UsageLocation>> reference_set_; }; Loading tools/aapt2/java/ProguardRules_test.cpp +10 −8 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ TEST(ProguardRulesTest, FragmentNameRuleIsEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); } TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) { Loading @@ -91,7 +91,7 @@ TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); } TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { Loading @@ -107,8 +107,8 @@ TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }")); } TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) { Loading Loading @@ -267,8 +267,8 @@ TEST(ProguardRulesTest, MenuRulesAreEmitted) { EXPECT_THAT(actual, HasSubstr( "-keepclassmembers class * { *** on_click(android.view.MenuItem); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(android.content.Context); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(android.content.Context); }")); EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat"))); } Loading @@ -285,7 +285,8 @@ TEST(ProguardRulesTest, TransitionPathMotionRulesAreEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr( "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }")); } TEST(ProguardRulesTest, TransitionRulesAreEmitted) { Loading @@ -301,7 +302,8 @@ TEST(ProguardRulesTest, TransitionRulesAreEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr( "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }")); } } // namespace aapt Loading
tools/aapt2/java/ProguardRules.cpp +39 −27 Original line number Diff line number Diff line Loading @@ -50,11 +50,11 @@ class BaseVisitor : public xml::Visitor { // This is a custom view, let's figure out the class name from this. std::string package = maybe_package.value().package + "." + node->name; if (util::IsJavaClassName(package)) { AddClass(node->line_number, package); AddClass(node->line_number, package, "..."); } } } else if (util::IsJavaClassName(node->name)) { AddClass(node->line_number, node->name); AddClass(node->line_number, node->name, "..."); } for (const auto& child : node->children) { Loading @@ -75,8 +75,10 @@ class BaseVisitor : public xml::Visitor { ResourceFile file_; KeepSet* keep_set_; virtual void AddClass(size_t line_number, const std::string& class_name) { keep_set_->AddConditionalClass({file_.name, file_.source.WithLine(line_number)}, class_name); virtual void AddClass(size_t line_number, const std::string& class_name, const std::string& ctor_signature) { keep_set_->AddConditionalClass({file_.name, file_.source.WithLine(line_number)}, {class_name, ctor_signature}); } void AddMethod(size_t line_number, const std::string& method_name, Loading Loading @@ -106,27 +108,33 @@ class LayoutVisitor : public BaseVisitor { } void Visit(xml::Element* node) override { bool check_class = false; bool check_name = false; bool is_view = false; bool is_fragment = false; if (node->namespace_uri.empty()) { if (node->name == "view") { check_class = true; is_view = true; } else if (node->name == "fragment") { check_class = check_name = true; is_fragment = true; } } else if (node->namespace_uri == xml::kSchemaAndroid) { check_name = node->name == "fragment"; is_fragment = node->name == "fragment"; } for (const auto& attr : node->attributes) { if (check_class && attr.namespace_uri.empty() && attr.name == "class" && util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value); } else if (check_name && attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name" && util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value); } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") { if (attr.namespace_uri.empty() && attr.name == "class") { if (util::IsJavaClassName(attr.value)) { if (is_view) { AddClass(node->line_number, attr.value, "android.content.Context, android.util.AttributeSet"); } else if (is_fragment) { AddClass(node->line_number, attr.value, ""); } } } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name") { if (is_fragment && util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value, ""); } } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") { AddMethod(node->line_number, attr.value, "android.view.View"); } } Loading @@ -149,7 +157,7 @@ class MenuVisitor : public BaseVisitor { if (attr.namespace_uri == xml::kSchemaAndroid) { if ((attr.name == "actionViewClass" || attr.name == "actionProviderClass") && util::IsJavaClassName(attr.value)) { AddClass(node->line_number, attr.value); AddClass(node->line_number, attr.value, "android.content.Context"); } else if (attr.name == "onClick") { AddMethod(node->line_number, attr.value, "android.view.MenuItem"); } Loading Loading @@ -180,7 +188,7 @@ class XmlResourceVisitor : public BaseVisitor { xml::Attribute* attr = node->FindAttribute(xml::kSchemaAndroid, "fragment"); if (attr && util::IsJavaClassName(attr->value)) { AddClass(node->line_number, attr->value); AddClass(node->line_number, attr->value, ""); } } Loading @@ -202,7 +210,7 @@ class NavigationVisitor : public BaseVisitor { 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); AddClass(node->line_number, name, "..."); } } Loading @@ -225,7 +233,8 @@ class TransitionVisitor : public BaseVisitor { if (check_class) { xml::Attribute* attr = node->FindAttribute({}, "class"); if (attr && util::IsJavaClassName(attr->value)) { AddClass(node->line_number, attr->value); AddClass(node->line_number, attr->value, "android.content.Context, android.util.AttributeSet"); } } Loading Loading @@ -256,14 +265,14 @@ class ManifestVisitor : public BaseVisitor { if (attr) { Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value); if (result) { AddClass(node->line_number, result.value()); AddClass(node->line_number, result.value(), ""); } } attr = node->FindAttribute(xml::kSchemaAndroid, "appComponentFactory"); if (attr) { Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value); if (result) { AddClass(node->line_number, result.value()); AddClass(node->line_number, result.value(), ""); } } if (main_dex_only_) { Loading Loading @@ -294,7 +303,7 @@ class ManifestVisitor : public BaseVisitor { if (get_name) { Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value); if (result) { AddClass(node->line_number, result.value()); AddClass(node->line_number, result.value(), ""); } } } Loading @@ -302,7 +311,8 @@ class ManifestVisitor : public BaseVisitor { BaseVisitor::Visit(node); } virtual void AddClass(size_t line_number, const std::string& class_name) override { virtual void AddClass(size_t line_number, const std::string& class_name, const std::string& ctor_signature) override { keep_set_->AddManifestClass({file_.name, file_.source.WithLine(line_number)}, class_name); } Loading Loading @@ -390,13 +400,15 @@ void WriteKeepSet(const KeepSet& keep_set, OutputStream* out) { printer.Print("-if class **.R$layout { int ") .Print(JavaClassGenerator::TransformToFieldName(location.name.entry)) .Println("; }"); printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }"); printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(") .Print(entry.first.signature).Println("); }"); } } else { for (const UsageLocation& location : entry.second) { printer.Print("# Referenced at ").Println(location.source.to_string()); } printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }"); printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(") .Print(entry.first.signature).Println("); }"); } printer.Println(); } Loading
tools/aapt2/java/ProguardRules.h +4 −3 Original line number Diff line number Diff line Loading @@ -56,8 +56,9 @@ class KeepSet { manifest_class_set_[class_name].insert(file); } inline void AddConditionalClass(const UsageLocation& file, const std::string& class_name) { conditional_class_set_[class_name].insert(file); inline void AddConditionalClass(const UsageLocation& file, const NameAndSignature& class_and_signature) { conditional_class_set_[class_and_signature].insert(file); } inline void AddMethod(const UsageLocation& file, const NameAndSignature& name_and_signature) { Loading @@ -77,7 +78,7 @@ class KeepSet { bool conditional_keep_rules_ = false; std::map<std::string, std::set<UsageLocation>> manifest_class_set_; std::map<NameAndSignature, std::set<UsageLocation>> method_set_; std::map<std::string, std::set<UsageLocation>> conditional_class_set_; std::map<NameAndSignature, std::set<UsageLocation>> conditional_class_set_; std::map<ResourceName, std::set<UsageLocation>> reference_set_; }; Loading
tools/aapt2/java/ProguardRules_test.cpp +10 −8 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ TEST(ProguardRulesTest, FragmentNameRuleIsEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); } TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) { Loading @@ -91,7 +91,7 @@ TEST(ProguardRulesTest, FragmentClassRuleIsEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); } TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { Loading @@ -107,8 +107,8 @@ TEST(ProguardRulesTest, FragmentNameAndClassRulesAreEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }")); } TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) { Loading Loading @@ -267,8 +267,8 @@ TEST(ProguardRulesTest, MenuRulesAreEmitted) { EXPECT_THAT(actual, HasSubstr( "-keepclassmembers class * { *** on_click(android.view.MenuItem); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(android.content.Context); }")); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(android.content.Context); }")); EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat"))); } Loading @@ -285,7 +285,8 @@ TEST(ProguardRulesTest, TransitionPathMotionRulesAreEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr( "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }")); } TEST(ProguardRulesTest, TransitionRulesAreEmitted) { Loading @@ -301,7 +302,8 @@ TEST(ProguardRulesTest, TransitionRulesAreEmitted) { std::string actual = GetKeepSetString(set); EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }")); EXPECT_THAT(actual, HasSubstr( "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }")); } } // namespace aapt