Skip to content

Feature/kathleen audio flow#169

Closed
kathleenalexandra24 wants to merge 10 commits into
prototype-ai-glassesfrom
feature/kathleen-audio-flow
Closed

Feature/kathleen audio flow#169
kathleenalexandra24 wants to merge 10 commits into
prototype-ai-glassesfrom
feature/kathleen-audio-flow

Conversation

@kathleenalexandra24
Copy link
Copy Markdown

No description provided.

Copy link
Copy Markdown
Contributor

@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 introduces support for an AI glasses experience in the Gemini Live To-Do sample. Key changes include the addition of a new GlassesActivity, specialized UI components for visual and audio modes on glasses, and updates to the TodoRepository and TodoScreenViewModel to manage live sessions and microphone status. Feedback focuses on correcting architectural violations where Activity references are passed to or held by the ViewModel, improving encapsulation of the LiveSession, and removing redundant dependencies and logic within the repository.

private val TAG = "TodoScreenViewModel"
private var session: LiveSession? = null
internal var session: LiveSession? = null
private var hostActivityRef: WeakReference<Activity>? = null
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

ViewModels should not hold references to Activity objects, even via WeakReference. This violates the principle of ViewModels being agnostic of the Android lifecycle and can lead to memory leaks or crashes if the Activity is recreated. Consider using a more robust way to handle Activity-dependent actions, such as a shared Flow or a callback mechanism initiated from the UI layer.

References
  1. ViewModels should be agnostic of the Android lifecycle. Avoid references to lifecycle-related types, Activities, Fragments, Context, or Resources. (link)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

viewModel.initializeGeminiLive(this)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Passing an Activity instance to a ViewModel function is strongly discouraged as it can lead to memory leaks and violates the separation of concerns between the UI and data layers. The ViewModel should be agnostic of the Activity lifecycle and should not depend on UI-specific types like Activity.

References
  1. ViewModel functions should never take an activity as a parameter to avoid memory leaks. (link)

class TodoScreenViewModel @Inject constructor(private val todoRepository: TodoRepository) : ViewModel() {
private val TAG = "TodoScreenViewModel"
private var session: LiveSession? = null
internal var session: LiveSession? = null
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The 'session' property should be private to encapsulate the implementation details of the live session. Exposing it as 'internal' allows the UI layer to bypass the ViewModel and interact with the session directly, which violates the Unidirectional Data Flow (UDF) principle and separation of concerns.

Suggested change
internal var session: LiveSession? = null
private var session: LiveSession? = null

scope.launch {
// Give Gemini Live a moment to open the channel
kotlinx.coroutines.delay(500)
viewModel.session?.send(content { text("Turning Microphone On") })
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Directly accessing and calling 'send' on the ViewModel's session object from the UI layer breaks encapsulation and the observer pattern. The ViewModel should provide a dedicated method for sending voice feedback or commands to maintain a clean separation of concerns and adhere to Unidirectional Data Flow (UDF).


implementation(libs.androidx.xr.glimmer)
implementation(libs.androidx.xr.projected)
implementation("com.google.firebase:firebase-ai:17.5.0")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This dependency is redundant as 'libs.firebase.ai' is already included on line 62. It is recommended to use the version catalog ('libs') for all dependencies to ensure consistency and easier version management across the project.

statusText = "Mic Status",
isMicOn = false
),
).filterNot { it.id == MIC_STATUS_TODO_ID },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The filter operation here appears to be redundant because 'MIC_STATUS_TODO_ID' (-999) is not present in the preceding list. This logic can be simplified by removing the filter call.

Suggested change
).filterNot { it.id == MIC_STATUS_TODO_ID },
)

@kathleenalexandra24 kathleenalexandra24 changed the base branch from main to prototype-ai-glasses May 8, 2026 16:04
@JolandaVerhoef
Copy link
Copy Markdown
Collaborator

Refer to #168 instead

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.

5 participants