aboutsummaryrefslogtreecommitdiffstats
path: root/autofill-parser/src
diff options
context:
space:
mode:
Diffstat (limited to 'autofill-parser/src')
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillFormParser.kt3
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt49
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillScenario.kt11
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategy.kt3
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt8
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt18
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt4
-rw-r--r--autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/PublicSuffixListCache.kt11
8 files changed, 20 insertions, 87 deletions
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillFormParser.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillFormParser.kt
index 3dc74f33..eba3b2bc 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillFormParser.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillFormParser.kt
@@ -11,7 +11,6 @@ import android.content.pm.PackageManager.ApplicationInfoFlags
import android.os.Build
import android.os.Bundle
import android.view.autofill.AutofillId
-import androidx.annotation.RequiresApi
import androidx.core.net.toUri
import logcat.logcat
@@ -69,7 +68,6 @@ public sealed class FormOrigin(public open val identifier: String) {
/**
* Manages the detection of fields to fill in an [AssistStructure] and determines the [FormOrigin].
*/
-@RequiresApi(Build.VERSION_CODES.O)
private class AutofillFormParser(
context: Context,
structure: AssistStructure,
@@ -200,7 +198,6 @@ public data class Credentials(val username: String?, val password: String?, val
* Represents a collection of fields in a specific app that can be filled or saved. This is the
* entry point to all fill and save features.
*/
-@RequiresApi(Build.VERSION_CODES.O)
public class FillableForm
private constructor(
public val formOrigin: FormOrigin,
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt
index 9ff646c9..b177b5c0 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillHelper.kt
@@ -15,7 +15,6 @@ import android.service.autofill.SaveCallback
import android.util.Base64
import android.view.autofill.AutofillId
import android.widget.Toast
-import androidx.annotation.RequiresApi
import java.security.MessageDigest
import logcat.LogPriority.ERROR
import logcat.logcat
@@ -56,24 +55,22 @@ public fun computeCertificatesHash(context: Context, appPackage: String): String
.signatures
.orEmpty()
val stableHashOld = stableHash(signaturesOld.map { it.toByteArray() })
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
- val info =
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- context.packageManager.getPackageInfo(
- appPackage,
- PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES.toLong()),
- )
- } else {
- context.packageManager.getPackageInfo(appPackage, PackageManager.GET_SIGNING_CERTIFICATES)
- }
- val signaturesNew =
- info.signingInfo?.signingCertificateHistory ?: info.signingInfo?.apkContentsSigners.orEmpty()
- val stableHashNew = stableHash(signaturesNew.map { it.toByteArray() })
- if (stableHashNew != stableHashOld)
- logcat("CertificatesHash", ERROR) {
- "Mismatch between old and new hash: $stableHashNew != $stableHashOld"
- }
- }
+ val info =
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ context.packageManager.getPackageInfo(
+ appPackage,
+ PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES.toLong()),
+ )
+ } else {
+ context.packageManager.getPackageInfo(appPackage, PackageManager.GET_SIGNING_CERTIFICATES)
+ }
+ val signaturesNew =
+ info.signingInfo?.signingCertificateHistory ?: info.signingInfo?.apkContentsSigners.orEmpty()
+ val stableHashNew = stableHash(signaturesNew.map { it.toByteArray() })
+ if (stableHashNew != stableHashOld)
+ logcat("CertificatesHash", ERROR) {
+ "Mismatch between old and new hash: $stableHashNew != $stableHashOld"
+ }
return stableHashOld
}
@@ -82,15 +79,12 @@ public fun computeCertificatesHash(context: Context, appPackage: String): String
* its `webDomain` and `webScheme`, if available.
*/
internal val AssistStructure.ViewNode.webOrigin: String?
- @RequiresApi(Build.VERSION_CODES.O)
get() =
webDomain?.let { domain ->
- val scheme =
- (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) webScheme else null) ?: "https"
+ val scheme = webScheme ?: "https"
"$scheme://$domain"
}
-@RequiresApi(Build.VERSION_CODES.O)
public class FixedSaveCallback(private val context: Context, private val callback: SaveCallback) {
private val applicationContext = context.applicationContext
@@ -120,13 +114,7 @@ public class FixedSaveCallback(private val context: Context, private val callbac
applicationContext.startIntentSender(intentSender, null, 0, 0, 0, options)
callback.onSuccess()
}
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> callback.onSuccess(intentSender)
- else -> {
- callback.onSuccess()
- // On SDKs < 28, we cannot advise the Autofill framework to launch the save intent in
- // the context of the app that triggered the save request. Hence, we launch it here.
- applicationContext.startIntentSender(intentSender, null, 0, 0, 0)
- }
+ else -> callback.onSuccess(intentSender)
}
}
}
@@ -147,7 +135,6 @@ private fun visitViewNode(
}
}
-@RequiresApi(Build.VERSION_CODES.O)
internal fun AssistStructure.findNodeByAutofillId(
autofillId: AutofillId
): AssistStructure.ViewNode? {
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillScenario.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillScenario.kt
index 8a5b7fe3..15faabde 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillScenario.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillScenario.kt
@@ -11,7 +11,6 @@ import android.service.autofill.Dataset
import android.service.autofill.Field
import android.view.autofill.AutofillId
import android.view.autofill.AutofillValue
-import androidx.annotation.RequiresApi
import androidx.core.os.BundleCompat
import logcat.LogPriority.ERROR
import logcat.asLog
@@ -30,7 +29,6 @@ public enum class AutofillAction {
* [FormField], [AssistStructure.ViewNode] or [AutofillId], depending on how much metadata about the
* field is needed and available in the particular situation.
*/
-@RequiresApi(Build.VERSION_CODES.O)
public sealed class AutofillScenario<out T : Any> {
public companion object {
@@ -187,7 +185,6 @@ public sealed class AutofillScenario<out T : Any> {
get() = username != null
}
-@RequiresApi(Build.VERSION_CODES.O)
internal data class ClassifiedAutofillScenario<T : Any>(
override val username: T?,
override val fillUsername: Boolean,
@@ -212,7 +209,6 @@ internal data class ClassifiedAutofillScenario<T : Any>(
get() = newPassword.ifEmpty { currentPassword }
}
-@RequiresApi(Build.VERSION_CODES.O)
internal data class GenericAutofillScenario<T : Any>(
override val username: T?,
override val fillUsername: Boolean,
@@ -236,7 +232,6 @@ internal data class GenericAutofillScenario<T : Any>(
get() = genericPassword
}
-@RequiresApi(Build.VERSION_CODES.O)
internal fun AutofillScenario<FormField>.passesOriginCheck(singleOriginMode: Boolean): Boolean {
return if (singleOriginMode) {
// In single origin mode, only the browsers URL bar (which is never filled) should have
@@ -249,7 +244,6 @@ internal fun AutofillScenario<FormField>.passesOriginCheck(singleOriginMode: Boo
}
}
-@RequiresApi(Build.VERSION_CODES.O)
@JvmName("fillWithAutofillId")
public fun Dataset.Builder.fillWith(
scenario: AutofillScenario<AutofillId>,
@@ -272,7 +266,6 @@ public fun Dataset.Builder.fillWith(
}
}
-@RequiresApi(Build.VERSION_CODES.O)
internal inline fun <T : Any, S : Any> AutofillScenario<T>.map(
transform: (T) -> S
): AutofillScenario<S> {
@@ -292,7 +285,6 @@ internal inline fun <T : Any, S : Any> AutofillScenario<T>.map(
return builder.build()
}
-@RequiresApi(Build.VERSION_CODES.O)
@JvmName("toBundleAutofillId")
internal fun AutofillScenario<AutofillId>.toBundle(): Bundle =
when (this) {
@@ -321,7 +313,6 @@ internal fun AutofillScenario<AutofillId>.toBundle(): Bundle =
}
}
-@RequiresApi(Build.VERSION_CODES.O)
public fun AutofillScenario<AutofillId>.recoverNodes(
structure: AssistStructure
): AutofillScenario<AssistStructure.ViewNode>? {
@@ -329,13 +320,11 @@ public fun AutofillScenario<AutofillId>.recoverNodes(
}
public val AutofillScenario<AssistStructure.ViewNode>.usernameValue: String?
- @RequiresApi(Build.VERSION_CODES.O)
get() {
val value = username?.autofillValue ?: return null
return if (value.isText) value.textValue.toString() else null
}
public val AutofillScenario<AssistStructure.ViewNode>.passwordValue: String?
- @RequiresApi(Build.VERSION_CODES.O)
get() {
val distinctValues =
passwordFieldsToSave
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategy.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategy.kt
index bc227bad..5e1cebad 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategy.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategy.kt
@@ -4,8 +4,6 @@
*/
package com.github.androidpasswordstore.autofillparser
-import android.os.Build
-import androidx.annotation.RequiresApi
import com.github.androidpasswordstore.autofillparser.CertaintyLevel.Certain
import com.github.androidpasswordstore.autofillparser.CertaintyLevel.Likely
@@ -22,7 +20,6 @@ private inline fun <T> Pair<T, T>.none(predicate: T.() -> Boolean) =
* The strategy used to detect [AutofillScenario] s; expressed using the DSL implemented in
* [AutofillDsl].
*/
-@RequiresApi(Build.VERSION_CODES.O)
internal val autofillStrategy = strategy {
// Match two new password fields, an optional current password field right below or above, and
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt
index 673c7466..a9b01f25 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/AutofillStrategyDsl.kt
@@ -4,14 +4,11 @@
*/
package com.github.androidpasswordstore.autofillparser
-import android.os.Build
-import androidx.annotation.RequiresApi
import logcat.LogPriority.WARN
import logcat.logcat
@DslMarker internal annotation class AutofillDsl
-@RequiresApi(Build.VERSION_CODES.O)
internal interface FieldMatcher {
fun match(fields: List<FormField>, alreadyMatched: List<FormField>): List<FormField>?
@@ -72,7 +69,6 @@ internal interface FieldMatcher {
}
}
-@RequiresApi(Build.VERSION_CODES.O)
internal class SingleFieldMatcher(
private val take: (FormField, List<FormField>) -> Boolean,
private val tieBreakers: List<(FormField, List<FormField>) -> Boolean>,
@@ -136,7 +132,6 @@ internal class SingleFieldMatcher(
}
}
-@RequiresApi(Build.VERSION_CODES.O)
private class PairOfFieldsMatcher(
private val take: (Pair<FormField, FormField>, List<FormField>) -> Boolean,
private val tieBreakers: List<(Pair<FormField, FormField>, List<FormField>) -> Boolean>,
@@ -174,7 +169,6 @@ private class PairOfFieldsMatcher(
}
}
-@RequiresApi(Build.VERSION_CODES.O)
internal class AutofillRule
private constructor(
private val matchers: List<AutofillRuleMatcher>,
@@ -384,7 +378,6 @@ private constructor(
}
}
-@RequiresApi(Build.VERSION_CODES.O)
internal class AutofillStrategy private constructor(private val rules: List<AutofillRule>) {
@AutofillDsl
@@ -436,6 +429,5 @@ internal class AutofillStrategy private constructor(private val rules: List<Auto
}
}
-@RequiresApi(Build.VERSION_CODES.O)
internal fun strategy(block: AutofillStrategy.Builder.() -> Unit) =
AutofillStrategy.Builder().apply(block).build()
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt
index de28cd80..2db02f51 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetection.kt
@@ -11,7 +11,6 @@ import android.content.pm.PackageManager.ResolveInfoFlags
import android.os.Build
import android.provider.Settings
import android.service.autofill.SaveInfo
-import androidx.annotation.RequiresApi
import androidx.core.net.toUri
/**
@@ -143,7 +142,6 @@ private fun getBrowserMultiOriginMethod(appPackage: String): BrowserMultiOriginM
* Some browsers may not issue save requests automatically and thus need
* `FLAG_SAVE_ON_ALL_VIEW_INVISIBLE` to be set.
*/
-@RequiresApi(Build.VERSION_CODES.O)
private val BROWSER_SAVE_FLAG =
mapOf(
"com.duckduckgo.mobile.android" to 0,
@@ -159,7 +157,6 @@ private val BROWSER_SAVE_FLAG =
"com.opera.touch" to 0,
)
-@RequiresApi(Build.VERSION_CODES.O)
private val BROWSER_SAVE_FLAG_IF_NO_ACCESSIBILITY =
mapOf(
"com.android.chrome" to SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE,
@@ -180,7 +177,6 @@ private fun isNoAccessibilityServiceEnabled(context: Context): Boolean {
.isNullOrEmpty()
}
-@RequiresApi(Build.VERSION_CODES.O)
private fun getBrowserSaveFlag(context: Context, appPackage: String): Int? =
BROWSER_SAVE_FLAG[appPackage]
?: BROWSER_SAVE_FLAG_IF_NO_ACCESSIBILITY[appPackage]?.takeIf {
@@ -192,7 +188,6 @@ internal data class BrowserAutofillSupportInfo(
val saveFlags: Int?,
)
-@RequiresApi(Build.VERSION_CODES.O)
internal fun getBrowserAutofillSupportInfoIfTrusted(
context: Context,
appPackage: String,
@@ -215,7 +210,6 @@ public enum class BrowserAutofillSupportLevel {
GeneralFillAndSave,
}
-@RequiresApi(Build.VERSION_CODES.O)
private fun getBrowserAutofillSupportLevel(
context: Context,
appPackage: String,
@@ -230,19 +224,9 @@ private fun getBrowserAutofillSupportLevel(
BrowserAutofillSupportLevel.PasswordFill
browserInfo.saveFlags == null -> BrowserAutofillSupportLevel.GeneralFill
else -> BrowserAutofillSupportLevel.GeneralFillAndSave
- }.takeUnless { supportLevel ->
- // On Android Oreo, only browsers with native Autofill support can be used with Password
- // Store
- // (compatibility mode is only available on Android Pie and higher). Since all known
- // browsers
- // with native Autofill support offer full save support as well, we reuse the list of those
- // browsers here.
- supportLevel != BrowserAutofillSupportLevel.GeneralFillAndSave &&
- Build.VERSION.SDK_INT < Build.VERSION_CODES.P
- } ?: BrowserAutofillSupportLevel.None
+ }
}
-@RequiresApi(Build.VERSION_CODES.O)
public fun getInstalledBrowsersWithAutofillSupportLevel(
context: Context
): List<Pair<String, BrowserAutofillSupportLevel>> {
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt
index 983a8f0a..b8df0664 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/FormField.kt
@@ -5,11 +5,9 @@
package com.github.androidpasswordstore.autofillparser
import android.app.assist.AssistStructure
-import android.os.Build
import android.text.InputType
import android.view.View
import android.view.autofill.AutofillId
-import androidx.annotation.RequiresApi
import androidx.autofill.HintConstants
import java.util.Locale
@@ -24,7 +22,6 @@ internal enum class CertaintyLevel {
* Represents a single potentially fillable or saveable field together with all meta data extracted
* from its [AssistStructure.ViewNode].
*/
-@RequiresApi(Build.VERSION_CODES.O)
internal class FormField(
node: AssistStructure.ViewNode,
private val index: Int,
@@ -91,7 +88,6 @@ internal class FormField(
.toSet()
.toList()
- @RequiresApi(Build.VERSION_CODES.O)
private fun isSupportedHint(hint: String?) = hint in HINTS_FILLABLE
private val EXCLUDED_TERMS =
diff --git a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/PublicSuffixListCache.kt b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/PublicSuffixListCache.kt
index 8eb113d5..d14358e8 100644
--- a/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/PublicSuffixListCache.kt
+++ b/autofill-parser/src/main/java/com/github/androidpasswordstore/autofillparser/PublicSuffixListCache.kt
@@ -6,7 +6,6 @@ package com.github.androidpasswordstore.autofillparser
import android.content.Context
import android.net.InetAddresses
-import android.os.Build
import android.util.Patterns
import kotlinx.coroutines.runBlocking
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
@@ -45,21 +44,13 @@ internal fun getPublicSuffixPlusOne(
// We do not check whether the domain actually exists (actually, not even whether its TLD
// exists). As long as we restrict ourselves to syntactically valid domain names,
// getPublicSuffixPlusOne will return non-colliding results.
- if (!Patterns.DOMAIN_NAME.matcher(domain).matches() || isNumericAddress(domain)) {
+ if (!Patterns.DOMAIN_NAME.matcher(domain).matches() || InetAddresses.isNumericAddress(domain)) {
domain
} else {
getCanonicalSuffix(context, domain, customSuffixes)
}
}
-private fun isNumericAddress(domain: String): Boolean {
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- InetAddresses.isNumericAddress(domain)
- } else {
- @Suppress("DEPRECATION") Patterns.IP_ADDRESS.matcher(domain).matches()
- }
-}
-
/**
* Returns:
* - [domain], if [domain] equals [suffix];