Refactor JCA to extract OpenGL/EGL effects into dedicated :core📷effects module#527
Refactor JCA to extract OpenGL/EGL effects into dedicated :core📷effects module#527davidjiagoogle wants to merge 21 commits into
Conversation
…ts module and dynamically inject it via Hilt
There was a problem hiding this comment.
Code Review
This pull request modularizes the camera effects by introducing a new :core:camera:effects module and decoupling SingleSurfaceForcingEffect from the core camera session. It defines a SingleStreamEffectProvider interface and injects its implementation using Hilt multibindings. The review feedback highlights a potential compilation error if the effects module is excluded, which can be resolved using @Multibinds. Additionally, suggestions were made to adhere to the repository style guide by restricting visibility to internal, adding KDoc documentation, and adjusting the Hilt component scope.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
temcguir
left a comment
There was a problem hiding this comment.
The overall direction of moving effects into a dedicated module and injecting them to allow for "lite" builds is solid. However, there are a few architectural issues with the current implementation that prevent it from being truly extensible for arbitrary custom effects.
Most notably, the PR description states that this uses Hilt @IntoSet multi-binding, but the code actually relies on @BindsOptionalOf to inject a single Optional<SingleStreamEffectProvider>. This single-instance injection prevents multiple effects from coexisting and forces developers to completely overwrite the module if they want to inject their own custom effect.
To resolve this, I've left a few inline comments outlining an approach that aligns with our existing LowLightBoost and ImagePostProcessor implementations:
- Generalize the interface: Rename
SingleStreamEffectProviderto a genericCameraEffectProvider. - Use a Map Registry: Replace
CameraSessionOptionalModulewith a@Multibindsmodule inside:data:camerato provide aMap<CameraEffectFeatureKey, Provider<CameraEffectProvider>>. This guarantees the Map is always present (even if empty in lite builds) and completely eliminates the need forOptionalinjection. - Drive via Settings: Treat the active effect as a configurable UI state by adding it to
CameraAppSettings(andSessionSettings), rather than hardcoding it instartCamera.CameraSessioncan then simply use the setting state to look up the correct provider from the injected Map registry.
# Conflicts: # core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/CameraEffectFeatureKey.kt # core/model/src/main/java/com/google/jetpackcamera/model/CameraEffect.kt # core/model/src/main/proto/com/google/jetpackcamera/model/proto/stream_config.proto # data/settings/src/main/java/com/google/jetpackcamera/settings/JcaSettingsSerializer.kt # data/settings/src/main/java/com/google/jetpackcamera/settings/LocalSettingsRepository.kt # data/settings/src/main/java/com/google/jetpackcamera/settings/SettingsRepositoryModule.kt # data/settings/src/main/proto/com/google/jetpackcamera/settings/jca_settings.proto # data/settings/testing/src/main/java/com/google/jetpackcamera/settings/testing/FakeJcaSettingsSerializer.kt # data/settings/testing/src/main/java/com/google/jetpackcamera/settings/testing/FakeSettingsRepository.kt
…sible String-based Camera Effects
…, add dynamic effect targets and capabilities map, and remove hardcoded string checks in settings
…successful capture on viewer screen
This PR modularizes the OpenGL/EGL surface-processing and single-stream effects in the Jetpack Camera App (JCA), separating them into a dedicated
:core:camera:effectsmodule.Key Changes:
SingleStreamEffectProviderin:core:cameraas the injection contract.effects/package hierarchy (includingSingleSurfaceForcingEffect,CopyingSurfaceProcessor, shaders, and GL helper classes) from:core:camerato:core:camera:effects.libs.androidx.graphics.core(OpenGL/EGL wrapper library) to:core:camera:effects'sbuild.gradle.kts.SingleStreamEffectProviderImplusing Hilt@IntoSetmulti-binding.CameraXCameraSystemnow injectsSet<SingleStreamEffectProvider>and passes the effect provider toCameraSessiondynamically.:core:camera:effectsdependency, preventing theandroidx.graphics:graphics-corelibrary (~15KB) from being compiled and bundled into the production APK.Tried out removing effects module in the app layer in the david/splitEffectsTryout branch