Broaden Android accessibility autofill fallback
This commit is contained in:
@@ -12,7 +12,6 @@ import java.util.List;
|
||||
|
||||
public final class KeePassGOAccessibilityService extends AccessibilityService {
|
||||
private static final String TAG = "KeePassGOA11y";
|
||||
|
||||
private String lastFilledSignature = "";
|
||||
|
||||
@Override
|
||||
@@ -22,22 +21,17 @@ public final class KeePassGOAccessibilityService extends AccessibilityService {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
CharSequence packageName = root.getPackageName();
|
||||
if (packageName == null || !"com.android.chrome".contentEquals(packageName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ChromeForm form = inspectChrome(root);
|
||||
ChromeForm form = inspectWindow(root);
|
||||
if (form == null || form.passwordField == null) {
|
||||
return;
|
||||
}
|
||||
AutofillCacheStore.Entry entry = AutofillCacheStore.findBestMatch(this, form.url);
|
||||
AutofillCacheStore.Entry entry = AutofillCacheStore.findBestMatch(this, form.matchTarget);
|
||||
if (entry == null) {
|
||||
Log.i(TAG, "no accessibility-fill match for " + form.url);
|
||||
Log.i(TAG, "no accessibility-fill match for " + form.matchTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
String signature = form.url + "|" + entry.username + "|" + nodeKey(form.passwordField);
|
||||
String signature = form.matchTarget + "|" + entry.username + "|" + nodeKey(form.passwordField);
|
||||
if (signature.equals(lastFilledSignature)) {
|
||||
return;
|
||||
}
|
||||
@@ -49,7 +43,7 @@ public final class KeePassGOAccessibilityService extends AccessibilityService {
|
||||
filled |= setNodeText(form.passwordField, entry.password);
|
||||
if (filled) {
|
||||
lastFilledSignature = signature;
|
||||
Log.i(TAG, "filled login form for " + form.url + " with " + entry.username);
|
||||
Log.i(TAG, "filled login form for " + form.matchTarget + " with " + entry.username);
|
||||
}
|
||||
} catch (Exception err) {
|
||||
Log.e(TAG, "accessibility fill failed", err);
|
||||
@@ -61,11 +55,11 @@ public final class KeePassGOAccessibilityService extends AccessibilityService {
|
||||
Log.i(TAG, "accessibility service interrupted");
|
||||
}
|
||||
|
||||
private static ChromeForm inspectChrome(AccessibilityNodeInfo root) {
|
||||
private static ChromeForm inspectWindow(AccessibilityNodeInfo root) {
|
||||
List<AccessibilityNodeInfo> editables = new ArrayList<>();
|
||||
ChromeForm form = new ChromeForm();
|
||||
walk(root, editables, form);
|
||||
if (form.url.isEmpty()) {
|
||||
if (form.matchTarget.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (form.passwordField == null) {
|
||||
@@ -111,7 +105,13 @@ public final class KeePassGOAccessibilityService extends AccessibilityService {
|
||||
if (viewID != null && viewID.toString().endsWith(":id/url_bar")) {
|
||||
CharSequence text = node.getText();
|
||||
if (text != null) {
|
||||
form.url = text.toString().trim();
|
||||
form.webDomain = text.toString().trim();
|
||||
}
|
||||
}
|
||||
if (form.packageName.isEmpty()) {
|
||||
CharSequence packageName = node.getPackageName();
|
||||
if (packageName != null) {
|
||||
form.packageName = packageName.toString().trim();
|
||||
}
|
||||
}
|
||||
if (node.isEditable()) {
|
||||
@@ -128,6 +128,7 @@ public final class KeePassGOAccessibilityService extends AccessibilityService {
|
||||
walk(child, editables, form);
|
||||
}
|
||||
}
|
||||
form.matchTarget = AutofillFallbackTarget.resolve(form.packageName, form.webDomain);
|
||||
}
|
||||
|
||||
private static boolean isPasswordNode(AccessibilityNodeInfo node) {
|
||||
@@ -188,7 +189,9 @@ public final class KeePassGOAccessibilityService extends AccessibilityService {
|
||||
}
|
||||
|
||||
private static final class ChromeForm {
|
||||
String url = "";
|
||||
String packageName = "";
|
||||
String webDomain = "";
|
||||
String matchTarget = "";
|
||||
AccessibilityNodeInfo usernameField;
|
||||
AccessibilityNodeInfo passwordField;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user