mirror of
https://github.com/bitwarden/android.git
synced 2026-10-22 19:13:34 -05:00
Chore: Add Autofill logging for debug purposes (#7450)
This commit is contained in:
1 parent
1f03415c0a
commit
dc8d32fbdd
6 files changed
+135
-7
No files matched your search
+3
-1
@@ -5,6 +5,7 @@ import android.view.accessibility.AccessibilityNodeInfo
|
||||
import androidx.core.net.toUri
|
||||
import com.x8bit.bitwarden.data.autofill.accessibility.manager.AccessibilityNodeInfoManager
|
||||
import com.x8bit.bitwarden.data.autofill.accessibility.model.FillableFields
|
||||
import com.x8bit.bitwarden.data.autofill.accessibility.parser.util.logAccessibilityNodeInfo
|
||||
import com.x8bit.bitwarden.data.autofill.accessibility.util.getSupportedBrowserOrNull
|
||||
import com.x8bit.bitwarden.data.autofill.accessibility.util.isEditText
|
||||
import com.x8bit.bitwarden.data.autofill.accessibility.util.toUriOrNull
|
||||
@@ -13,7 +14,7 @@ import com.x8bit.bitwarden.data.platform.util.hasHttpProtocol
|
||||
/**
|
||||
* The default implementation for the [AccessibilityParser].
|
||||
*/
|
||||
class AccessibilityParserImpl(
|
||||
internal class AccessibilityParserImpl(
|
||||
private val accessibilityNodeInfoManager: AccessibilityNodeInfoManager,
|
||||
) : AccessibilityParser {
|
||||
override fun parseForFillableFields(
|
||||
@@ -36,6 +37,7 @@ class AccessibilityParserImpl(
|
||||
}
|
||||
|
||||
override fun parseForUriOrPackageName(rootNode: AccessibilityNodeInfo): Uri? {
|
||||
rootNode.logAccessibilityNodeInfo(depth = 0)
|
||||
val packageName = rootNode.packageName.toString()
|
||||
val browser = packageName
|
||||
.getSupportedBrowserOrNull()
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.x8bit.bitwarden.data.autofill.accessibility.parser.util
|
||||
|
||||
import android.view.accessibility.AccessibilityNodeInfo
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.bitwarden.annotation.OmitFromCoverage
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Indicates whether Accessibility Autofill verbose logging is enabled or not. This should be
|
||||
* `false` unless you are actively debugging.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
internal const val ENABLE_ACCESSIBILITY_LOGS: Boolean = false
|
||||
|
||||
/**
|
||||
* Logs data about a [AccessibilityNodeInfo] that is currently being parsed.
|
||||
*/
|
||||
@OmitFromCoverage
|
||||
internal fun AccessibilityNodeInfo.logAccessibilityNodeInfo(depth: Int = 0) {
|
||||
if (!ENABLE_ACCESSIBILITY_LOGS) return
|
||||
Timber
|
||||
.tag(tag = "BitwardenAccessibilityAutofill")
|
||||
.v(message = "${" ".repeat(n = depth)} $this")
|
||||
for (i in 0..<this.childCount) {
|
||||
this.getChild(i)?.logAccessibilityNodeInfo(depth = depth + 1)
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,9 @@ import com.x8bit.bitwarden.data.autofill.model.AutofillPartition
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillRequest
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillView
|
||||
import com.x8bit.bitwarden.data.autofill.model.ViewNodeTraversalData
|
||||
import com.x8bit.bitwarden.data.autofill.parser.util.logViewNode
|
||||
import com.x8bit.bitwarden.data.autofill.parser.util.logWindowNodeEnd
|
||||
import com.x8bit.bitwarden.data.autofill.parser.util.logWindowNodeStart
|
||||
import com.x8bit.bitwarden.data.autofill.util.buildFillAssistViews
|
||||
import com.x8bit.bitwarden.data.autofill.util.buildPackageNameOrNull
|
||||
import com.x8bit.bitwarden.data.autofill.util.buildUriOrNull
|
||||
@@ -86,7 +89,7 @@ private val IDENTITY_FILL_ASSIST_CATEGORIES: List<String> = listOf(
|
||||
* The default [AutofillParser] implementation for the app. This is a tool for parsing autofill data
|
||||
* from the OS into domain models.
|
||||
*/
|
||||
class AutofillParserImpl(
|
||||
internal class AutofillParserImpl(
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val fillAssistManager: FillAssistManager,
|
||||
private val featureFlagManager: FeatureFlagManager,
|
||||
@@ -316,14 +319,17 @@ private fun AssistStructure.traverse(
|
||||
(0 until windowNodeCount)
|
||||
.map { getWindowNodeAt(it) }
|
||||
.mapNotNull { windowNode ->
|
||||
windowNode.logWindowNodeStart()
|
||||
windowNode
|
||||
.rootViewNode
|
||||
?.traverse(
|
||||
parentWebsite = null,
|
||||
isIdentityAutofillEnabled = isIdentityAutofillEnabled,
|
||||
depth = 1,
|
||||
)
|
||||
?.updateForMissingPasswordFields()
|
||||
?.updateForMissingUsernameFields()
|
||||
.also { windowNode.logWindowNodeEnd() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,6 +442,7 @@ private fun ViewNodeTraversalData.copyAndMapAutofillViews(
|
||||
private fun AssistStructure.ViewNode.traverse(
|
||||
parentWebsite: String?,
|
||||
isIdentityAutofillEnabled: Boolean,
|
||||
depth: Int,
|
||||
): ViewNodeTraversalData {
|
||||
// Set up mutable lists for collecting valid AutofillViews and ignorable view ids.
|
||||
val mutableAutofillViewList: MutableList<AutofillView> = mutableListOf()
|
||||
@@ -455,10 +462,11 @@ private fun AssistStructure.ViewNode.traverse(
|
||||
|
||||
// Try converting this `ViewNode` into an `AutofillView`. If a valid instance is returned, add
|
||||
// it to the list. Otherwise, ignore the `AutofillId` associated with this `ViewNode`.
|
||||
toAutofillView(
|
||||
parentWebsite = parentWebsite,
|
||||
isIdentityAutofillEnabled = isIdentityAutofillEnabled,
|
||||
)
|
||||
this
|
||||
.toAutofillView(
|
||||
parentWebsite = parentWebsite,
|
||||
isIdentityAutofillEnabled = isIdentityAutofillEnabled,
|
||||
)
|
||||
?.also { view ->
|
||||
if (view !is AutofillView.Unused) {
|
||||
claimedAutofillIds.add(view.data.autofillId)
|
||||
@@ -482,7 +490,7 @@ private fun AssistStructure.ViewNode.traverse(
|
||||
}
|
||||
}
|
||||
?: autofillId?.run(mutableIgnoreAutofillIdList::add)
|
||||
|
||||
this.logViewNode(depth = depth)
|
||||
// Recursively traverse all of this view node's children.
|
||||
for (i in 0 until childCount) {
|
||||
// Extract the traversal data from each child view node and add it to the lists.
|
||||
@@ -490,6 +498,7 @@ private fun AssistStructure.ViewNode.traverse(
|
||||
.traverse(
|
||||
parentWebsite = website,
|
||||
isIdentityAutofillEnabled = isIdentityAutofillEnabled,
|
||||
depth = depth + 1,
|
||||
)
|
||||
.let { viewNodeTraversalData ->
|
||||
// Ids already claimed by an ancestor's own view (e.g. a container-redirect
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.x8bit.bitwarden.data.autofill.parser.util
|
||||
|
||||
import android.app.assist.AssistStructure
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.bitwarden.annotation.OmitFromCoverage
|
||||
import com.x8bit.bitwarden.data.autofill.util.website
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Indicates whether Autofill verbose logging is enabled or not. This should be `false` unless
|
||||
* you are actively debugging.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
internal const val ENABLE_ASSIST_STRUCTURE_LOGS: Boolean = false
|
||||
|
||||
/**
|
||||
* Logs data about a [AssistStructure.WindowNode] that is about to be parsed.
|
||||
*/
|
||||
@OmitFromCoverage
|
||||
internal fun AssistStructure.WindowNode.logWindowNodeStart() {
|
||||
if (!ENABLE_ASSIST_STRUCTURE_LOGS) return
|
||||
Timber
|
||||
.tag(tag = "BitwardenAutofill")
|
||||
.v(
|
||||
message = buildString {
|
||||
append("START :: windowNode: ")
|
||||
append("${this@logWindowNodeStart.title} -- ")
|
||||
append("${this@logWindowNodeStart.displayId}")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs data about a [AssistStructure.WindowNode] that has just been parsed.
|
||||
*/
|
||||
@OmitFromCoverage
|
||||
internal fun AssistStructure.WindowNode.logWindowNodeEnd() {
|
||||
if (!ENABLE_ASSIST_STRUCTURE_LOGS) return
|
||||
Timber
|
||||
.tag(tag = "BitwardenAutofill")
|
||||
.v(
|
||||
message = buildString {
|
||||
append("END :: windowNode: ")
|
||||
append("${this@logWindowNodeEnd.title} -- ")
|
||||
append("${this@logWindowNodeEnd.displayId}")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs data about a [AssistStructure.ViewNode] that is currently being parsed.
|
||||
*/
|
||||
@OmitFromCoverage
|
||||
internal fun AssistStructure.ViewNode.logViewNode(depth: Int) {
|
||||
if (!ENABLE_ASSIST_STRUCTURE_LOGS) return
|
||||
Timber
|
||||
.tag(tag = "BitwardenAutofill")
|
||||
.v(
|
||||
message = buildString {
|
||||
append("${" ".repeat(n = depth)} ViewNode: ")
|
||||
append("${this@logViewNode.website} -- ")
|
||||
append("${this@logViewNode.className} -- ")
|
||||
append("${this@logViewNode.idEntry} -- ")
|
||||
append("${this@logViewNode.idPackage} -- ")
|
||||
append("${this@logViewNode.text} -- ")
|
||||
},
|
||||
)
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.x8bit.bitwarden.data.autofill.accessibility.parser.util
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class LogUtilsTest {
|
||||
@Test
|
||||
fun `accessibility autofill logs must be disabled`() {
|
||||
assertFalse(ENABLE_ACCESSIBILITY_LOGS)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.x8bit.bitwarden.data.autofill.parser.util
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class LogUtilTests {
|
||||
@Test
|
||||
fun `autofill logs must be disabled`() {
|
||||
assertFalse(ENABLE_ASSIST_STRUCTURE_LOGS)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user