feat: refine AI navigation and accessibility recovery
This commit is contained in:
@@ -57,34 +57,34 @@
|
||||
android:process=":recognition"
|
||||
android:stopWithTask="false"/>
|
||||
|
||||
<service
|
||||
android:name=".ScreenshotTileService"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/screenshot_tile_label"
|
||||
android:process=":recognition"
|
||||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
|
||||
<service
|
||||
android:name=".ScreenshotTileService"
|
||||
android:exported="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/screenshot_tile_label"
|
||||
android:stopWithTask="false"
|
||||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".PaymentNotificationListenerService"
|
||||
android:exported="true"
|
||||
android:label="@string/notification_listener_label"
|
||||
android:process=":recognition"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||
android:name=".PaymentNotificationListenerService"
|
||||
android:exported="true"
|
||||
android:label="@string/notification_listener_label"
|
||||
android:stopWithTask="false"
|
||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.notification.NotificationListenerService"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".ScreenshotAccessibilityService"
|
||||
android:exported="true"
|
||||
android:process=":recognition"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<service
|
||||
android:name=".ScreenshotAccessibilityService"
|
||||
android:exported="true"
|
||||
android:stopWithTask="false"
|
||||
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.accessibilityservice.AccessibilityService"/>
|
||||
</intent-filter>
|
||||
@@ -95,10 +95,9 @@
|
||||
|
||||
<provider
|
||||
android:name=".RecognitionBridgeProvider"
|
||||
android:authorities="${applicationId}.recognition.bridge"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="false"
|
||||
android:process=":recognition"/>
|
||||
android:authorities="${applicationId}.recognition.bridge"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="false"/>
|
||||
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
|
||||
@@ -778,8 +778,8 @@ class MainActivity : FlutterActivity() {
|
||||
},
|
||||
)
|
||||
}
|
||||
private fun recognitionStatus(): Map<String, Any?> {
|
||||
val response = RecognitionBridge.call(
|
||||
private fun recognitionStatus(): Map<String, Any?> {
|
||||
val response = RecognitionBridge.call(
|
||||
this,
|
||||
RecognitionBridgeProvider.METHOD_STATUS,
|
||||
)
|
||||
@@ -787,13 +787,27 @@ class MainActivity : FlutterActivity() {
|
||||
contentResolver,
|
||||
"enabled_notification_listeners",
|
||||
).orEmpty()
|
||||
val notificationAuthorized = enabledListeners
|
||||
val notificationAuthorized = enabledListeners
|
||||
.split(':')
|
||||
.mapNotNull(ComponentName::unflattenFromString)
|
||||
.any { it == ComponentName(this, PaymentNotificationListenerService::class.java) }
|
||||
return mapOf(
|
||||
"accessibilityAuthorized" to isAccessibilityEnabledInSystem(),
|
||||
"accessibilityConnected" to (response?.getBoolean("accessibilityConnected") == true),
|
||||
.any { it == ComponentName(this, PaymentNotificationListenerService::class.java) }
|
||||
val accessibilityAuthorized = isAccessibilityEnabledInSystem()
|
||||
val accessibilityConnected = response?.getBoolean("accessibilityConnected") == true
|
||||
val recognitionProcessStartedAt = response?.getLong("recognitionProcessStartedAt") ?: 0L
|
||||
val accessibilityConnectionState = when {
|
||||
!accessibilityAuthorized -> "unauthorized"
|
||||
accessibilityConnected -> "connected"
|
||||
recognitionProcessStartedAt > 0L &&
|
||||
System.currentTimeMillis() - recognitionProcessStartedAt < 5_000L -> "reconnecting"
|
||||
else -> "disconnected"
|
||||
}
|
||||
return mapOf(
|
||||
"accessibilityAuthorized" to accessibilityAuthorized,
|
||||
"accessibilityConnected" to accessibilityConnected,
|
||||
"accessibilityConnectionState" to accessibilityConnectionState,
|
||||
"accessibilityLastConnectedAt" to (response?.getLong("accessibilityLastConnectedAt") ?: 0L),
|
||||
"accessibilityLastDisconnectedAt" to (response?.getLong("accessibilityLastDisconnectedAt") ?: 0L),
|
||||
"recognitionProcessStartedAt" to recognitionProcessStartedAt,
|
||||
"notificationAuthorized" to notificationAuthorized,
|
||||
"notificationConnected" to (response?.getBoolean("notificationConnected") == true),
|
||||
"postNotificationsGranted" to (
|
||||
|
||||
@@ -22,6 +22,9 @@ class RecognitionBridgeProvider : ContentProvider() {
|
||||
return when (method) {
|
||||
METHOD_STATUS -> Bundle().apply {
|
||||
putBoolean("accessibilityConnected", ScreenshotAccessibilityService.isConnected)
|
||||
putLong("accessibilityLastConnectedAt", ScreenshotAccessibilityService.lastConnectedAt)
|
||||
putLong("accessibilityLastDisconnectedAt", ScreenshotAccessibilityService.lastDisconnectedAt)
|
||||
putLong("recognitionProcessStartedAt", PROCESS_STARTED_AT)
|
||||
putBoolean("notificationConnected", PaymentNotificationListenerService.isConnected)
|
||||
putString("settings", RecognitionSettings.statusJson(appContext))
|
||||
putString("latestStatus", RecognitionCoordinator.get(appContext).latestStatus())
|
||||
@@ -143,6 +146,7 @@ class RecognitionBridgeProvider : ContentProvider() {
|
||||
private data class CaptureResult(val path: String?, val error: String?)
|
||||
|
||||
companion object {
|
||||
private val PROCESS_STARTED_AT = System.currentTimeMillis()
|
||||
const val METHOD_STATUS = "status"
|
||||
const val METHOD_SET_TOGGLE = "setToggle"
|
||||
const val METHOD_SET_RUNTIME = "setRuntime"
|
||||
|
||||
@@ -78,6 +78,7 @@ class ScreenshotAccessibilityService : AccessibilityService() {
|
||||
}
|
||||
activeInstance = this
|
||||
isConnected = true
|
||||
lastConnectedAt = System.currentTimeMillis()
|
||||
Log.i(TAG, "Accessibility recognition service connected")
|
||||
}
|
||||
|
||||
@@ -363,6 +364,7 @@ class ScreenshotAccessibilityService : AccessibilityService() {
|
||||
private fun disconnect() {
|
||||
if (activeInstance === this) activeInstance = null
|
||||
isConnected = false
|
||||
lastDisconnectedAt = System.currentTimeMillis()
|
||||
pendingRetry = null
|
||||
retryTimeout = null
|
||||
pendingVisualCapture = null
|
||||
@@ -1270,6 +1272,14 @@ class ScreenshotAccessibilityService : AccessibilityService() {
|
||||
var isConnected = false
|
||||
private set
|
||||
|
||||
@Volatile
|
||||
var lastConnectedAt = 0L
|
||||
private set
|
||||
|
||||
@Volatile
|
||||
var lastDisconnectedAt = 0L
|
||||
private set
|
||||
|
||||
fun requestScreenshot(
|
||||
showResult: Boolean,
|
||||
delayMs: Long = 0L,
|
||||
|
||||
Reference in New Issue
Block a user