Skip to content

Commit

Permalink
Improve accessibility autofill performance
Browse files Browse the repository at this point in the history
  • Loading branch information
david-livefront committed Nov 8, 2024
1 parent 016d0f8 commit 5645ab3
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ class BitwardenAccessibilityService : AccessibilityService() {
lateinit var processor: BitwardenAccessibilityProcessor

override fun onAccessibilityEvent(event: AccessibilityEvent) {
if (rootInActiveWindow?.packageName != event.packageName) return
processor.processAccessibilityEvent(rootAccessibilityNodeInfo = event.source)
processor.processAccessibilityEvent(event = event) { rootInActiveWindow }
}

override fun onInterrupt() = Unit
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package com.x8bit.bitwarden.data.autofill.accessibility.processor

import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo

/**
* A class to handle accessibility event processing. This only includes fill requests.
*/
interface BitwardenAccessibilityProcessor {
/**
* Processes the [AccessibilityNodeInfo] for autofill options.
* Processes the [AccessibilityEvent] for autofill options and grant access to the current
* [AccessibilityNodeInfo] via the [rootAccessibilityNodeInfoProvider] (note that calling the
* `rootAccessibilityNodeInfoProvider` is expensive).
*/
fun processAccessibilityEvent(rootAccessibilityNodeInfo: AccessibilityNodeInfo?)
fun processAccessibilityEvent(
event: AccessibilityEvent,
rootAccessibilityNodeInfoProvider: () -> AccessibilityNodeInfo?,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.autofill.accessibility.processor

import android.content.Context
import android.os.PowerManager
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Toast
import com.x8bit.bitwarden.R
Expand All @@ -25,15 +26,18 @@ class BitwardenAccessibilityProcessorImpl(
private val launcherPackageNameManager: LauncherPackageNameManager,
private val powerManager: PowerManager,
) : BitwardenAccessibilityProcessor {
override fun processAccessibilityEvent(rootAccessibilityNodeInfo: AccessibilityNodeInfo?) {
val rootNode = rootAccessibilityNodeInfo ?: return
override fun processAccessibilityEvent(
event: AccessibilityEvent,
rootAccessibilityNodeInfoProvider: () -> AccessibilityNodeInfo?,
) {
val eventNode = event.source ?: return
// Ignore the event when the phone is inactive
if (!powerManager.isInteractive) return
// We skip if the system package
if (rootNode.isSystemPackage) return
if (eventNode.isSystemPackage) return
// We skip any package that is a launcher or unsupported
if (rootNode.shouldSkipPackage ||
launcherPackageNameManager.launcherPackages.any { it == rootNode.packageName }
if (eventNode.shouldSkipPackage ||
launcherPackageNameManager.launcherPackages.any { it == eventNode.packageName }
) {
// Clear the action since this event needs to be ignored completely
accessibilityAutofillManager.accessibilityAction = null
Expand All @@ -42,14 +46,19 @@ class BitwardenAccessibilityProcessorImpl(

// Only process the event if the tile was clicked
val accessibilityAction = accessibilityAutofillManager.accessibilityAction ?: return
// We only call for the root node once after all other checks
// have passed because it is significant performance hit
if (rootAccessibilityNodeInfoProvider()?.packageName != event.packageName) return

// Clea the action since we are now acting on it
accessibilityAutofillManager.accessibilityAction = null

when (accessibilityAction) {
is AccessibilityAction.AttemptFill -> {
handleAttemptFill(rootNode = rootNode, attemptFill = accessibilityAction)
handleAttemptFill(rootNode = eventNode, attemptFill = accessibilityAction)
}

AccessibilityAction.AttemptParseUri -> handleAttemptParseUri(rootNode = rootNode)
AccessibilityAction.AttemptParseUri -> handleAttemptParseUri(rootNode = eventNode)
}
}

Expand Down
Loading

0 comments on commit 5645ab3

Please sign in to comment.