mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 18:58:59 +03:00
BIT-1316: Add compatibility for browser apps (#796)
This commit is contained in:
parent
0818638273
commit
f2d90dda55
14 changed files with 715 additions and 284 deletions
|
@ -11,17 +11,11 @@ sealed class AutofillView {
|
|||
* The data important to a given [AutofillView].
|
||||
*
|
||||
* @param autofillId The [AutofillId] associated with this view.
|
||||
* @param idPackage The package id for this view, if there is one.
|
||||
* @param isFocused Whether the view is currently focused.
|
||||
* @param webDomain The web domain for this view, if there is one. (example: m.facebook.com)
|
||||
* @param webScheme The web scheme for this view, if there is one. (example: https)
|
||||
*/
|
||||
data class Data(
|
||||
val autofillId: AutofillId,
|
||||
val idPackage: String?,
|
||||
val isFocused: Boolean,
|
||||
val webDomain: String?,
|
||||
val webScheme: String?,
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,8 +4,15 @@ import android.view.autofill.AutofillId
|
|||
|
||||
/**
|
||||
* A convenience data structure for view node traversal.
|
||||
*
|
||||
* @param autofillViews The list of views we care about for autofilling.
|
||||
* @param idPackage The package id for this view, if there is one.
|
||||
* @param ignoreAutofillIds The list of [AutofillId]s that should be ignored in the fill response.
|
||||
* @param website The website that is being displayed in the app, given there is one.
|
||||
*/
|
||||
data class ViewNodeTraversalData(
|
||||
val autofillViews: List<AutofillView>,
|
||||
val idPackage: String?,
|
||||
val ignoreAutofillIds: List<AutofillId>,
|
||||
val website: String?,
|
||||
)
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.x8bit.bitwarden.data.autofill.util.buildUriOrNull
|
|||
import com.x8bit.bitwarden.data.autofill.util.getInlinePresentationSpecs
|
||||
import com.x8bit.bitwarden.data.autofill.util.getMaxInlineSuggestionsCount
|
||||
import com.x8bit.bitwarden.data.autofill.util.toAutofillView
|
||||
import com.x8bit.bitwarden.data.autofill.util.website
|
||||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
|
||||
/**
|
||||
|
@ -119,6 +120,8 @@ private fun AssistStructure.ViewNode.traverse(): ViewNodeTraversalData {
|
|||
// Set up mutable lists for collecting valid AutofillViews and ignorable view ids.
|
||||
val mutableAutofillViewList: MutableList<AutofillView> = mutableListOf()
|
||||
val mutableIgnoreAutofillIdList: MutableList<AutofillId> = mutableListOf()
|
||||
var idPackage: String? = this.idPackage
|
||||
var website: String? = this.website
|
||||
|
||||
// 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`.
|
||||
|
@ -134,6 +137,15 @@ private fun AssistStructure.ViewNode.traverse(): ViewNodeTraversalData {
|
|||
.let { viewNodeTraversalData ->
|
||||
viewNodeTraversalData.autofillViews.forEach(mutableAutofillViewList::add)
|
||||
viewNodeTraversalData.ignoreAutofillIds.forEach(mutableIgnoreAutofillIdList::add)
|
||||
|
||||
// Get the first non-null idPackage.
|
||||
if (idPackage.isNullOrBlank()) {
|
||||
idPackage = viewNodeTraversalData.idPackage
|
||||
}
|
||||
// Get the first non-null website.
|
||||
if (website == null) {
|
||||
website = viewNodeTraversalData.website
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,6 +153,8 @@ private fun AssistStructure.ViewNode.traverse(): ViewNodeTraversalData {
|
|||
// descendant's.
|
||||
return ViewNodeTraversalData(
|
||||
autofillViews = mutableAutofillViewList,
|
||||
idPackage = idPackage,
|
||||
ignoreAutofillIds = mutableIgnoreAutofillIdList,
|
||||
website = website,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,12 +3,18 @@ package com.x8bit.bitwarden.data.autofill.util
|
|||
import android.app.assist.AssistStructure
|
||||
import android.view.View
|
||||
import com.x8bit.bitwarden.data.autofill.model.AutofillView
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank
|
||||
|
||||
/**
|
||||
* The class name of the android edit text field.
|
||||
*/
|
||||
private const val ANDROID_EDIT_TEXT_CLASS_NAME: String = "android.widget.EditText"
|
||||
|
||||
/**
|
||||
* The default web URI scheme.
|
||||
*/
|
||||
private const val DEFAULT_SCHEME: String = "https"
|
||||
|
||||
/**
|
||||
* The set of raw autofill hints that should be ignored.
|
||||
*/
|
||||
|
@ -72,10 +78,7 @@ fun AssistStructure.ViewNode.toAutofillView(): AutofillView? =
|
|||
if (supportedHint != null || this.isInputField) {
|
||||
val autofillViewData = AutofillView.Data(
|
||||
autofillId = nonNullAutofillId,
|
||||
idPackage = idPackage,
|
||||
isFocused = isFocused,
|
||||
webDomain = webDomain,
|
||||
webScheme = webScheme,
|
||||
)
|
||||
buildAutofillView(
|
||||
autofillViewData = autofillViewData,
|
||||
|
@ -164,3 +167,22 @@ fun AssistStructure.ViewNode.isUsernameField(
|
|||
inputType.isUsernameInputType ||
|
||||
idEntry?.containsAnyTerms(SUPPORTED_RAW_USERNAME_HINTS) == true ||
|
||||
hint?.containsAnyTerms(SUPPORTED_RAW_USERNAME_HINTS) == true
|
||||
|
||||
/**
|
||||
* The website that this [AssistStructure.ViewNode] is a part of representing.
|
||||
*/
|
||||
val AssistStructure.ViewNode.website: String?
|
||||
get() = this
|
||||
.webDomain
|
||||
.takeUnless { it?.isBlank() == true }
|
||||
?.let { webDomain ->
|
||||
val webScheme = this
|
||||
.webScheme
|
||||
.orNullIfBlank()
|
||||
?: DEFAULT_SCHEME
|
||||
|
||||
buildUri(
|
||||
domain = webDomain,
|
||||
scheme = webScheme,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,11 +9,6 @@ import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank
|
|||
*/
|
||||
private const val ANDROID_APP_SCHEME: String = "androidapp"
|
||||
|
||||
/**
|
||||
* The default web URI scheme.
|
||||
*/
|
||||
private const val DEFAULT_SCHEME: String = "https"
|
||||
|
||||
/**
|
||||
* Try and build a URI. The try progression looks like this:
|
||||
* 1. Try searching traversal data for website URIs.
|
||||
|
@ -25,13 +20,17 @@ fun List<ViewNodeTraversalData>.buildUriOrNull(
|
|||
assistStructure: AssistStructure,
|
||||
): String? {
|
||||
// Search list of [ViewNodeTraversalData] for a website URI.
|
||||
buildWebsiteUriOrNull()
|
||||
this
|
||||
.firstOrNull { it.website != null }
|
||||
?.website
|
||||
?.let { websiteUri ->
|
||||
return websiteUri
|
||||
}
|
||||
|
||||
// Search list of [ViewNodeTraversalData] for a valid package name.
|
||||
buildPackageNameOrNull()
|
||||
this
|
||||
.firstOrNull { it.idPackage != null }
|
||||
?.idPackage
|
||||
?.let { packageName ->
|
||||
return buildUri(
|
||||
domain = packageName,
|
||||
|
@ -53,7 +52,7 @@ fun List<ViewNodeTraversalData>.buildUriOrNull(
|
|||
/**
|
||||
* Combine [domain] and [scheme] into a URI.
|
||||
*/
|
||||
private fun buildUri(
|
||||
fun buildUri(
|
||||
domain: String,
|
||||
scheme: String,
|
||||
): String = "$scheme://$domain"
|
||||
|
@ -74,29 +73,3 @@ private fun AssistStructure.buildPackageNameOrNull(): String? = if (windowNodeCo
|
|||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
/**
|
||||
* Search each [ViewNodeTraversalData.autofillViews] list for a valid package id. If one is found
|
||||
* return it and terminate the search.
|
||||
*/
|
||||
private fun List<ViewNodeTraversalData>.buildPackageNameOrNull(): String? =
|
||||
flatMap { it.autofillViews }
|
||||
.firstOrNull { !it.data.idPackage.isNullOrEmpty() }
|
||||
?.data
|
||||
?.idPackage
|
||||
|
||||
/**
|
||||
* Search each [ViewNodeTraversalData.autofillViews] list for a valid web domain. If one is found,
|
||||
* combine it with its scheme and return it.
|
||||
*/
|
||||
private fun List<ViewNodeTraversalData>.buildWebsiteUriOrNull(): String? =
|
||||
flatMap { it.autofillViews }
|
||||
.firstOrNull { !it.data.webDomain.isNullOrEmpty() }
|
||||
?.let { autofillView ->
|
||||
val webDomain = requireNotNull(autofillView.data.webDomain)
|
||||
val webScheme = autofillView.data.webScheme.orNullIfBlank() ?: DEFAULT_SCHEME
|
||||
buildUri(
|
||||
domain = webDomain,
|
||||
scheme = webScheme,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,278 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<autofill-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:supportsInlineSuggestions="true" />
|
||||
android:supportsInlineSuggestions="true">
|
||||
<!--
|
||||
These compatibility packages must be kept in sync with
|
||||
/xml/autofill_service_configuration.xml
|
||||
-->
|
||||
<compatibility-package
|
||||
android:name="alook.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="alook.browser.google"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="app.vanadium.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.amazon.cloud9"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.android.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.android.chrome"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.android.htmlviewer"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.avast.android.secure.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.avg.android.secure.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser_beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser_default"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser_dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser_nightly"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.chrome.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.chrome.canary"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.chrome.dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.cookiegames.smartcookie"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.cookiejarapps.android.smartcookieweb"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.ecosia.android"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.google.android.apps.chrome"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.google.android.apps.chrome_dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.google.android.captiveportallogin"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.iode.firefox"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.jamal2367.styx"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.kiwibrowser.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.kiwibrowser.browser.dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.lemurbrowser.exts"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx.canary"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx.dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.mmbox.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.mmbox.xbrowser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.mycompany.app.soulbrowser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.naver.whale"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.neeva.app"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.browser.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.gx"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.mini.native"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.mini.native.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.touch"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.qflair.browserq"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.qwant.liberty"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.rainsee.create"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.sec.android.app.sbrowser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.sec.android.app.sbrowser.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.stoutner.privacybrowser.free"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.stoutner.privacybrowser.standard"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.vivaldi.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.vivaldi.browser.snapshot"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.vivaldi.browser.sopranos"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.yandex.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.yjllq.internet"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.yjllq.kito"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.yujian.ResideMenuDemo"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.z28j.feel"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="idm.internet.download.manager"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="idm.internet.download.manager.adm.lite"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="idm.internet.download.manager.plus"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="io.github.forkmaintainers.iceraven"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="mark.via"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="mark.via.gp"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.dezor.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.download"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.download.debug"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.playstore"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.playstore.debug"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.adblockplus.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.adblockplus.browser.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.bromite.bromite"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.bromite.chromium"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.chromium.chrome"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.codeaurora.swe.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.cromite.cromite"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.gnu.icecat"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fenix"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fenix.nightly"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fennec_aurora"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fennec_fdroid"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.firefox"
|
||||
android:maxLongVersionCode="2015836711" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.firefox_beta"
|
||||
android:maxLongVersionCode="2015849447" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.reference.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.rocket"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.torproject.torbrowser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.torproject.torbrowser_alpha"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.ungoogled.chromium.extensions.stable"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.ungoogled.chromium.stable"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="us.spotco.fennec_dos"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
</autofill-service>
|
||||
|
|
|
@ -1,2 +1,277 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<autofill-service />
|
||||
<autofill-service xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!--
|
||||
These compatibility packages must be kept in sync with
|
||||
/xml-v30/autofill_service_configuration.xml
|
||||
-->
|
||||
<compatibility-package
|
||||
android:name="alook.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="alook.browser.google"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="app.vanadium.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.amazon.cloud9"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.android.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.android.chrome"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.android.htmlviewer"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.avast.android.secure.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.avg.android.secure.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser_beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser_default"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser_dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.brave.browser_nightly"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.chrome.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.chrome.canary"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.chrome.dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.cookiegames.smartcookie"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.cookiejarapps.android.smartcookieweb"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.ecosia.android"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.google.android.apps.chrome"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.google.android.apps.chrome_dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.google.android.captiveportallogin"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.iode.firefox"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.jamal2367.styx"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.kiwibrowser.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.kiwibrowser.browser.dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.lemurbrowser.exts"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx.canary"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx.dev"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.mmbox.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.mmbox.xbrowser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.mycompany.app.soulbrowser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.naver.whale"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.neeva.app"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.browser.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.gx"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.mini.native"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.mini.native.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.opera.touch"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.qflair.browserq"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.qwant.liberty"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.rainsee.create"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.sec.android.app.sbrowser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.sec.android.app.sbrowser.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.stoutner.privacybrowser.free"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.stoutner.privacybrowser.standard"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.vivaldi.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.vivaldi.browser.snapshot"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.vivaldi.browser.sopranos"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.yandex.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.yjllq.internet"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.yjllq.kito"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.yujian.ResideMenuDemo"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="com.z28j.feel"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="idm.internet.download.manager"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="idm.internet.download.manager.adm.lite"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="idm.internet.download.manager.plus"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="io.github.forkmaintainers.iceraven"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="mark.via"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="mark.via.gp"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.dezor.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.download"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.download.debug"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.playstore"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.playstore.debug"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.adblockplus.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.adblockplus.browser.beta"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.bromite.bromite"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.bromite.chromium"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.chromium.chrome"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.codeaurora.swe.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.cromite.cromite"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.gnu.icecat"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fenix"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fenix.nightly"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fennec_aurora"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.fennec_fdroid"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.firefox"
|
||||
android:maxLongVersionCode="2015836711" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.firefox_beta"
|
||||
android:maxLongVersionCode="2015849447" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.reference.browser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.mozilla.rocket"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.torproject.torbrowser"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.torproject.torbrowser_alpha"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.ungoogled.chromium.extensions.stable"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="org.ungoogled.chromium.stable"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
<compatibility-package
|
||||
android:name="us.spotco.fennec_dos"
|
||||
android:maxLongVersionCode="10000000000" />
|
||||
</autofill-service>
|
||||
|
|
|
@ -111,10 +111,7 @@ class FillResponseBuilderTest {
|
|||
AutofillView.Login.Username(
|
||||
data = AutofillView.Data(
|
||||
autofillId = mockk(),
|
||||
idPackage = null,
|
||||
isFocused = true,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -35,10 +35,7 @@ class FilledDataBuilderTest {
|
|||
private val autofillId: AutofillId = mockk()
|
||||
private val autofillViewData = AutofillView.Data(
|
||||
autofillId = autofillId,
|
||||
idPackage = null,
|
||||
isFocused = false,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
)
|
||||
|
||||
@BeforeEach
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.x8bit.bitwarden.data.autofill.util.buildUriOrNull
|
|||
import com.x8bit.bitwarden.data.autofill.util.getInlinePresentationSpecs
|
||||
import com.x8bit.bitwarden.data.autofill.util.getMaxInlineSuggestionsCount
|
||||
import com.x8bit.bitwarden.data.autofill.util.toAutofillView
|
||||
import com.x8bit.bitwarden.data.autofill.util.website
|
||||
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
|
@ -30,13 +31,6 @@ class AutofillParserTests {
|
|||
private lateinit var parser: AutofillParser
|
||||
|
||||
private val autofillAppInfo: AutofillAppInfo = mockk()
|
||||
private val autofillViewData = AutofillView.Data(
|
||||
autofillId = mockk(),
|
||||
isFocused = true,
|
||||
idPackage = null,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
)
|
||||
private val assistStructure: AssistStructure = mockk()
|
||||
private val cardAutofillHint = View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR
|
||||
private val cardAutofillId: AutofillId = mockk()
|
||||
|
@ -44,6 +38,7 @@ class AutofillParserTests {
|
|||
every { this@mockk.autofillHints } returns arrayOf(cardAutofillHint)
|
||||
every { this@mockk.autofillId } returns cardAutofillId
|
||||
every { this@mockk.childCount } returns 0
|
||||
every { this@mockk.idPackage } returns ID_PACKAGE
|
||||
}
|
||||
private val loginAutofillHint = View.AUTOFILL_HINT_USERNAME
|
||||
private val loginAutofillId: AutofillId = mockk()
|
||||
|
@ -51,6 +46,7 @@ class AutofillParserTests {
|
|||
every { this@mockk.autofillHints } returns arrayOf(loginAutofillHint)
|
||||
every { this@mockk.autofillId } returns loginAutofillId
|
||||
every { this@mockk.childCount } returns 0
|
||||
every { this@mockk.idPackage } returns ID_PACKAGE
|
||||
}
|
||||
private val cardWindowNode: AssistStructure.WindowNode = mockk {
|
||||
every { this@mockk.rootViewNode } returns cardViewNode
|
||||
|
@ -74,11 +70,14 @@ class AutofillParserTests {
|
|||
@BeforeEach
|
||||
fun setup() {
|
||||
mockkStatic(AssistStructure.ViewNode::toAutofillView)
|
||||
mockkStatic(AssistStructure.ViewNode::website)
|
||||
mockkStatic(
|
||||
FillRequest::getMaxInlineSuggestionsCount,
|
||||
FillRequest::getInlinePresentationSpecs,
|
||||
)
|
||||
mockkStatic(List<ViewNodeTraversalData>::buildUriOrNull)
|
||||
every { cardViewNode.website } returns WEBSITE
|
||||
every { loginViewNode.website } returns WEBSITE
|
||||
every {
|
||||
fillRequest.getInlinePresentationSpecs(
|
||||
autofillAppInfo = autofillAppInfo,
|
||||
|
@ -112,6 +111,7 @@ class AutofillParserTests {
|
|||
@AfterEach
|
||||
fun teardown() {
|
||||
unmockkStatic(AssistStructure.ViewNode::toAutofillView)
|
||||
unmockkStatic(AssistStructure.ViewNode::website)
|
||||
unmockkStatic(
|
||||
FillRequest::getMaxInlineSuggestionsCount,
|
||||
FillRequest::getInlinePresentationSpecs,
|
||||
|
@ -160,13 +160,15 @@ class AutofillParserTests {
|
|||
every { this@mockk.autofillHints } returns arrayOf(childAutofillHint)
|
||||
every { this@mockk.autofillId } returns childAutofillId
|
||||
every { this@mockk.childCount } returns 0
|
||||
every { this@mockk.idPackage } returns null
|
||||
every { this@mockk.isFocused } returns false
|
||||
every { this@mockk.toAutofillView() } returns null
|
||||
every { this@mockk.website } returns null
|
||||
}
|
||||
val parentAutofillHint = View.AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_YEAR
|
||||
val parentAutofillId: AutofillId = mockk()
|
||||
val parentAutofillView: AutofillView.Card = AutofillView.Card.ExpirationMonth(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = parentAutofillId,
|
||||
isFocused = true,
|
||||
),
|
||||
|
@ -174,9 +176,11 @@ class AutofillParserTests {
|
|||
val parentViewNode: AssistStructure.ViewNode = mockk {
|
||||
every { this@mockk.autofillHints } returns arrayOf(parentAutofillHint)
|
||||
every { this@mockk.autofillId } returns parentAutofillId
|
||||
every { this@mockk.idPackage } returns null
|
||||
every { this@mockk.toAutofillView() } returns parentAutofillView
|
||||
every { this@mockk.childCount } returns 1
|
||||
every { this@mockk.getChildAt(0) } returns childViewNode
|
||||
every { this@mockk.website } returns null
|
||||
}
|
||||
val windowNode: AssistStructure.WindowNode = mockk {
|
||||
every { this@mockk.rootViewNode } returns parentViewNode
|
||||
|
@ -220,13 +224,13 @@ class AutofillParserTests {
|
|||
// Setup
|
||||
setupAssistStructureWithAllAutofillViewTypes()
|
||||
val cardAutofillView: AutofillView.Card = AutofillView.Card.ExpirationMonth(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = cardAutofillId,
|
||||
isFocused = true,
|
||||
),
|
||||
)
|
||||
val loginAutofillView: AutofillView.Login = AutofillView.Login.Username(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = loginAutofillId,
|
||||
isFocused = false,
|
||||
),
|
||||
|
@ -270,13 +274,13 @@ class AutofillParserTests {
|
|||
// Setup
|
||||
setupAssistStructureWithAllAutofillViewTypes()
|
||||
val cardAutofillView: AutofillView.Card = AutofillView.Card.ExpirationMonth(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = cardAutofillId,
|
||||
isFocused = false,
|
||||
),
|
||||
)
|
||||
val loginAutofillView: AutofillView.Login = AutofillView.Login.Username(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = loginAutofillId,
|
||||
isFocused = true,
|
||||
),
|
||||
|
@ -320,13 +324,13 @@ class AutofillParserTests {
|
|||
// Setup
|
||||
setupAssistStructureWithAllAutofillViewTypes()
|
||||
val cardAutofillView: AutofillView.Card = AutofillView.Card.ExpirationMonth(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = cardAutofillId,
|
||||
isFocused = true,
|
||||
),
|
||||
)
|
||||
val loginAutofillView: AutofillView.Login = AutofillView.Login.Username(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = loginAutofillId,
|
||||
isFocused = true,
|
||||
),
|
||||
|
@ -371,13 +375,13 @@ class AutofillParserTests {
|
|||
mockIsInlineAutofillEnabled = false
|
||||
setupAssistStructureWithAllAutofillViewTypes()
|
||||
val cardAutofillView: AutofillView.Card = AutofillView.Card.ExpirationMonth(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = cardAutofillId,
|
||||
isFocused = true,
|
||||
),
|
||||
)
|
||||
val loginAutofillView: AutofillView.Login = AutofillView.Login.Username(
|
||||
data = autofillViewData.copy(
|
||||
data = AutofillView.Data(
|
||||
autofillId = loginAutofillId,
|
||||
isFocused = true,
|
||||
),
|
||||
|
@ -427,5 +431,7 @@ class AutofillParserTests {
|
|||
}
|
||||
}
|
||||
|
||||
private const val ID_PACKAGE: String = "com.x8bit.bitwarden"
|
||||
private const val MAX_INLINE_SUGGESTION_COUNT: Int = 42
|
||||
private const val URI: String = "androidapp://com.x8bit.bitwarden"
|
||||
private const val WEBSITE: String = "https://www.google.com"
|
||||
|
|
|
@ -19,10 +19,7 @@ class AutofillViewExtensionsTest {
|
|||
private val autofillValue: AutofillValue = mockk()
|
||||
private val autofillViewData = AutofillView.Data(
|
||||
autofillId = autofillId,
|
||||
idPackage = null,
|
||||
isFocused = false,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
)
|
||||
|
||||
@BeforeEach
|
||||
|
|
|
@ -69,10 +69,7 @@ class FilledDataExtensionsTest {
|
|||
AutofillView.Login.Username(
|
||||
data = AutofillView.Data(
|
||||
autofillId = autofillId,
|
||||
idPackage = null,
|
||||
isFocused = true,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -22,20 +22,14 @@ class ViewNodeExtensionsTest {
|
|||
private val expectedIsFocused = true
|
||||
private val autofillViewData = AutofillView.Data(
|
||||
autofillId = expectedAutofillId,
|
||||
idPackage = ID_PACKAGE,
|
||||
isFocused = expectedIsFocused,
|
||||
webDomain = WEB_DOMAIN,
|
||||
webScheme = WEB_SCHEME,
|
||||
)
|
||||
|
||||
private val viewNode: AssistStructure.ViewNode = mockk {
|
||||
every { this@mockk.autofillId } returns expectedAutofillId
|
||||
every { this@mockk.childCount } returns 0
|
||||
every { this@mockk.inputType } returns 1
|
||||
every { this@mockk.idPackage } returns ID_PACKAGE
|
||||
every { this@mockk.isFocused } returns expectedIsFocused
|
||||
every { this@mockk.webDomain } returns WEB_DOMAIN
|
||||
every { this@mockk.webScheme } returns WEB_SCHEME
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
|
@ -375,6 +369,80 @@ class ViewNodeExtensionsTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `website should return URI if domain and scheme are valid`() {
|
||||
// Setup
|
||||
val webDomain = "www.google.com"
|
||||
val webScheme = "http"
|
||||
val expected = "http://www.google.com"
|
||||
every { viewNode.webDomain } returns webDomain
|
||||
every { viewNode.webScheme } returns webScheme
|
||||
|
||||
// Test
|
||||
val actual = viewNode.website
|
||||
|
||||
// Verify
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `website should return URI with default scheme if domain is valid and scheme is null`() {
|
||||
// Setup
|
||||
val webDomain = "www.google.com"
|
||||
val webScheme = null
|
||||
val expected = "https://www.google.com"
|
||||
every { viewNode.webDomain } returns webDomain
|
||||
every { viewNode.webScheme } returns webScheme
|
||||
|
||||
// Test
|
||||
val actual = viewNode.website
|
||||
|
||||
// Verify
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `website should return URI with default scheme if domain is valid and scheme is blank`() {
|
||||
// Setup
|
||||
val webDomain = "www.google.com"
|
||||
val webScheme = " "
|
||||
val expected = "https://www.google.com"
|
||||
every { viewNode.webDomain } returns webDomain
|
||||
every { viewNode.webScheme } returns webScheme
|
||||
|
||||
// Test
|
||||
val actual = viewNode.website
|
||||
|
||||
// Verify
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `website should return null when domain is null`() {
|
||||
// Setup
|
||||
val webDomain = null
|
||||
every { viewNode.webDomain } returns webDomain
|
||||
|
||||
// Test
|
||||
val actual = viewNode.website
|
||||
|
||||
// Verify
|
||||
assertNull(actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `website should return null when domain is blank`() {
|
||||
// Setup
|
||||
val webDomain = " "
|
||||
every { viewNode.webDomain } returns webDomain
|
||||
|
||||
// Test
|
||||
val actual = viewNode.website
|
||||
|
||||
// Verify
|
||||
assertNull(actual)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up [viewNode] to be an input field but not supported.
|
||||
*/
|
||||
|
@ -391,9 +459,6 @@ class ViewNodeExtensionsTest {
|
|||
}
|
||||
|
||||
private const val ANDROID_EDIT_TEXT_CLASS_NAME: String = "android.widget.EditText"
|
||||
private const val ID_PACKAGE: String = "ID_PACKAGE"
|
||||
private const val WEB_DOMAIN: String = "WEB_DOMAIN"
|
||||
private const val WEB_SCHEME: String = "WEB_SCHEME"
|
||||
private val IGNORED_RAW_HINTS: List<String> = listOf(
|
||||
"search",
|
||||
"find",
|
||||
|
|
|
@ -6,7 +6,6 @@ import com.x8bit.bitwarden.data.autofill.model.ViewNodeTraversalData
|
|||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class ViewNodeTraversalDataExtensionsTest {
|
||||
|
@ -17,28 +16,18 @@ class ViewNodeTraversalDataExtensionsTest {
|
|||
}
|
||||
private val autofillViewData = AutofillView.Data(
|
||||
autofillId = mockk(),
|
||||
idPackage = null,
|
||||
isFocused = false,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `buildUriOrNull should return URI when contains valid domain and scheme`() {
|
||||
fun `buildUriOrNull should return website URI when present`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
webDomain = WEB_DOMAIN,
|
||||
webScheme = WEB_SCHEME,
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
autofillViews = emptyList(),
|
||||
idPackage = null,
|
||||
ignoreAutofillIds = emptyList(),
|
||||
website = WEBSITE,
|
||||
)
|
||||
val expected = "$WEB_SCHEME://$WEB_DOMAIN"
|
||||
|
||||
// Test
|
||||
val actual = listOf(viewNodeTraversalData).buildUriOrNull(
|
||||
|
@ -46,77 +35,17 @@ class ViewNodeTraversalDataExtensionsTest {
|
|||
)
|
||||
|
||||
// Verify
|
||||
assertEquals(expected, actual)
|
||||
assertEquals(WEBSITE, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `buildUriOrNull should return URI with default scheme when domain valid and scheme null`() {
|
||||
fun `buildUriOrNull should return idPackage URI when WEBSITE is null`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
webDomain = WEB_DOMAIN,
|
||||
webScheme = null,
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
ignoreAutofillIds = emptyList(),
|
||||
)
|
||||
val expected = "https://$WEB_DOMAIN"
|
||||
|
||||
// Test
|
||||
val actual = listOf(viewNodeTraversalData).buildUriOrNull(
|
||||
assistStructure = assistStructure,
|
||||
)
|
||||
|
||||
// Verify
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `buildUriOrNull should return URI with default scheme when domain valid and scheme empty`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
webDomain = WEB_DOMAIN,
|
||||
webScheme = "",
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
ignoreAutofillIds = emptyList(),
|
||||
)
|
||||
val expected = "https://$WEB_DOMAIN"
|
||||
|
||||
// Test
|
||||
val actual = listOf(viewNodeTraversalData).buildUriOrNull(
|
||||
assistStructure = assistStructure,
|
||||
)
|
||||
|
||||
// Verify
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `buildUriOrNull should return idPackage URI when domain is null`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
idPackage = ID_PACKAGE,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
autofillViews = emptyList(),
|
||||
idPackage = ID_PACKAGE,
|
||||
ignoreAutofillIds = emptyList(),
|
||||
website = null,
|
||||
)
|
||||
val expected = "androidapp://$ID_PACKAGE"
|
||||
|
||||
|
@ -130,47 +59,13 @@ class ViewNodeTraversalDataExtensionsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `buildUriOrNull should return idPackage URI when domain is empty`() {
|
||||
fun `buildUriOrNull should return title URI when website and idPackage are null`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
idPackage = ID_PACKAGE,
|
||||
webDomain = "",
|
||||
webScheme = "",
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
ignoreAutofillIds = emptyList(),
|
||||
)
|
||||
val expected = "androidapp://$ID_PACKAGE"
|
||||
|
||||
// Test
|
||||
val actual = listOf(viewNodeTraversalData).buildUriOrNull(
|
||||
assistStructure = assistStructure,
|
||||
)
|
||||
|
||||
// Verify
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `buildUriOrNull should return title URI when domain and idPackage are null`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
idPackage = null,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
autofillViews = emptyList(),
|
||||
idPackage = null,
|
||||
ignoreAutofillIds = emptyList(),
|
||||
website = null,
|
||||
)
|
||||
val expected = "androidapp://com.x8bit.bitwarden"
|
||||
every { windowNode.title } returns "com.x8bit.bitwarden/path.deeper.into.app"
|
||||
|
@ -184,91 +79,8 @@ class ViewNodeTraversalDataExtensionsTest {
|
|||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `buildUriOrNull should return title URI when domain and idPackage are empty`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
idPackage = "",
|
||||
webDomain = "",
|
||||
webScheme = null,
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
ignoreAutofillIds = emptyList(),
|
||||
)
|
||||
val expected = "androidapp://com.x8bit.bitwarden"
|
||||
every { windowNode.title } returns "com.x8bit.bitwarden/path.deeper.into.app"
|
||||
|
||||
// Test
|
||||
val actual = listOf(viewNodeTraversalData).buildUriOrNull(
|
||||
assistStructure = assistStructure,
|
||||
)
|
||||
|
||||
// Verify
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `buildUriOrNull should return null when title, domain, and idPackage are null`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
idPackage = null,
|
||||
webDomain = null,
|
||||
webScheme = null,
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
ignoreAutofillIds = emptyList(),
|
||||
)
|
||||
every { windowNode.title } returns null
|
||||
|
||||
// Test
|
||||
val actual = listOf(viewNodeTraversalData).buildUriOrNull(
|
||||
assistStructure = assistStructure,
|
||||
)
|
||||
|
||||
// Verify
|
||||
assertNull(actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `buildUriOrNull should return null when title, domain, and idPackage are empty`() {
|
||||
// Setup
|
||||
val autofillView = AutofillView.Card.Number(
|
||||
data = autofillViewData.copy(
|
||||
idPackage = "",
|
||||
webDomain = "",
|
||||
webScheme = null,
|
||||
),
|
||||
)
|
||||
val viewNodeTraversalData = ViewNodeTraversalData(
|
||||
autofillViews = listOf(
|
||||
autofillView,
|
||||
),
|
||||
ignoreAutofillIds = emptyList(),
|
||||
)
|
||||
every { windowNode.title } returns ""
|
||||
|
||||
// Test
|
||||
val actual = listOf(viewNodeTraversalData).buildUriOrNull(
|
||||
assistStructure = assistStructure,
|
||||
)
|
||||
|
||||
// Verify
|
||||
assertNull(actual)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ID_PACKAGE: String = "com.x8bit.bitwarden"
|
||||
private const val WEB_DOMAIN: String = "www.google.com"
|
||||
private const val WEB_SCHEME: String = "https"
|
||||
private const val WEBSITE: String = "https://www.google.com"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue