From 509727c373230242e141735b77656fe2ef97b9fb Mon Sep 17 00:00:00 2001 From: Logan Rosen Date: Thu, 9 Jul 2026 15:27:10 -0400 Subject: [PATCH] Add Hilt testing manifest activity artifact Adds a small published Android AAR containing a Hilt-enabled ComponentActivity and manifest entry for tests that launch activities through ActivityScenario or Compose rules. Also wires Gradle/Bazel publishing, artifact validation, coalesced Javadocs, and a consumer-shaped Hilt fixture instrumentation test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2b0862cb-279b-4d8c-9ab0-53f462a5037c --- BUILD | 2 + hilt-android-testing-manifest/BUILD | 80 +++++++++++++++++ .../api/hilt-android-testing-manifest.api | 12 +++ .../build.gradle.kts | 33 +++++++ .../main/AndroidManifest.xml | 24 ++++++ .../java/dagger/hilt/android/testing/BUILD | 32 +++++++ .../testing/HiltComponentActivity.java | 29 +++++++ .../hilt-android/simple/app/build.gradle.kts | 1 + .../simple/HiltComponentActivityTest.java | 86 +++++++++++++++++++ settings.gradle.kts | 2 + util/deploy-hilt.sh | 8 ++ util/validate-artifacts.sh | 3 +- workspace_defs.bzl | 14 +++ 13 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 hilt-android-testing-manifest/BUILD create mode 100644 hilt-android-testing-manifest/api/hilt-android-testing-manifest.api create mode 100644 hilt-android-testing-manifest/build.gradle.kts create mode 100644 hilt-android-testing-manifest/main/AndroidManifest.xml create mode 100644 hilt-android-testing-manifest/main/java/dagger/hilt/android/testing/BUILD create mode 100644 hilt-android-testing-manifest/main/java/dagger/hilt/android/testing/HiltComponentActivity.java create mode 100644 javatests/artifacts/hilt-android/simple/app/src/androidTest/java/dagger/hilt/android/simple/HiltComponentActivityTest.java diff --git a/BUILD b/BUILD index daabf44bff9..827426ed877 100644 --- a/BUILD +++ b/BUILD @@ -60,6 +60,7 @@ javadoc_library( "//dagger-spi:srcs", "//hilt-android:javadoc-srcs", "//hilt-android-testing:javadoc-srcs", + "//hilt-android-testing-manifest:javadoc-srcs", "//hilt-core:javadoc-srcs", "//java/dagger/hilt/android/plugin/main:srcs_filegroup", ], @@ -83,5 +84,6 @@ javadoc_library( "//dagger-spi", "//hilt-android:artifact-lib", "//hilt-android-testing:artifact-lib", + "//hilt-android-testing-manifest:artifact-lib", ], ) diff --git a/hilt-android-testing-manifest/BUILD b/hilt-android-testing-manifest/BUILD new file mode 100644 index 00000000000..44bdc1eda0e --- /dev/null +++ b/hilt-android-testing-manifest/BUILD @@ -0,0 +1,80 @@ +# Copyright (C) 2026 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# Description: +# Manifest artifact for Hilt Android tests. + +load("@rules_android//rules:rules.bzl", "android_library") +load("//:build_defs.bzl", "POM_VERSION") +load("//tools/maven:maven.bzl", "gen_maven_artifact") + +package(default_visibility = ["//:src"]) + +filegroup( + name = "javadoc-srcs", + srcs = [ + "//hilt-android-testing-manifest/main/java/dagger/hilt/android/testing:srcs_filegroup", + ], +) + +android_library( + name = "artifact-lib", + testonly = 1, + tags = ["maven_coordinates=com.google.dagger:hilt-android-testing-manifest:" + POM_VERSION], + exports = [ + "//hilt-android-testing-manifest/main/java/dagger/hilt/android/testing:hilt_component_activity", + ], +) + +gen_maven_artifact( + name = "artifact", + testonly = 1, + artifact_coordinates = "com.google.dagger:hilt-android-testing-manifest:" + POM_VERSION, + artifact_name = "Hilt Android Testing Manifest", + artifact_target = ":artifact-lib", + artifact_target_libs = [ + "//hilt-android-testing-manifest/main/java/dagger/hilt/android/testing:hilt_component_activity", + ], + artifact_target_maven_deps = [ + "androidx.activity:activity", + "androidx.annotation:annotation", + "androidx.fragment:fragment", + "androidx.lifecycle:lifecycle-common", + "androidx.lifecycle:lifecycle-viewmodel", + "androidx.lifecycle:lifecycle-viewmodel-savedstate", + "androidx.savedstate:savedstate", + "com.google.code.findbugs:jsr305", + "com.google.dagger:dagger", + "com.google.dagger:hilt-android", + "com.google.dagger:hilt-core", + "jakarta.inject:jakarta.inject-api", + "javax.inject:javax.inject", + "org.jetbrains.kotlin:kotlin-stdlib", + ], + artifact_target_maven_deps_banned = [ + "com.google.guava:guava", + "javax.annotation:javax.annotation-api", + ], + javadoc_android_api_level = 34, + javadoc_exclude_packages = [ + "dagger.hilt.android.internal", + ], + javadoc_root_packages = [ + "dagger.hilt.android.testing", + ], + javadoc_srcs = [ + ":javadoc-srcs", + ], + manifest = "main/AndroidManifest.xml", + packaging = "aar", +) diff --git a/hilt-android-testing-manifest/api/hilt-android-testing-manifest.api b/hilt-android-testing-manifest/api/hilt-android-testing-manifest.api new file mode 100644 index 00000000000..5845ae6f478 --- /dev/null +++ b/hilt-android-testing-manifest/api/hilt-android-testing-manifest.api @@ -0,0 +1,12 @@ +public final class dagger/hilt/android/testing/HiltComponentActivity { + public fun ()V + public synthetic fun getDefaultViewModelProviderFactory ()Landroidx/lifecycle/ViewModelProvider$Factory; +} + +public abstract interface class dagger/hilt/android/testing/HiltComponentActivity_GeneratedInjector { + public abstract fun injectHiltComponentActivity (Ldagger/hilt/android/testing/HiltComponentActivity;)V +} + +public class hilt_aggregated_deps/_dagger_hilt_android_testing_HiltComponentActivity_GeneratedInjector { + public fun ()V +} diff --git a/hilt-android-testing-manifest/build.gradle.kts b/hilt-android-testing-manifest/build.gradle.kts new file mode 100644 index 00000000000..4ea57074f07 --- /dev/null +++ b/hilt-android-testing-manifest/build.gradle.kts @@ -0,0 +1,33 @@ +import dagger.gradle.build.SoftwareType +import dagger.gradle.build.findXProcessingJar + +plugins { + alias(libs.plugins.daggerBuild) + id(libs.plugins.android.library.get().pluginId) + id(libs.plugins.kotlinAndroid.get().pluginId) + id(libs.plugins.binaryCompatibilityValidator.get().pluginId) +} + +dependencies { + api(project(":hilt-android")) + + api(libs.androidx.activity) + implementation(libs.kotlin.stdlib) + + annotationProcessor(project(":dagger-compiler", "unshaded")) + annotationProcessor(project(":hilt-compiler", "unshaded")) + annotationProcessor(libs.auto.common) + annotationProcessor(files(project.findXProcessingJar())) +} + +daggerBuild { + type = SoftwareType.ANDROID_LIBRARY + isPublished = true +} + +android { + namespace = "dagger.hilt.android.testing" + defaultConfig { minSdk = 16 } +} + +kotlin { explicitApi() } diff --git a/hilt-android-testing-manifest/main/AndroidManifest.xml b/hilt-android-testing-manifest/main/AndroidManifest.xml new file mode 100644 index 00000000000..e74be181651 --- /dev/null +++ b/hilt-android-testing-manifest/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/hilt-android-testing-manifest/main/java/dagger/hilt/android/testing/BUILD b/hilt-android-testing-manifest/main/java/dagger/hilt/android/testing/BUILD new file mode 100644 index 00000000000..ef9b2655273 --- /dev/null +++ b/hilt-android-testing-manifest/main/java/dagger/hilt/android/testing/BUILD @@ -0,0 +1,32 @@ +# Copyright (C) 2026 The Dagger Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("@rules_android//rules:rules.bzl", "android_library") + +package(default_visibility = ["//:src"]) + +android_library( + name = "hilt_component_activity", + testonly = 1, + srcs = ["HiltComponentActivity.java"], + deps = [ + "@maven//:androidx_activity_activity", + "//hilt-android/main/java/dagger/hilt/android:android_entry_point", + ], +) + +filegroup( + name = "srcs_filegroup", + srcs = glob(["*"]), +) diff --git a/hilt-android-testing-manifest/main/java/dagger/hilt/android/testing/HiltComponentActivity.java b/hilt-android-testing-manifest/main/java/dagger/hilt/android/testing/HiltComponentActivity.java new file mode 100644 index 00000000000..16fcc390e3d --- /dev/null +++ b/hilt-android-testing-manifest/main/java/dagger/hilt/android/testing/HiltComponentActivity.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2026 The Dagger Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dagger.hilt.android.testing; + +import androidx.activity.ComponentActivity; +import dagger.hilt.android.AndroidEntryPoint; + +/** + * A Hilt-enabled {@link ComponentActivity} for instrumentation tests. + * + *

Add the {@code hilt-android-testing-manifest} artifact to a debug configuration, then launch + * this activity from ActivityScenario or a Compose Android test rule. + */ +@AndroidEntryPoint(ComponentActivity.class) +public final class HiltComponentActivity extends Hilt_HiltComponentActivity {} diff --git a/javatests/artifacts/hilt-android/simple/app/build.gradle.kts b/javatests/artifacts/hilt-android/simple/app/build.gradle.kts index b1cd7dcf334..e18536be056 100644 --- a/javatests/artifacts/hilt-android/simple/app/build.gradle.kts +++ b/javatests/artifacts/hilt-android/simple/app/build.gradle.kts @@ -168,6 +168,7 @@ dependencies { androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") androidTestImplementation("com.google.dagger:hilt-android-testing:$dagger_version") androidTestAnnotationProcessor("com.google.dagger:hilt-compiler:$dagger_version") + debugImplementation("com.google.dagger:hilt-android-testing-manifest:$dagger_version") // To help us catch usages of Guava APIs for Java 8 in the '-jre' variant. annotationProcessor("com.google.guava:guava:33.6.0-android") diff --git a/javatests/artifacts/hilt-android/simple/app/src/androidTest/java/dagger/hilt/android/simple/HiltComponentActivityTest.java b/javatests/artifacts/hilt-android/simple/app/src/androidTest/java/dagger/hilt/android/simple/HiltComponentActivityTest.java new file mode 100644 index 00000000000..2fd2e9c47e0 --- /dev/null +++ b/javatests/artifacts/hilt-android/simple/app/src/androidTest/java/dagger/hilt/android/simple/HiltComponentActivityTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2026 The Dagger Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dagger.hilt.android.simple; + +import static androidx.lifecycle.Lifecycle.State.RESUMED; +import static com.google.common.truth.Truth.assertThat; + +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import dagger.Module; +import dagger.Provides; +import dagger.hilt.EntryPoint; +import dagger.hilt.EntryPoints; +import dagger.hilt.InstallIn; +import dagger.hilt.android.components.ActivityComponent; +import dagger.hilt.android.testing.HiltAndroidRule; +import dagger.hilt.android.testing.HiltAndroidTest; +import dagger.hilt.android.testing.HiltComponentActivity; +import javax.inject.Named; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** Tests the reusable Hilt test activity from hilt-android-testing-manifest. */ +@HiltAndroidTest +@RunWith(AndroidJUnit4.class) +public final class HiltComponentActivityTest { + private static final String ACTIVITY_QUALIFIER = "HILT_COMPONENT_ACTIVITY"; + private static final String ACTIVITY_VALUE = "HiltComponentActivityTest_ActivityValue"; + + @Module + @InstallIn(ActivityComponent.class) + interface TestActivityModule { + @Provides + @Named(ACTIVITY_QUALIFIER) + static String provideString() { + return ACTIVITY_VALUE; + } + } + + @EntryPoint + @InstallIn(ActivityComponent.class) + interface TestActivityEntryPoint { + @Named(ACTIVITY_QUALIFIER) + String activityValue(); + } + + @Rule public HiltAndroidRule rule = new HiltAndroidRule(this); + + @Test + public void hiltComponentActivity_canBeLaunchedFromManifestArtifact() { + rule.inject(); + + try (ActivityScenario scenario = + ActivityScenario.launch(HiltComponentActivity.class)) { + assertThat(scenario.getState()).isEqualTo(RESUMED); + } + } + + @Test + public void hiltComponentActivity_hasActivityComponent() { + rule.inject(); + + try (ActivityScenario scenario = + ActivityScenario.launch(HiltComponentActivity.class)) { + scenario.onActivity( + activity -> + assertThat(EntryPoints.get(activity, TestActivityEntryPoint.class).activityValue()) + .isEqualTo(ACTIVITY_VALUE)); + } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index d75d5b0ddb1..b38c7d9890c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -56,6 +56,8 @@ includeProject(":hilt-android", "hilt-android") includeProject(":hilt-android-testing", "hilt-android-testing") +includeProject(":hilt-android-testing-manifest", "hilt-android-testing-manifest") + includeProject(":hilt-compiler", "hilt-compiler") includeProject(":hilt-core", "hilt-core") diff --git a/util/deploy-hilt.sh b/util/deploy-hilt.sh index 32be5f10124..33f4bed9fa6 100755 --- a/util/deploy-hilt.sh +++ b/util/deploy-hilt.sh @@ -59,6 +59,14 @@ _deploy \ hilt-android-testing/artifact-javadoc.jar \ "" +_deploy \ + "" \ + hilt-android-testing-manifest/artifact.aar \ + hilt-android-testing-manifest/pom.xml \ + hilt-android-testing-manifest/artifact-src.jar \ + hilt-android-testing-manifest/artifact-javadoc.jar \ + "" + _deploy \ "$_SHADED_RULES" \ hilt-compiler/artifact.jar \ diff --git a/util/validate-artifacts.sh b/util/validate-artifacts.sh index b5565494887..45217c4b019 100755 --- a/util/validate-artifacts.sh +++ b/util/validate-artifacts.sh @@ -18,7 +18,7 @@ _validate_jar() { if [[ $artifact_id == "dagger-gwt" ]]; then python $(dirname $0)/validate-jar-entry-prefixes.py \ $artifact_jar "dagger/,META-INF/,javax/inject/Inject.gwt.xml,jakarta/inject/Inject.gwt.xml,org/jspecify/Jspecify.gwt.xml" - elif [[ $artifact_id == "hilt-android" ]]; then + elif [[ $artifact_id == "hilt-android" || $artifact_id == "hilt-android-testing-manifest" ]]; then python $(dirname $0)/validate-jar-entry-prefixes.py \ $artifact_jar "dagger/,META-INF/,hilt_aggregated_deps/" else @@ -46,6 +46,7 @@ _validate_jar "dagger-lint-aar" "aar" $JDK8 _validate_jar "hilt-core" "jar" $JDK8 _validate_jar "hilt-android" "aar" $JDK8 _validate_jar "hilt-android-testing" "aar" $JDK8 +_validate_jar "hilt-android-testing-manifest" "aar" $JDK8 # Processor artifacts _validate_jar "dagger-spi" "jar" $JDK8 diff --git a/workspace_defs.bzl b/workspace_defs.bzl index c631d0a452e..6c8ebf9cd4c 100644 --- a/workspace_defs.bzl +++ b/workspace_defs.bzl @@ -45,6 +45,7 @@ HILT_ANDROID_ARTIFACTS = [ "com.google.dagger:dagger-compiler:" + _VERSION, "com.google.dagger:hilt-android:" + _VERSION, "com.google.dagger:hilt-android-testing:" + _VERSION, + "com.google.dagger:hilt-android-testing-manifest:" + _VERSION, "com.google.dagger:hilt-android-compiler:" + _VERSION, "com.google.dagger:hilt-core:" + _VERSION, ] @@ -286,6 +287,19 @@ def hilt_android_rules(repo_name = "@maven"): ], ) + # https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md#native-android + # buildifier: disable=native-android + native.android_library( + name = "hilt-android-testing-manifest", + testonly = 1, + visibility = ["//visibility:public"], + exports = [ + ":hilt-android", + "%s//:androidx_activity_activity" % repo_name, + "%s//:com_google_dagger_hilt_android_testing_manifest" % repo_name, + ], + ) + native.java_plugin( name = "hilt_bind_value_processor", generates_api = 1,