mirror of
https://github.com/aliasvault/aliasvault.git
synced 2025-12-23 22:28:22 -05:00
Improve android autofill matching logic for common usecases (#1332)
This commit is contained in:
@@ -80,7 +80,6 @@ class AutofillService : AutofillService() {
|
||||
safeCallback()
|
||||
return
|
||||
}
|
||||
|
||||
launchActivityForAutofill(fieldFinder) { response -> safeCallback(response) }
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unexpected error in onFillRequest", e)
|
||||
@@ -279,7 +278,7 @@ class AutofillService : AutofillService() {
|
||||
}
|
||||
}
|
||||
FieldType.EMAIL -> {
|
||||
if (credential.alias?.email != null) {
|
||||
if (credential.alias?.email != null && credential.alias.email.isNotEmpty()) {
|
||||
dataSetBuilder.setValue(
|
||||
field.first,
|
||||
AutofillValue.forText(credential.alias.email),
|
||||
@@ -290,7 +289,7 @@ class AutofillService : AutofillService() {
|
||||
} else if (!credential.username.isNullOrEmpty()) {
|
||||
presentationDisplayValue += " (${credential.username})"
|
||||
}
|
||||
} else if (credential.username != null) {
|
||||
} else if (!credential.username.isNullOrEmpty()) {
|
||||
dataSetBuilder.setValue(
|
||||
field.first,
|
||||
AutofillValue.forText(credential.username),
|
||||
@@ -304,7 +303,7 @@ class AutofillService : AutofillService() {
|
||||
}
|
||||
}
|
||||
FieldType.USERNAME -> {
|
||||
if (credential.username != null) {
|
||||
if (!credential.username.isNullOrEmpty()) {
|
||||
dataSetBuilder.setValue(
|
||||
field.first,
|
||||
AutofillValue.forText(credential.username),
|
||||
@@ -315,7 +314,7 @@ class AutofillService : AutofillService() {
|
||||
} else if ((credential.alias?.email ?: "").isNotEmpty()) {
|
||||
presentationDisplayValue += " (${credential.alias?.email})"
|
||||
}
|
||||
} else if (credential.alias?.email != null) {
|
||||
} else if (credential.alias?.email != null && credential.alias.email.isNotEmpty()) {
|
||||
dataSetBuilder.setValue(
|
||||
field.first,
|
||||
AutofillValue.forText(credential.alias.email),
|
||||
@@ -328,7 +327,7 @@ class AutofillService : AutofillService() {
|
||||
}
|
||||
else -> {
|
||||
// For unknown field types, try both email and username
|
||||
if (credential.alias?.email != null) {
|
||||
if (credential.alias?.email != null && credential.alias.email.isNotEmpty()) {
|
||||
dataSetBuilder.setValue(
|
||||
field.first,
|
||||
AutofillValue.forText(credential.alias.email),
|
||||
@@ -337,7 +336,7 @@ class AutofillService : AutofillService() {
|
||||
if (credential.alias.email.isNotEmpty()) {
|
||||
presentationDisplayValue += " (${credential.alias.email})"
|
||||
}
|
||||
} else if (credential.username != null) {
|
||||
} else if (!credential.username.isNullOrEmpty()) {
|
||||
dataSetBuilder.setValue(
|
||||
field.first,
|
||||
AutofillValue.forText(credential.username),
|
||||
|
||||
@@ -35,9 +35,9 @@ class FieldFinder(var structure: AssistStructure) {
|
||||
var foundPasswordField = false
|
||||
|
||||
/**
|
||||
* Whether a username field has been found.
|
||||
* List of undetected editable fields (not identified as password/username/email).
|
||||
*/
|
||||
var lastField: AutofillId? = null
|
||||
private val unknownFields = mutableListOf<AutofillId>()
|
||||
|
||||
/**
|
||||
* Parse the structure.
|
||||
@@ -49,6 +49,15 @@ class FieldFinder(var structure: AssistStructure) {
|
||||
val rootNode = windowNode.rootViewNode
|
||||
parseNode(rootNode)
|
||||
}
|
||||
|
||||
// If only a password field was found, but there is exactly one other undetected field,
|
||||
// assume it's the username/email field
|
||||
if (foundPasswordField && !foundUsernameField && unknownFields.size == 1) {
|
||||
val unknownFieldId = unknownFields.first()
|
||||
Log.d(TAG, "Found password field without username - promoting unknown field to USERNAME type")
|
||||
autofillableFields.add(Pair(unknownFieldId, FieldType.USERNAME))
|
||||
foundUsernameField = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +90,7 @@ class FieldFinder(var structure: AssistStructure) {
|
||||
/**
|
||||
* Determines if a field is most likely an email field, username field, password field, or unknown.
|
||||
*/
|
||||
fun determineFieldType(fieldId: AutofillId): FieldType {
|
||||
private fun determineFieldType(fieldId: AutofillId): FieldType {
|
||||
// Find the node in the structure
|
||||
val node = findNodeById(fieldId) ?: return FieldType.UNKNOWN
|
||||
|
||||
@@ -221,12 +230,15 @@ class FieldFinder(var structure: AssistStructure) {
|
||||
if (fieldType == FieldType.PASSWORD) {
|
||||
foundPasswordField = true
|
||||
autofillableFields.add(Pair(viewId, fieldType))
|
||||
Log.d(TAG, "Found PASSWORD field: ${node.idEntry}")
|
||||
} else if (fieldType == FieldType.USERNAME || fieldType == FieldType.EMAIL) {
|
||||
foundUsernameField = true
|
||||
autofillableFields.add(Pair(viewId, fieldType))
|
||||
Log.d(TAG, "Found ${fieldType.name} field: ${node.idEntry}")
|
||||
} else {
|
||||
// Store the last field we saw in case we need it for username detection
|
||||
lastField = viewId
|
||||
// Store undetected editable fields for potential username promotion
|
||||
unknownFields.add(viewId)
|
||||
Log.d(TAG, "Found UNKNOWN editable field: ${node.idEntry}, hint=${node.hint}, inputType=${node.inputType}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +275,9 @@ class FieldFinder(var structure: AssistStructure) {
|
||||
val hintContains = hint?.contains(pattern, ignoreCase = false) == true
|
||||
val contentContains = contentDescription?.contains(pattern, ignoreCase = false) == true
|
||||
|
||||
return idEntryContains || hintContains || contentContains
|
||||
if (idEntryContains || hintContains || contentContains) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
@@ -20,7 +20,7 @@ complexity:
|
||||
thresholdInObjects: 60
|
||||
CyclomaticComplexMethod:
|
||||
active: true
|
||||
threshold: 35
|
||||
threshold: 40
|
||||
NestedBlockDepth:
|
||||
active: true
|
||||
threshold: 5
|
||||
|
||||
Reference in New Issue
Block a user