From 01e6745e6d8239e091394de041dea1ba1d433b8a Mon Sep 17 00:00:00 2001 From: Senthil Raja R Date: Tue, 16 Jun 2026 10:36:03 +0530 Subject: [PATCH] feat(hilt): Add limited dynamic feature module support for tests When applying the Hilt plugin to a dynamic feature module (com.android.dynamic-feature), AGP provides a DynamicFeatureAndroidComponentsExtension which was not handled by the plugin's type checks, causing the error: "Hilt plugin does not know how to configure 'extension androidComponents'" This change adds support for dynamic feature modules in a limited capacity: - Dynamic feature modules are treated like libraries for Hilt purposes - Only test variants (unitTest and androidTest) are configured as Hilt roots, allowing test-specific graphs to be created - Dynamic features cannot contribute bindings/modules to the main app graph - @HiltAndroidApp is still correctly rejected in dynamic feature modules (enforced by AndroidEntryPointProcessingStep's GradleProjectType.APP check) Fixes #5089 --- .../processor/internal/optionvalues/GradleProjectType.java | 5 +++-- .../kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt | 4 ++++ .../main/kotlin/dagger/hilt/android/plugin/util/Variants.kt | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/hilt-compiler/main/java/dagger/hilt/processor/internal/optionvalues/GradleProjectType.java b/hilt-compiler/main/java/dagger/hilt/processor/internal/optionvalues/GradleProjectType.java index 4c3fa16cb3e..9fdf8e7b97a 100644 --- a/hilt-compiler/main/java/dagger/hilt/processor/internal/optionvalues/GradleProjectType.java +++ b/hilt-compiler/main/java/dagger/hilt/processor/internal/optionvalues/GradleProjectType.java @@ -17,8 +17,9 @@ package dagger.hilt.processor.internal.optionvalues; /** - * Valid Gradle project type values. Note that we exclude 'com.android.feature' as Hilt doesn't - * support it for now. + * Valid Gradle project type values. Note that 'com.android.dynamic-feature' (formerly + * 'com.android.feature') is supported in a limited capacity -- dynamic feature modules are + * treated as libraries and can only contribute test-specific graphs, not the main app graph. */ public enum GradleProjectType { /** Project type is not set, e.g. Hilt Gradle Plugin not applied. */ diff --git a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt index e26fbf90410..7941de2b19e 100644 --- a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt +++ b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/HiltGradlePlugin.kt @@ -25,6 +25,7 @@ import com.android.build.api.instrumentation.InstrumentationScope import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.android.build.api.variant.Component +import com.android.build.api.variant.DynamicFeatureAndroidComponentsExtension import com.android.build.api.variant.LibraryAndroidComponentsExtension import com.android.build.api.variant.ScopedArtifacts import com.android.build.api.variant.TestAndroidComponentsExtension @@ -397,6 +398,9 @@ class HiltGradlePlugin @Inject constructor(private val providers: ProviderFactor when (androidExtension) { is ApplicationAndroidComponentsExtension -> GradleProjectType.APP is LibraryAndroidComponentsExtension -> GradleProjectType.LIBRARY + // Dynamic feature modules are treated as libraries since they cannot have a + // @HiltAndroidApp and cannot contribute to the main app's component tree. + is DynamicFeatureAndroidComponentsExtension -> GradleProjectType.LIBRARY is TestAndroidComponentsExtension -> GradleProjectType.TEST else -> error("Hilt plugin does not know how to configure '$androidExtension'") } diff --git a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Variants.kt b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Variants.kt index 0a1b74b6a56..1f43fca4a50 100644 --- a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Variants.kt +++ b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Variants.kt @@ -19,6 +19,7 @@ package dagger.hilt.android.plugin.util import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.android.build.api.variant.Component +import com.android.build.api.variant.DynamicFeatureAndroidComponentsExtension import com.android.build.api.variant.HasAndroidTest import com.android.build.api.variant.HasUnitTest import com.android.build.api.variant.LibraryAndroidComponentsExtension @@ -39,6 +40,9 @@ internal fun AndroidComponentsExtension<*, *, *>.onRootVariants( // For a library project, only the androidTest and unitTest variant are configured since // Hilt components are not generated in a library. is LibraryAndroidComponentsExtension -> onTestVariants(block) + // Dynamic feature modules behave like libraries for Hilt purposes. They cannot contribute + // bindings to the main app graph, but they can create test-specific graphs. + is DynamicFeatureAndroidComponentsExtension -> onTestVariants(block) is TestAndroidComponentsExtension -> onVariants { block(it, null) } else -> error("Hilt plugin does not know how to configure '$this'") }