From daecceb3421c75a276a4fddb3a9fe121e1a5fa2a Mon Sep 17 00:00:00 2001 From: cogwheel0 <172976095+cogwheel0@users.noreply.github.com> Date: Fri, 21 Nov 2025 20:59:49 +0530 Subject: [PATCH] feat(android): Add screenshot processing for Android assistant --- .../app/cogwheel/conduit/MainActivity.kt | 15 ++++ lib/core/utils/android_assistant_handler.dart | 70 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/android/app/src/main/kotlin/app/cogwheel/conduit/MainActivity.kt b/android/app/src/main/kotlin/app/cogwheel/conduit/MainActivity.kt index 4343470..04fa508 100644 --- a/android/app/src/main/kotlin/app/cogwheel/conduit/MainActivity.kt +++ b/android/app/src/main/kotlin/app/cogwheel/conduit/MainActivity.kt @@ -45,9 +45,24 @@ class MainActivity : FlutterActivity() { } private fun handleIntent(intent: android.content.Intent) { + android.util.Log.d("MainActivity", "handleIntent called") + android.util.Log.d("MainActivity", "Intent extras: ${intent.extras?.keySet()}") + val screenContext = intent.getStringExtra("screen_context") + val screenshotPath = intent.getStringExtra("screenshot_path") + + android.util.Log.d("MainActivity", "screenContext: $screenContext") + android.util.Log.d("MainActivity", "screenshotPath: $screenshotPath") + android.util.Log.d("MainActivity", "methodChannel: $methodChannel") + if (screenContext != null) { + android.util.Log.d("MainActivity", "Invoking analyzeScreen") methodChannel?.invokeMethod("analyzeScreen", screenContext) + } else if (screenshotPath != null) { + android.util.Log.d("MainActivity", "Invoking analyzeScreenshot with path: $screenshotPath") + methodChannel?.invokeMethod("analyzeScreenshot", screenshotPath) + } else { + android.util.Log.d("MainActivity", "No screen context or screenshot path found") } } diff --git a/lib/core/utils/android_assistant_handler.dart b/lib/core/utils/android_assistant_handler.dart index 19b9f44..1e079cb 100644 --- a/lib/core/utils/android_assistant_handler.dart +++ b/lib/core/utils/android_assistant_handler.dart @@ -1,5 +1,14 @@ +import 'dart:io'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:path/path.dart' as path; +import '../../features/chat/providers/chat_providers.dart'; +import '../../features/chat/services/file_attachment_service.dart'; +import '../services/navigation_service.dart'; +import '../../shared/services/tasks/task_queue.dart'; +import '../providers/app_providers.dart'; +import '../../features/auth/providers/unified_auth_providers.dart'; +import 'debug_logger.dart'; final androidAssistantProvider = Provider( (ref) => AndroidAssistantHandler(ref), @@ -30,6 +39,67 @@ class AndroidAssistantHandler { if (call.method == 'analyzeScreen') { final String context = call.arguments as String; _ref.read(screenContextProvider.notifier).setContext(context); + } else if (call.method == 'analyzeScreenshot') { + final String screenshotPath = call.arguments as String; + await _processScreenshot(screenshotPath); + } + } + + Future _processScreenshot(String screenshotPath) async { + try { + DebugLogger.log('Processing screenshot: $screenshotPath', scope: 'assistant'); + + // Wait for app to be ready (authenticated and model available) + final navState = _ref.read(authNavigationStateProvider); + final model = _ref.read(selectedModelProvider); + + if (navState != AuthNavigationState.authenticated || model == null) { + DebugLogger.log('App not ready for screenshot processing', scope: 'assistant'); + return; + } + + // Navigate to chat if not already there + final isOnChatRoute = NavigationService.currentRoute == Routes.chat; + if (!isOnChatRoute) { + // Navigation will happen via auth state + return; + } + + // Start a fresh chat context + startNewChat(_ref); + + // Add screenshot as attachment + final file = File(screenshotPath); + if (!await file.exists()) { + DebugLogger.log('Screenshot file not found: $screenshotPath', scope: 'assistant'); + return; + } + + final svc = _ref.read(fileAttachmentServiceProvider); + if (svc != null) { + final attachment = LocalAttachment( + file: file, + displayName: path.basename(screenshotPath), + ); + + _ref.read(attachedFilesProvider.notifier).addFiles([attachment]); + + // Enqueue upload via task queue + final activeConv = _ref.read(activeConversationProvider); + try { + await _ref.read(taskQueueProvider.notifier).enqueueUploadMedia( + conversationId: activeConv?.id, + filePath: attachment.file.path, + fileName: attachment.displayName, + fileSize: await attachment.file.length(), + ); + DebugLogger.log('Screenshot uploaded successfully', scope: 'assistant'); + } catch (e) { + DebugLogger.log('Failed to upload screenshot: $e', scope: 'assistant'); + } + } + } catch (e) { + DebugLogger.log('Failed to process screenshot: $e', scope: 'assistant'); } } }