Add test coverage for Hilt subcomponents using `@TestInstallIn`.

When looking at a recent issue (https://github.com/google/dagger/issues/3695) I realized we didn't actually have test coverage for `@TestInstallIn` for components other than `SingletonComponent`. This CL adds tests for `ActivityComponent` and `FragmentComponent`.

RELNOTES=N/A
PiperOrigin-RevId: 501018396
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/AndroidManifest.xml b/javatests/dagger/hilt/android/testing/testinstallin/AndroidManifest.xml
new file mode 100644
index 0000000..9a2580e
--- /dev/null
+++ b/javatests/dagger/hilt/android/testing/testinstallin/AndroidManifest.xml
@@ -0,0 +1,11 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="dagger.hilt.android.testing.testinstallin">
+
+  <application>
+    <activity
+        android:name=".TestInstallInFooTest$TestActivity"
+        android:exported="false"
+        tools:ignore="MissingClass"/>
+  </application>
+</manifest>
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/BUILD b/javatests/dagger/hilt/android/testing/testinstallin/BUILD
index ff26292..352a388 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/BUILD
+++ b/javatests/dagger/hilt/android/testing/testinstallin/BUILD
@@ -19,6 +19,7 @@
 android_local_test(
     name = "TestInstallInFooTest",
     srcs = ["TestInstallInFooTest.java"],
+    manifest = "AndroidManifest.xml",
     manifest_values = {
         "minSdkVersion": "15",
         "targetSdkVersion": "27",
@@ -27,8 +28,14 @@
         ":TestInstallInModules",
         "//:android_local_test_exports",
         "//:dagger_with_compiler",
+        "//java/dagger/hilt/android:android_entry_point",
         "//java/dagger/hilt/android/testing:hilt_android_test",
         "//third_party/java/truth",
+        "@maven//:androidx_activity_activity",
+        "@maven//:androidx_fragment_fragment",
+        "@maven//:androidx_lifecycle_lifecycle_common",
+        "@maven//:androidx_lifecycle_lifecycle_viewmodel",
+        "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate",
         "@maven//:androidx_test_core",
         "@maven//:androidx_test_ext_junit",
         "@maven//:junit_junit",
@@ -98,5 +105,10 @@
         "//java/dagger/hilt:install_in",
         "//java/dagger/hilt/android/components",
         "//java/dagger/hilt/testing:test_install_in",
+        "@maven//:androidx_activity_activity",
+        "@maven//:androidx_fragment_fragment",
+        "@maven//:androidx_lifecycle_lifecycle_common",
+        "@maven//:androidx_lifecycle_lifecycle_viewmodel",
+        "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate",
     ],
 )
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInAppTest.java b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInAppTest.java
index beb198c..a322125 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInAppTest.java
+++ b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInAppTest.java
@@ -20,8 +20,8 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalBarModule;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalFooModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonFooModule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
@@ -33,12 +33,12 @@
 
   @Test
   public void testFoo() {
-    assertThat(getMyApplication().foo.moduleClass).isEqualTo(GlobalFooModule.class);
+    assertThat(getMyApplication().foo.moduleClass).isEqualTo(SingletonFooModule.class);
   }
 
   @Test
   public void testBar() {
-    assertThat(getMyApplication().bar.moduleClass).isEqualTo(GlobalBarModule.class);
+    assertThat(getMyApplication().bar.moduleClass).isEqualTo(SingletonBarModule.class);
   }
 
   private static TestInstallInApp getMyApplication() {
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInBarTest.java b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInBarTest.java
index 8cf9de7..8c733a1 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInBarTest.java
+++ b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInBarTest.java
@@ -28,8 +28,8 @@
 import dagger.hilt.android.testing.UninstallModules;
 import dagger.hilt.android.testing.testinstallin.TestInstallInModules.Bar;
 import dagger.hilt.android.testing.testinstallin.TestInstallInModules.Foo;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalBarModule;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalFooTestModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonFooTestModule;
 import dagger.hilt.components.SingletonComponent;
 import javax.inject.Inject;
 import org.junit.Rule;
@@ -41,7 +41,7 @@
  * Tests that Foo uses the global {@linkplain TestInstallIn} module and that Bar uses the local
  * {@linkplain InstallIn} module due to {@linkplain UninstallModules}.
  */
-@UninstallModules(GlobalBarModule.class)
+@UninstallModules(SingletonBarModule.class)
 @HiltAndroidTest
 @RunWith(AndroidJUnit4.class)
 @Config(application = HiltTestApplication.class)
@@ -51,7 +51,7 @@
 
   @Module
   @InstallIn(SingletonComponent.class)
-  public interface LocalBarTestModule {
+  interface LocalBarTestModule {
     @Provides
     static Bar provideBar() {
       return new Bar(LocalBarTestModule.class);
@@ -64,7 +64,7 @@
   @Test
   public void testFoo() {
     hiltRule.inject();
-    assertThat(foo.moduleClass).isEqualTo(GlobalFooTestModule.class);
+    assertThat(foo.moduleClass).isEqualTo(SingletonFooTestModule.class);
   }
 
   @Test
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInFooTest.java b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInFooTest.java
index 8a78157..2311431 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInFooTest.java
+++ b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInFooTest.java
@@ -18,14 +18,24 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.test.core.app.ActivityScenario;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import dagger.hilt.android.AndroidEntryPoint;
 import dagger.hilt.android.testing.HiltAndroidRule;
 import dagger.hilt.android.testing.HiltAndroidTest;
 import dagger.hilt.android.testing.HiltTestApplication;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.ActivityBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.ActivityFooTestModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.ActivityLevel;
 import dagger.hilt.android.testing.testinstallin.TestInstallInModules.Bar;
 import dagger.hilt.android.testing.testinstallin.TestInstallInModules.Foo;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalBarModule;
-import dagger.hilt.android.testing.testinstallin.TestInstallInModules.GlobalFooTestModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.FragmentBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.FragmentFooTestModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.FragmentLevel;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonBarModule;
+import dagger.hilt.android.testing.testinstallin.TestInstallInModules.SingletonFooTestModule;
 import javax.inject.Inject;
 import org.junit.Rule;
 import org.junit.Test;
@@ -43,15 +53,71 @@
   @Inject Foo foo;
   @Inject Bar bar;
 
-  @Test
-  public void testFoo() {
-    hiltRule.inject();
-    assertThat(foo.moduleClass).isEqualTo(GlobalFooTestModule.class);
+  @AndroidEntryPoint(FragmentActivity.class)
+  public static final class TestActivity extends Hilt_TestInstallInFooTest_TestActivity {
+    @Inject @ActivityLevel Foo foo;
+    @Inject @ActivityLevel Bar bar;
+  }
+
+  @AndroidEntryPoint(Fragment.class)
+  public static final class TestFragment extends Hilt_TestInstallInFooTest_TestFragment {
+    @Inject @FragmentLevel Foo foo;
+    @Inject @FragmentLevel Bar bar;
   }
 
   @Test
-  public void testBar() {
+  public void testSingletonFooUsesTestInstallIn() {
     hiltRule.inject();
-    assertThat(bar.moduleClass).isEqualTo(GlobalBarModule.class);
+    assertThat(foo.moduleClass).isEqualTo(SingletonFooTestModule.class);
+  }
+
+  @Test
+  public void testSingletonBarUsesInstallIn() {
+    hiltRule.inject();
+    assertThat(bar.moduleClass).isEqualTo(SingletonBarModule.class);
+  }
+
+  @Test
+  public void testActivityFooUsesTestInstallIn() {
+    try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
+      scenario.onActivity(
+          activity -> assertThat(activity.foo.moduleClass).isEqualTo(ActivityFooTestModule.class));
+    }
+  }
+
+  @Test
+  public void testActivityBarUsesInstallIn() {
+    try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
+      scenario.onActivity(
+          activity -> assertThat(activity.bar.moduleClass).isEqualTo(ActivityBarModule.class));
+    }
+  }
+
+  @Test
+  public void testFragmentFooUsesTestInstallIn() {
+    try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
+      scenario.onActivity(
+          activity -> assertThat(getTestFragment(activity).foo.moduleClass)
+              .isEqualTo(FragmentFooTestModule.class));
+    }
+  }
+
+  @Test
+  public void testFragmentBarUsesInstallIn() {
+    try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
+      scenario.onActivity(
+          activity -> assertThat(getTestFragment(activity).bar.moduleClass)
+              .isEqualTo(FragmentBarModule.class));
+    }
+  }
+
+  private TestFragment getTestFragment(FragmentActivity activity) {
+    TestFragment fragment = new TestFragment();
+    activity
+        .getSupportFragmentManager()
+        .beginTransaction()
+        .add(fragment, null)
+        .commitNow();
+    return fragment;
   }
 }
diff --git a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInModules.java b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInModules.java
index ab15d98..81d1c00 100644
--- a/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInModules.java
+++ b/javatests/dagger/hilt/android/testing/testinstallin/TestInstallInModules.java
@@ -16,16 +16,27 @@
 
 package dagger.hilt.android.testing.testinstallin;
 
+import android.app.Activity;
+import androidx.fragment.app.Fragment;
 import dagger.Module;
 import dagger.Provides;
 import dagger.hilt.InstallIn;
+import dagger.hilt.android.components.ActivityComponent;
+import dagger.hilt.android.components.FragmentComponent;
 import dagger.hilt.components.SingletonComponent;
 import dagger.hilt.testing.TestInstallIn;
+import javax.inject.Qualifier;
 
 /** Modules and classes used in TestInstallInFooTest and TestInstallInBarTest. */
 final class TestInstallInModules {
   private TestInstallInModules() {}
 
+  @Qualifier
+  public @interface ActivityLevel {}
+
+  @Qualifier
+  public @interface FragmentLevel {}
+
   static class Foo {
     Class<?> moduleClass;
 
@@ -44,28 +55,92 @@
 
   @Module
   @InstallIn(SingletonComponent.class)
-  interface GlobalFooModule {
+  interface SingletonFooModule {
     @Provides
     static Foo provideFoo() {
-      return new Foo(GlobalFooModule.class);
+      return new Foo(SingletonFooModule.class);
     }
   }
 
   @Module
   @InstallIn(SingletonComponent.class)
-  interface GlobalBarModule {
+  interface SingletonBarModule {
     @Provides
     static Bar provideFoo() {
-      return new Bar(GlobalBarModule.class);
+      return new Bar(SingletonBarModule.class);
     }
   }
 
   @Module
-  @TestInstallIn(components = SingletonComponent.class, replaces = GlobalFooModule.class)
-  interface GlobalFooTestModule {
+  @TestInstallIn(components = SingletonComponent.class, replaces = SingletonFooModule.class)
+  interface SingletonFooTestModule {
     @Provides
     static Foo provideFoo() {
-      return new Foo(GlobalFooTestModule.class);
+      return new Foo(SingletonFooTestModule.class);
+    }
+  }
+
+  @Module
+  @InstallIn(ActivityComponent.class)
+  interface ActivityFooModule {
+    @Provides
+    @ActivityLevel
+    static Foo provideFoo() {
+      throw new AssertionError("This provides method should never be called.");
+    }
+  }
+
+  @Module
+  @InstallIn(ActivityComponent.class)
+  interface ActivityBarModule {
+    @Provides
+    @ActivityLevel
+    // Add an activity dependency to make sure Dagger adds this module to the correct component.
+    static Bar provideFoo(@SuppressWarnings("UnusedVariable") Activity activity) {
+      return new Bar(ActivityBarModule.class);
+    }
+  }
+
+  @Module
+  @TestInstallIn(components = ActivityComponent.class, replaces = ActivityFooModule.class)
+  interface ActivityFooTestModule {
+    @Provides
+    @ActivityLevel
+    // Add an activity dependency to make sure Dagger adds this module to the correct component.
+    static Foo provideFoo(@SuppressWarnings("UnusedVariable") Activity activity) {
+      return new Foo(ActivityFooTestModule.class);
+    }
+  }
+
+  @Module
+  @InstallIn(FragmentComponent.class)
+  interface FragmentFooModule {
+    @Provides
+    @FragmentLevel
+    static Foo provideFoo() {
+      throw new AssertionError("This provides method should never be called.");
+    }
+  }
+
+  @Module
+  @InstallIn(FragmentComponent.class)
+  interface FragmentBarModule {
+    @Provides
+    @FragmentLevel
+    // Add a fragment dependency to make sure Dagger adds this module to the correct component.
+    static Bar provideFoo(@SuppressWarnings("UnusedVariable") Fragment fragment) {
+      return new Bar(FragmentBarModule.class);
+    }
+  }
+
+  @Module
+  @TestInstallIn(components = FragmentComponent.class, replaces = FragmentFooModule.class)
+  interface FragmentFooTestModule {
+    @Provides
+    @FragmentLevel
+    // Add a fragment dependency to make sure Dagger adds this module to the correct component.
+    static Foo provideFoo(@SuppressWarnings("UnusedVariable") Fragment fragment) {
+      return new Foo(FragmentFooTestModule.class);
     }
   }
 }