diff options
Diffstat (limited to 'autofill-parser/src/main/java')
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]; |
