diff options
Diffstat (limited to 'tools/aapt2/java/ProguardRules.cpp')
-rw-r--r-- | tools/aapt2/java/ProguardRules.cpp | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp index 92487f4e6854..63f9dd327c0b 100644 --- a/tools/aapt2/java/ProguardRules.cpp +++ b/tools/aapt2/java/ProguardRules.cpp @@ -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) { @@ -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, @@ -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"); } } @@ -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"); } @@ -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, ""); } } @@ -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, "..."); } } @@ -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"); } } @@ -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_) { @@ -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(), ""); } } } @@ -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); } @@ -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(); } |