Skip to content

Commit 5d5e91d

Browse files
Add files via upload
1 parent c402fb8 commit 5d5e91d

2 files changed

Lines changed: 103 additions & 19 deletions

File tree

app/src/main/kotlin/com/google/ai/sample/MainActivity.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ import com.google.ai.sample.ui.theme.GenerativeAISample
2828

2929
class MainActivity : ComponentActivity() {
3030

31+
// PhotoReasoningViewModel instance
32+
private var photoReasoningViewModel: com.google.ai.sample.feature.multimodal.PhotoReasoningViewModel? = null
33+
34+
// Function to get the PhotoReasoningViewModel
35+
fun getPhotoReasoningViewModel(): com.google.ai.sample.feature.multimodal.PhotoReasoningViewModel? {
36+
return photoReasoningViewModel
37+
}
38+
39+
// Function to set the PhotoReasoningViewModel
40+
fun setPhotoReasoningViewModel(viewModel: com.google.ai.sample.feature.multimodal.PhotoReasoningViewModel) {
41+
photoReasoningViewModel = viewModel
42+
}
43+
3144
private val requiredPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
3245
arrayOf(
3346
Manifest.permission.READ_MEDIA_IMAGES,
@@ -137,5 +150,28 @@ class MainActivity : ComponentActivity() {
137150

138151
companion object {
139152
private const val TAG = "MainActivity"
153+
154+
// Static instance of MainActivity for accessibility service access
155+
private var instance: MainActivity? = null
156+
157+
// Method to get the MainActivity instance
158+
fun getInstance(): MainActivity? {
159+
return instance
160+
}
161+
}
162+
163+
override fun onResume() {
164+
super.onResume()
165+
// Set the instance when activity is resumed
166+
instance = this
167+
}
168+
169+
override fun onPause() {
170+
super.onPause()
171+
// Clear the instance when activity is paused
172+
// Only clear if this instance is the current one
173+
if (instance == this) {
174+
instance = null
175+
}
140176
}
141177
}

app/src/main/kotlin/com/google/ai/sample/ScreenOperatorAccessibilityService.kt

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,25 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
269269
// Show a toast to indicate the screenshot was added
270270
instance?.applicationContext?.let { context ->
271271
Toast.makeText(context, "Screenshot added to conversation", Toast.LENGTH_SHORT).show()
272+
273+
// Get the current activity context
274+
val currentActivity = MainActivity.getInstance()
275+
if (currentActivity != null) {
276+
// Get the PhotoReasoningViewModel and add the screenshot to the conversation
277+
val viewModel = currentActivity.getPhotoReasoningViewModel()
278+
if (viewModel != null) {
279+
// Add the screenshot to the conversation after 1 second
280+
Handler(Looper.getMainLooper()).postDelayed({
281+
viewModel.addScreenshotToConversation(screenshotUri, context)
282+
Log.d(TAG, "Automatically sent screenshot to AI after 1 second")
283+
}, 1000) // 1 second delay
284+
} else {
285+
Log.e(TAG, "PhotoReasoningViewModel is null")
286+
}
287+
} else {
288+
Log.e(TAG, "MainActivity instance is null")
289+
}
272290
}
273-
274-
// The PhotoReasoningViewModel will handle adding the screenshot to the conversation
275-
// in its next interaction with the AI
276291
} else {
277292
Log.e(TAG, "Failed to take screenshot or get URI")
278293

@@ -383,6 +398,11 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
383398
val centerX = rect.exactCenterX()
384399
val centerY = rect.exactCenterY()
385400
Log.d(TAG, "No clickable parent found, tapping at center coordinates: $centerX, $centerY")
401+
402+
// Use tapAtCoordinates to click at the center of the node
403+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
404+
return tapAtCoordinates(centerX, centerY)
405+
}
386406
return tapAtCoordinates(centerX, centerY)
387407
}
388408
} else {
@@ -424,24 +444,52 @@ class ScreenOperatorAccessibilityService : AccessibilityService() {
424444
return false
425445
}
426446

427-
val path = Path()
428-
path.moveTo(x, y)
429-
430-
val gesture = GestureDescription.Builder()
431-
.addStroke(GestureDescription.StrokeDescription(path, 0, 100))
432-
.build()
433-
434-
return dispatchGesture(gesture, object : GestureResultCallback() {
435-
override fun onCompleted(gestureDescription: GestureDescription) {
436-
super.onCompleted(gestureDescription)
437-
Log.d(TAG, "Tap gesture completed")
438-
}
447+
try {
448+
// Create a path for the tap gesture
449+
val path = Path()
450+
path.moveTo(x, y)
451+
452+
// Create a stroke description with longer duration for better recognition
453+
val strokeDescription = GestureDescription.StrokeDescription(path, 0, 150)
439454

440-
override fun onCancelled(gestureDescription: GestureDescription) {
441-
super.onCancelled(gestureDescription)
442-
Log.e(TAG, "Tap gesture cancelled")
455+
// Build the gesture with the stroke
456+
val gestureBuilder = GestureDescription.Builder()
457+
gestureBuilder.addStroke(strokeDescription)
458+
val gesture = gestureBuilder.build()
459+
460+
// Create a callback to handle the result
461+
val callback = object : GestureResultCallback() {
462+
override fun onCompleted(gestureDescription: GestureDescription) {
463+
super.onCompleted(gestureDescription)
464+
Log.d(TAG, "Tap gesture completed successfully at coordinates: $x, $y")
465+
466+
// Show a toast to indicate the tap was performed
467+
Handler(Looper.getMainLooper()).post {
468+
applicationContext?.let { context ->
469+
Toast.makeText(context, "Tap performed at: $x, $y", Toast.LENGTH_SHORT).show()
470+
}
471+
}
472+
}
473+
474+
override fun onCancelled(gestureDescription: GestureDescription) {
475+
super.onCancelled(gestureDescription)
476+
Log.e(TAG, "Tap gesture cancelled at coordinates: $x, $y")
477+
478+
// Show a toast to indicate the tap was cancelled
479+
Handler(Looper.getMainLooper()).post {
480+
applicationContext?.let { context ->
481+
Toast.makeText(context, "Tap cancelled at: $x, $y", Toast.LENGTH_SHORT).show()
482+
}
483+
}
484+
}
443485
}
444-
}, null)
486+
487+
// Dispatch the gesture with the callback
488+
return dispatchGesture(gesture, callback, null)
489+
} catch (e: Exception) {
490+
Log.e(TAG, "Error performing tap at coordinates: $x, $y", e)
491+
return false
492+
}
445493
}
446494

447495
override fun onDestroy() {

0 commit comments

Comments
 (0)