Skip to content

Commit 6bcffc9

Browse files
fix: Correct compilation errors in PhotoReasoningViewModel
This commit addresses compilation errors that arose from the implementation of the stop button functionality. - Corrected unresolved `isActive` references by explicitly using `coroutineContext.isActive` within coroutines and suspend functions. This ensures checks are made against the correct coroutine context. - Reviewed `return` statements within `sendMessageWithRetry` and related functions to ensure they correctly exit from the intended scope. These changes resolve the build failures and ensure the stop functionality operates as intended with proper coroutine cancellation checks.
1 parent 0a1a643 commit 6bcffc9

File tree

1 file changed

+23
-23
lines changed

1 file changed

+23
-23
lines changed

app/src/main/kotlin/com/google/ai/sample/feature/multimodal/PhotoReasoningViewModel.kt

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,16 @@ class PhotoReasoningViewModel(
132132
currentReasoningJob = PhotoReasoningApplication.applicationScope.launch(Dispatchers.IO) {
133133
// Create content with the current images and prompt
134134
val inputContent = content {
135-
if (!isActive) return@launch // Check for cancellation
135+
if (!coroutineContext.isActive) return@launch // Check for cancellation
136136
for (bitmap in selectedImages) {
137-
if (!isActive) return@launch // Check for cancellation
137+
if (!coroutineContext.isActive) return@launch // Check for cancellation
138138
image(bitmap)
139139
}
140-
if (!isActive) return@launch // Check for cancellation
140+
if (!coroutineContext.isActive) return@launch // Check for cancellation
141141
text(prompt)
142142
}
143143

144-
if (!isActive) return@launch // Check for cancellation
144+
if (!coroutineContext.isActive) return@launch // Check for cancellation
145145
sendMessageWithRetry(inputContent, 0)
146146
}
147147
}
@@ -192,15 +192,15 @@ class PhotoReasoningViewModel(
192192
* @param retryCount The current retry count
193193
*/
194194
private suspend fun sendMessageWithRetry(inputContent: Content, retryCount: Int) {
195-
if (!isActive || stopExecutionFlag.get()) { // Check for cancellation
195+
if (!coroutineContext.isActive || stopExecutionFlag.get()) { // Check for cancellation
196196
_uiState.value = PhotoReasoningUiState.Success("Operation cancelled before sending.")
197197
updateAiMessage("Operation cancelled.")
198198
return
199199
}
200200
try {
201201
// Send the message to the chat to maintain context
202202
val response = chat.sendMessage(inputContent)
203-
if (!isActive || stopExecutionFlag.get()) { // Check for cancellation
203+
if (!coroutineContext.isActive || stopExecutionFlag.get()) { // Check for cancellation
204204
_uiState.value = PhotoReasoningUiState.Success("Operation cancelled after sending.")
205205
updateAiMessage("Operation cancelled.")
206206
return
@@ -212,13 +212,13 @@ class PhotoReasoningViewModel(
212212
response.text?.let { modelResponse ->
213213
outputContent = modelResponse
214214

215-
if (!isActive || stopExecutionFlag.get()) { // Check for cancellation
215+
if (!coroutineContext.isActive || stopExecutionFlag.get()) { // Check for cancellation
216216
_uiState.value = PhotoReasoningUiState.Success("Operation cancelled during response processing.")
217217
updateAiMessage("Operation cancelled.")
218218
return
219219
}
220220
withContext(Dispatchers.Main) {
221-
if (!isActive || stopExecutionFlag.get()) { // Check for cancellation
221+
if (!coroutineContext.isActive || stopExecutionFlag.get()) { // Check for cancellation
222222
_uiState.value = PhotoReasoningUiState.Success("Operation cancelled.")
223223
updateAiMessage("Operation cancelled.")
224224
return@withContext
@@ -234,13 +234,13 @@ class PhotoReasoningViewModel(
234234
}
235235

236236
// Save chat history after successful response
237-
if (isActive && !stopExecutionFlag.get()) {
237+
if (coroutineContext.isActive && !stopExecutionFlag.get()) {
238238
withContext(Dispatchers.Main) {
239239
saveChatHistory(MainActivity.getInstance()?.applicationContext)
240240
}
241241
}
242242
} catch (e: Exception) {
243-
if (!isActive || stopExecutionFlag.get()) { // Check for cancellation during exception handling
243+
if (!coroutineContext.isActive || stopExecutionFlag.get()) { // Check for cancellation during exception handling
244244
_uiState.value = PhotoReasoningUiState.Error("Operation cancelled during error handling.")
245245
updateAiMessage("Operation cancelled during error handling.")
246246
return
@@ -249,22 +249,22 @@ class PhotoReasoningViewModel(
249249

250250
// Check specifically for quota exceeded errors first
251251
if (isQuotaExceededError(e) && apiKeyManager != null) {
252-
if (!isActive || stopExecutionFlag.get()) return // Check for cancellation
252+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return // Check for cancellation
253253
handleQuotaExceededError(e, inputContent, retryCount)
254254
return
255255
}
256256

257257
// Check for other 503 errors
258258
if (is503Error(e) && apiKeyManager != null) {
259-
if (!isActive || stopExecutionFlag.get()) return // Check for cancellation
259+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return // Check for cancellation
260260
handle503Error(e, inputContent, retryCount)
261261
return
262262
}
263263

264264
// If we get here, it's not a 503 error or quota exceeded error
265-
if (isActive && !stopExecutionFlag.get()) {
265+
if (coroutineContext.isActive && !stopExecutionFlag.get()) {
266266
withContext(Dispatchers.Main) {
267-
if (!isActive || stopExecutionFlag.get()) return@withContext// Check for cancellation
267+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return@withContext// Check for cancellation
268268
_uiState.value = PhotoReasoningUiState.Error(e.localizedMessage ?: "Unknown error")
269269
_commandExecutionStatus.value = "Error during generation: ${e.localizedMessage}"
270270

@@ -335,7 +335,7 @@ class PhotoReasoningViewModel(
335335
* Handle quota exceeded errors specifically
336336
*/
337337
private suspend fun handleQuotaExceededError(e: Exception, inputContent: Content, retryCount: Int) {
338-
if (!isActive || stopExecutionFlag.get()) return // Check for cancellation
338+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return // Check for cancellation
339339
// Mark the current API key as failed
340340
val currentKey = MainActivity.getInstance()?.getCurrentApiKey()
341341
if (currentKey != null && apiKeyManager != null) {
@@ -412,7 +412,7 @@ class PhotoReasoningViewModel(
412412
)
413413

414414
// Retry the request with the new API key
415-
if (!isActive || stopExecutionFlag.get()) return // Check for cancellation
415+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return // Check for cancellation
416416
sendMessageWithRetry(inputContent, retryCount + 1)
417417
return
418418
}
@@ -424,7 +424,7 @@ class PhotoReasoningViewModel(
424424
* Handle 503 errors (excluding quota exceeded errors)
425425
*/
426426
private suspend fun handle503Error(e: Exception, inputContent: Content, retryCount: Int) {
427-
if (!isActive || stopExecutionFlag.get()) return // Check for cancellation
427+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return // Check for cancellation
428428
// Mark the current API key as failed
429429
val currentKey = MainActivity.getInstance()?.getCurrentApiKey()
430430
if (currentKey != null && apiKeyManager != null) {
@@ -498,7 +498,7 @@ class PhotoReasoningViewModel(
498498
)
499499

500500
// Retry the request with the new API key
501-
if (!isActive || stopExecutionFlag.get()) return // Check for cancellation
501+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return // Check for cancellation
502502
sendMessageWithRetry(inputContent, retryCount + 1)
503503
return
504504
}
@@ -589,13 +589,13 @@ class PhotoReasoningViewModel(
589589
private fun processCommands(text: String) {
590590
commandProcessingJob?.cancel() // Cancel any previous command processing
591591
commandProcessingJob = PhotoReasoningApplication.applicationScope.launch(Dispatchers.Main) {
592-
if (!isActive || stopExecutionFlag.get()) return@launch // Check for cancellation
592+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return@launch // Check for cancellation
593593
try {
594594
// Parse commands from the text
595595
val commands = CommandParser.parseCommands(text)
596596

597597
if (commands.isNotEmpty()) {
598-
if (!isActive || stopExecutionFlag.get()) return@launch
598+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return@launch
599599
Log.d(TAG, "Found ${commands.size} commands in response")
600600

601601
// Update the detected commands
@@ -611,7 +611,7 @@ class PhotoReasoningViewModel(
611611

612612
// Execute the commands
613613
for (command in commands) {
614-
if (!isActive || stopExecutionFlag.get()) { // Check for cancellation before executing each command
614+
if (!coroutineContext.isActive || stopExecutionFlag.get()) { // Check for cancellation before executing each command
615615
Log.d(TAG, "Command execution stopped before executing: $command")
616616
_commandExecutionStatus.value = "Command execution stopped."
617617
break // Exit loop if cancelled
@@ -626,7 +626,7 @@ class PhotoReasoningViewModel(
626626
break
627627
}
628628
} catch (e: Exception) {
629-
if (!isActive || stopExecutionFlag.get()) break // Exit loop if cancelled during error handling
629+
if (!coroutineContext.isActive || stopExecutionFlag.get()) break // Exit loop if cancelled during error handling
630630
Log.e(TAG, "Error executing command: ${e.message}", e)
631631
_commandExecutionStatus.value = "Error during command execution: ${e.message}"
632632
}
@@ -636,7 +636,7 @@ class PhotoReasoningViewModel(
636636
}
637637
}
638638
} catch (e: Exception) {
639-
if (!isActive || stopExecutionFlag.get()) return@launch
639+
if (!coroutineContext.isActive || stopExecutionFlag.get()) return@launch
640640
Log.e(TAG, "Error processing commands: ${e.message}", e)
641641
_commandExecutionStatus.value = "Error during command processing: ${e.message}"
642642
} finally {

0 commit comments

Comments
 (0)