diff options
Diffstat (limited to 'tools/aapt2/java')
-rw-r--r-- | tools/aapt2/java/JavaClassGenerator.cpp | 17 | ||||
-rw-r--r-- | tools/aapt2/java/JavaClassGenerator_test.cpp | 12 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules.cpp | 46 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules.h | 6 | ||||
-rw-r--r-- | tools/aapt2/java/ProguardRules_test.cpp | 21 |
5 files changed, 74 insertions, 28 deletions
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp index 31d205e1b9c9..bb541fe2490b 100644 --- a/tools/aapt2/java/JavaClassGenerator.cpp +++ b/tools/aapt2/java/JavaClassGenerator.cpp @@ -304,9 +304,11 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res auto documentation_remove_iter = std::remove_if(documentation_attrs.begin(), documentation_attrs.end(), [&](StyleableAttr entry) -> bool { - StringPiece attr_comment_line = entry.symbol.value().attribute->GetComment(); - return SkipSymbol(entry.symbol) || attr_comment_line.contains("@removed") - || attr_comment_line.contains("@hide"); + if (SkipSymbol(entry.symbol)) { + return true; + } + const StringPiece attr_comment_line = entry.symbol.value().attribute->GetComment(); + return attr_comment_line.contains("@removed") || attr_comment_line.contains("@hide"); }); documentation_attrs.erase(documentation_remove_iter, documentation_attrs.end()); @@ -428,7 +430,7 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res out_rewrite_method->AppendStatement( StringPrintf(" if ((styleable.%s[i] & 0xff000000) == 0) {", array_field_name.data())); out_rewrite_method->AppendStatement( - StringPrintf(" styleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (p << 24);", + StringPrintf(" styleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | packageIdBits;", array_field_name.data(), array_field_name.data())); out_rewrite_method->AppendStatement(" }"); out_rewrite_method->AppendStatement("}"); @@ -487,9 +489,9 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso if (out_rewrite_method != nullptr) { const StringPiece& type_str = to_string(name.type); - out_rewrite_method->AppendStatement(StringPrintf("%s.%s = (%s.%s & 0x00ffffff) | (p << 24);", - type_str.data(), field_name.data(), - type_str.data(), field_name.data())); + out_rewrite_method->AppendStatement( + StringPrintf("%s.%s = (%s.%s & 0x00ffffff) | packageIdBits;", type_str.data(), + field_name.data(), type_str.data(), field_name.data())); } } @@ -599,6 +601,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, rewrite_method->AppendStatement( StringPrintf("%s.R.onResourcesLoaded(p);", package_to_callback.data())); } + rewrite_method->AppendStatement("final int packageIdBits = p << 24;"); } for (const auto& package : table_->packages) { diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp index 4f51fc48c80e..1e1fe4740c6b 100644 --- a/tools/aapt2/java/JavaClassGenerator_test.cpp +++ b/tools/aapt2/java/JavaClassGenerator_test.cpp @@ -522,9 +522,15 @@ TEST(JavaClassGeneratorTest, GenerateOnResourcesLoadedCallbackForSharedLibrary) ASSERT_TRUE(generator.Generate("android", &out)); out.Flush(); - EXPECT_THAT(output, HasSubstr("void onResourcesLoaded")); - EXPECT_THAT(output, HasSubstr("com.foo.R.onResourcesLoaded")); - EXPECT_THAT(output, HasSubstr("com.boo.R.onResourcesLoaded")); + EXPECT_THAT(output, HasSubstr( + R"( public static void onResourcesLoaded(int p) { + com.foo.R.onResourcesLoaded(p); + com.boo.R.onResourcesLoaded(p); + final int packageIdBits = p << 24; + attr.foo = (attr.foo & 0x00ffffff) | packageIdBits; + id.foo = (id.foo & 0x00ffffff) | packageIdBits; + style.foo = (style.foo & 0x00ffffff) | packageIdBits; + })")); } TEST(JavaClassGeneratorTest, OnlyGenerateRText) { diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp index 806f4e37e22a..0db1807c75d9 100644 --- a/tools/aapt2/java/ProguardRules.cpp +++ b/tools/aapt2/java/ProguardRules.cpp @@ -160,13 +160,19 @@ class MenuVisitor : public BaseVisitor { void Visit(xml::Element* node) override { if (node->namespace_uri.empty() && node->name == "item") { for (const auto& attr : node->attributes) { - if (attr.namespace_uri == xml::kSchemaAndroid) { - if ((attr.name == "actionViewClass" || attr.name == "actionProviderClass") && - util::IsJavaClassName(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"); - } + // AppCompat-v7 defines its own versions of Android attributes if + // they're defined after SDK 7 (the below are from 11 and 14, + // respectively), so don't bother checking the XML namespace. + // + // Given the names of the containing XML files and the attribute + // names, it's unlikely that keeping these classes would be wrong. + if ((attr.name == "actionViewClass" || attr.name == "actionProviderClass") && + util::IsJavaClassName(attr.value)) { + AddClass(node->line_number, attr.value, "android.content.Context"); + } + + if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") { + AddMethod(node->line_number, attr.value, "android.view.MenuItem"); } } } @@ -393,11 +399,15 @@ bool CollectProguardRules(IAaptContext* context_, xml::XmlResource* res, KeepSet return true; } -void WriteKeepSet(const KeepSet& keep_set, OutputStream* out, bool minimal_keep) { +void WriteKeepSet(const KeepSet& keep_set, OutputStream* out, bool minimal_keep, + bool no_location_reference) { + Printer printer(out); for (const auto& entry : keep_set.manifest_class_set_) { - for (const UsageLocation& location : entry.second) { - printer.Print("# Referenced at ").Println(location.source.to_string()); + if (!no_location_reference) { + for (const UsageLocation& location : entry.second) { + printer.Print("# Referenced at ").Println(location.source.to_string()); + } } printer.Print("-keep class ").Print(entry.first).Println(" { <init>(); }"); } @@ -414,7 +424,9 @@ void WriteKeepSet(const KeepSet& keep_set, OutputStream* out, bool minimal_keep) if (can_be_conditional) { for (const UsageLocation& location : locations) { - printer.Print("# Referenced at ").Println(location.source.to_string()); + if (!no_location_reference) { + printer.Print("# Referenced at ").Println(location.source.to_string()); + } printer.Print("-if class **.R$layout { int ") .Print(JavaClassGenerator::TransformToFieldName(location.name.entry)) .Println("; }"); @@ -424,8 +436,10 @@ void WriteKeepSet(const KeepSet& keep_set, OutputStream* out, bool minimal_keep) printer.Println("); }"); } } else { - for (const UsageLocation& location : entry.second) { - printer.Print("# Referenced at ").Println(location.source.to_string()); + if (!no_location_reference) { + for (const UsageLocation& location : entry.second) { + printer.Print("# Referenced at ").Println(location.source.to_string()); + } } printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>("); @@ -436,8 +450,10 @@ void WriteKeepSet(const KeepSet& keep_set, OutputStream* out, bool minimal_keep) } for (const auto& entry : keep_set.method_set_) { - for (const UsageLocation& location : entry.second) { - printer.Print("# Referenced at ").Println(location.source.to_string()); + if (!no_location_reference) { + for (const UsageLocation& location : entry.second) { + printer.Print("# Referenced at ").Println(location.source.to_string()); + } } printer.Print("-keepclassmembers class * { *** ").Print(entry.first.name) .Print("(").Print(entry.first.signature).Println("); }"); diff --git a/tools/aapt2/java/ProguardRules.h b/tools/aapt2/java/ProguardRules.h index b15df59f56a6..a01b64d024d2 100644 --- a/tools/aapt2/java/ProguardRules.h +++ b/tools/aapt2/java/ProguardRules.h @@ -70,7 +70,8 @@ class KeepSet { } private: - friend void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out, bool minimal_keep); + friend void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out, bool minimal_keep, + bool no_location_reference); friend bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set, std::set<UsageLocation>* locations); @@ -89,7 +90,8 @@ bool CollectProguardRules(IAaptContext* context, xml::XmlResource* res, KeepSet* bool CollectResourceReferences(IAaptContext* context, ResourceTable* table, KeepSet* keep_set); -void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out, bool minimal_keep); +void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out, bool minimal_keep, + bool no_location_reference); bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set, std::set<UsageLocation>* locations); diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp index 25b55ab003b0..b6e76021ccc1 100644 --- a/tools/aapt2/java/ProguardRules_test.cpp +++ b/tools/aapt2/java/ProguardRules_test.cpp @@ -30,7 +30,7 @@ namespace aapt { std::string GetKeepSetString(const proguard::KeepSet& set, bool minimal_rules) { std::string out; StringOutputStream sout(&out); - proguard::WriteKeepSet(set, &sout, minimal_rules); + proguard::WriteKeepSet(set, &sout, minimal_rules, false); sout.Flush(); return out; } @@ -326,6 +326,25 @@ TEST(ProguardRulesTest, MenuRulesAreEmitted) { EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat"))); } +TEST(ProguardRulesTest, MenuRulesAreEmittedForActionClasses) { + std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); + std::unique_ptr<xml::XmlResource> menu = test::BuildXmlDom(R"( + <menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item android:id="@+id/my_item" + app:actionViewClass="com.foo.Bar" + app:actionProviderClass="com.foo.Baz" /> + </menu>)"); + menu->file.name = test::ParseNameOrDie("menu/foo"); + + proguard::KeepSet set; + ASSERT_TRUE(proguard::CollectProguardRules(context.get(), menu.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")); +} + TEST(ProguardRulesTest, TransitionPathMotionRulesAreEmitted) { std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build(); std::unique_ptr<xml::XmlResource> transition = test::BuildXmlDom(R"( |