Skip to content

Conversation

@SigmanZero
Copy link
Collaborator

No description provided.

SigmanZero and others added 4 commits October 26, 2025 21:31
These new samples demonstrate Android Camera & Media user experiences
that leverage AI. Please see the old-media-samples tag in this repo to
find the previous samples that were hosted here.
@SigmanZero SigmanZero merged commit e449dbf into main Oct 28, 2025
1 of 2 checks passed
@gemini-code-assist
Copy link

Summary of Changes

Hello @SigmanZero, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a significant update to the repository's sample content. It systematically removes outdated media-related samples and introduces a suite of new, modern examples built with CameraX and Jetpack Compose. These new samples demonstrate advanced functionalities such as real-time green screen effects using ML Kit and voice-activated camera controls powered by Firebase AI, providing contemporary and relevant showcases for Android developers.

Highlights

  • Sample Repository Overhaul: The pull request completely repurposes the repository by removing all existing legacy media samples, including BasicMediaDecoder, BasicMediaRouter, and MediaRecorder.
  • New CameraX Samples Introduced: Three new modern Android samples are added, built using CameraX and Jetpack Compose: a basic CameraX app, an advanced green screen effect app leveraging ML Kit, and a voice control app integrating Firebase AI.
  • ML Kit Integration for Green Screen: The final_green_screen sample demonstrates real-time background removal using ML Kit's selfie segmentation, applying a green screen effect to the camera feed.
  • Firebase AI Integration for Voice Control: The final_voice_control sample showcases how to control camera functions (take photo, start/stop video) using voice commands, powered by Firebase AI's Live Model.
  • Modern Android Development Stack: The new samples utilize Kotlin, Jetpack Compose for UI, and Gradle Kotlin DSL for build configuration, reflecting current best practices in Android development.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request repurposes the repository by removing old media samples and adding three new ones demonstrating CameraX features: a basic app, a green screen effect app, and a voice control app. My review focuses on the new code. I've identified a critical performance issue and a high-severity race condition in the green screen sample due to incorrect threading and state management. I've also pointed out that the voice control sample has its core functionality commented out, rendering it non-functional. Additionally, there's a medium-severity maintainability issue with magic numbers.

)
} else if (effectMode.value == EffectMode.GREEN_SCREEN) {
imageAnalyzer.setAnalyzer(
ContextCompat.getMainExecutor(application),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The SelfieSegmentationAnalyzer is being run on the main executor. The analyze method performs several heavy operations like bitmap creation and transformations, which can block the main thread and cause UI jank. This analyzer should be run on a background thread. You already have a cameraExecutor which would be suitable for this.

Suggested change
ContextCompat.getMainExecutor(application),
cameraExecutor,

Comment on lines +99 to +100
lateinit var mask: Bitmap
lateinit var bitmap: Bitmap

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

These top-level lateinit var properties are used to share data between the SelfieSegmentationAnalyzer and the OverlayEffect.OnDrawListener. This is not thread-safe and can lead to race conditions, as the analyzer and the draw listener can run on different threads. This can result in tearing, where the bitmap and mask are from different frames.

A better approach is to use a thread-safe mechanism to pass data. For example, you could encapsulate the bitmap and mask in a data class and use an AtomicReference to update and read them atomically.

Example:

// 1. Define a data class
data class SegmentationResult(val bitmap: Bitmap, val mask: Bitmap)

// 2. Replace the lateinit vars with an AtomicReference
private val segmentationResult = AtomicReference<SegmentationResult?>()

// 3. In SelfieSegmentationAnalyzer, at the end of analyze:
segmentationResult.set(SegmentationResult(bitmap, mask))

// 4. In greenScreenEffect.setOnDrawListener:
val result = segmentationResult.get()
if (result != null) {
    // ... use result.bitmap and result.mask
}

Comment on lines +110 to +117
// val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
// modelName = "gemini-live-2.5-flash-preview",
// generationConfig = liveGenerationConfig {
// responseModality = ResponseModality.AUDIO
// speechConfig = SpeechConfig(voice = Voice("FENRIR"))
// },
// systemInstruction = systemInstruction,
// tools = listOf(cameraControlTool))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The initialization of the Gemini liveModel is commented out, which makes the voice control feature non-functional. The call to model.connect() in startVoiceControl() is also commented out. Was this intentional? If this sample is meant to demonstrate voice control, this code should be enabled, perhaps with instructions for developers on how to configure their own API key.

frame.overlayCanvas.drawColor(GraphicsColor.TRANSPARENT, PorterDuff.Mode.CLEAR)

// Draw the bitmap and mask, positioning the overlay in the bottom right corner.
val rect = Rect(4*bitmap.width/3, bitmap.height/2, 7 * bitmap.width/3, 3*bitmap.height/2)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The coordinates for positioning the overlay are calculated using magic numbers (4, 3, 7, 2). This makes the code harder to understand and maintain. Consider extracting these values into named constants to clarify their purpose, for example, by defining the overlay's relative position and size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants