summaryrefslogtreecommitdiff
path: root/tools/aapt2/java
diff options
context:
space:
mode:
authorJake Wharton <jakew@google.com>2018-06-11 15:46:03 -0400
committerJake Wharton <jakew@google.com>2018-07-20 10:44:11 -0400
commit98100c382890b1b935a17265bc6cb1be3bf69640 (patch)
tree39fc1c157fb7f2be242dfb1918e271ba90752783 /tools/aapt2/java
parent55f098118c3b4be381d48a94817b923e58b72b21 (diff)
Only keep methods with correct signature for more types
- For transition and pathMotion attributes the method must have Context and AttributeSet parameters. - For actionViewClass and actionProviderClass attributes the constructor must have a single Context parameter. - For Fragment's class or name attributes the constructor must have zero parameters. Bug: 37123156 Test: make aapt2_tests Change-Id: I34017abd182867ba95172835051d114cb2f3b3ac
Diffstat (limited to 'tools/aapt2/java')
-rw-r--r--tools/aapt2/java/ProguardRules.cpp66
-rw-r--r--tools/aapt2/java/ProguardRules.h7
-rw-r--r--tools/aapt2/java/ProguardRules_test.cpp18
3 files changed, 53 insertions, 38 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();
}
diff --git a/tools/aapt2/java/ProguardRules.h b/tools/aapt2/java/ProguardRules.h
index acaceac41237..01dad0b08aea 100644
--- a/tools/aapt2/java/ProguardRules.h
+++ b/tools/aapt2/java/ProguardRules.h
@@ -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) {
@@ -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_;
};
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
index aeb9eb6e91c4..a41a8ca3394a 100644
--- a/tools/aapt2/java/ProguardRules_test.cpp
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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")));
}
@@ -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) {
@@ -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