Generate "keep" rules for android:name and class attributes

We should keep classes that are in the android:name or class xml
attributes.

Test: m -j aapt2_tests
Bug: 142601969
Change-Id: Ia67365bd702bae75d38b9572d68e9930e856e0f8
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index 806f4e3..ff7f5c1 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -115,15 +115,10 @@
 
   void Visit(xml::Element* node) override {
     bool is_view = false;
-    bool is_fragment = false;
     if (node->namespace_uri.empty()) {
       if (node->name == "view") {
         is_view = true;
-      } else if (node->name == "fragment") {
-        is_fragment = true;
       }
-    } else if (node->namespace_uri == xml::kSchemaAndroid) {
-      is_fragment = node->name == "fragment";
     }
 
     for (const auto& attr : node->attributes) {
@@ -132,12 +127,12 @@
           if (is_view) {
             AddClass(node->line_number, attr.value,
                 "android.content.Context, android.util.AttributeSet");
-          } else if (is_fragment) {
+          } else {
             AddClass(node->line_number, attr.value, "");
           }
         }
       } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "name") {
-        if (is_fragment && util::IsJavaClassName(attr.value)) {
+        if (util::IsJavaClassName(attr.value)) {
           AddClass(node->line_number, attr.value, "");
         }
       } else if (attr.namespace_uri == xml::kSchemaAndroid && attr.name == "onClick") {
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
index 25b55ab..7c3cda0 100644
--- a/tools/aapt2/java/ProguardRules_test.cpp
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -131,6 +131,61 @@
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }"));
 }
 
+TEST(ProguardRulesTest, FragmentContainerViewNameRuleIsEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"(
+      <androidx.fragment.app.FragmentContainerView
+          xmlns:android="http://schemas.android.com/apk/res/android"
+          android:name="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
+
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
+}
+
+TEST(ProguardRulesTest, FragmentContainerViewClassRuleIsEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout =
+      test::BuildXmlDom(R"(<androidx.fragment.app.FragmentContainerView class="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
+
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
+}
+
+TEST(ProguardRulesTest, FragmentContainerViewNameAndClassRulesAreEmitted) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> layout = test::BuildXmlDom(R"(
+      <androidx.fragment.app.FragmentContainerView
+          xmlns:android="http://schemas.android.com/apk/res/android"
+          android:name="com.foo.Baz"
+          class="com.foo.Bar"/>)");
+  layout->file.name = test::ParseNameOrDie("layout/foo");
+
+  proguard::KeepSet set;
+  ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
+
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }"));
+
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }"));
+}
+
 TEST(ProguardRulesTest, NavigationFragmentNameAndClassRulesAreEmitted) {
   std::unique_ptr<IAaptContext> context = test::ContextBuilder()
       .SetCompilationPackage("com.base").Build();