mirror of
https://github.com/android-password-store/Android-Password-Store
synced 2025-08-28 21:07:39 +00:00
Make autofill-parser API explicit and refactor (#1182)
This commit is contained in:
parent
1d13a1fbd6
commit
73648b39d0
@ -38,8 +38,7 @@ class AutofillResponseBuilder(form: FillableForm) {
|
||||
private val clientState = form.toClientState()
|
||||
|
||||
// We do not offer save when the only relevant field is a username field or there is no field.
|
||||
private val scenarioSupportsSave =
|
||||
scenario.fieldsToSave.minus(listOfNotNull(scenario.username)).isNotEmpty()
|
||||
private val scenarioSupportsSave = scenario.hasPasswordFieldsToSave
|
||||
private val canBeSaved = saveFlags != null && scenarioSupportsSave
|
||||
|
||||
private fun makeIntentDataset(
|
||||
@ -63,14 +62,14 @@ class AutofillResponseBuilder(form: FillableForm) {
|
||||
}
|
||||
|
||||
private fun makeMatchDataset(context: Context, file: File, imeSpec: InlinePresentationSpec?): Dataset? {
|
||||
if (scenario.fieldsToFillOn(AutofillAction.Match).isEmpty()) return null
|
||||
if (scenario.hasFieldsToFillOn(AutofillAction.Match)) return null
|
||||
val metadata = makeFillMatchMetadata(context, file)
|
||||
val intentSender = AutofillDecryptActivity.makeDecryptFileIntentSender(file, context)
|
||||
return makeIntentDataset(context, AutofillAction.Match, intentSender, metadata, imeSpec)
|
||||
}
|
||||
|
||||
private fun makeSearchDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? {
|
||||
if (scenario.fieldsToFillOn(AutofillAction.Search).isEmpty()) return null
|
||||
if (scenario.hasFieldsToFillOn(AutofillAction.Search)) return null
|
||||
val metadata = makeSearchAndFillMetadata(context)
|
||||
val intentSender =
|
||||
AutofillFilterView.makeMatchAndDecryptFileIntentSender(context, formOrigin)
|
||||
@ -78,14 +77,14 @@ class AutofillResponseBuilder(form: FillableForm) {
|
||||
}
|
||||
|
||||
private fun makeGenerateDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? {
|
||||
if (scenario.fieldsToFillOn(AutofillAction.Generate).isEmpty()) return null
|
||||
if (scenario.hasFieldsToFillOn(AutofillAction.Generate)) return null
|
||||
val metadata = makeGenerateAndFillMetadata(context)
|
||||
val intentSender = AutofillSaveActivity.makeSaveIntentSender(context, null, formOrigin)
|
||||
return makeIntentDataset(context, AutofillAction.Generate, intentSender, metadata, imeSpec)
|
||||
}
|
||||
|
||||
private fun makeFillOtpFromSmsDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? {
|
||||
if (scenario.fieldsToFillOn(AutofillAction.FillOtpFromSms).isEmpty()) return null
|
||||
if (scenario.hasFieldsToFillOn(AutofillAction.FillOtpFromSms)) return null
|
||||
if (!AutofillSmsActivity.shouldOfferFillFromSms(context)) return null
|
||||
val metadata = makeFillOtpFromSmsMetadata(context)
|
||||
val intentSender = AutofillSmsActivity.makeFillOtpFromSmsIntentSender(context)
|
||||
@ -131,10 +130,10 @@ class AutofillResponseBuilder(form: FillableForm) {
|
||||
private fun makeSaveInfo(): SaveInfo? {
|
||||
if (!canBeSaved) return null
|
||||
check(saveFlags != null)
|
||||
val idsToSave = scenario.fieldsToSave.map { it.autofillId }.toTypedArray()
|
||||
val idsToSave = scenario.fieldsToSave.toTypedArray()
|
||||
if (idsToSave.isEmpty()) return null
|
||||
var saveDataTypes = SaveInfo.SAVE_DATA_TYPE_PASSWORD
|
||||
if (scenario.username != null) {
|
||||
if (scenario.hasUsername) {
|
||||
saveDataTypes = saveDataTypes or SaveInfo.SAVE_DATA_TYPE_USERNAME
|
||||
}
|
||||
return SaveInfo.Builder(saveDataTypes, idsToSave).run {
|
||||
@ -202,7 +201,7 @@ class AutofillResponseBuilder(form: FillableForm) {
|
||||
clientState: Bundle,
|
||||
action: AutofillAction
|
||||
): Dataset {
|
||||
val scenario = AutofillScenario.fromBundle(clientState)
|
||||
val scenario = AutofillScenario.fromClientState(clientState)
|
||||
// Before Android P, Datasets used for fill-in had to come with a RemoteViews, even
|
||||
// though they are rarely shown.
|
||||
// FIXME: We should clone the original dataset here and add the credentials to be filled
|
||||
|
@ -108,7 +108,7 @@ class OreoAutofillService : AutofillService() {
|
||||
callback.onFailure(getString(R.string.oreo_autofill_save_internal_error))
|
||||
return
|
||||
}
|
||||
val scenario = AutofillScenario.fromBundle(clientState)?.recoverNodes(structure) ?: run {
|
||||
val scenario = AutofillScenario.fromClientState(clientState)?.recoverNodes(structure) ?: run {
|
||||
e { "Failed to recover client state or nodes from client state" }
|
||||
callback.onFailure(getString(R.string.oreo_autofill_save_internal_error))
|
||||
return
|
||||
|
@ -7,149 +7,31 @@ public final class com/github/androidpasswordstore/autofillparser/AutofillAction
|
||||
public static fun values ()[Lcom/github/androidpasswordstore/autofillparser/AutofillAction;
|
||||
}
|
||||
|
||||
public abstract interface annotation class com/github/androidpasswordstore/autofillparser/AutofillDsl : java/lang/annotation/Annotation {
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillHelperKt {
|
||||
public static final fun computeCertificatesHash (Landroid/content/Context;Ljava/lang/String;)Ljava/lang/String;
|
||||
public static final fun findNodeByAutofillId (Landroid/app/assist/AssistStructure;Landroid/view/autofill/AutofillId;)Landroid/app/assist/AssistStructure$ViewNode;
|
||||
public static final fun getWebOrigin (Landroid/app/assist/AssistStructure$ViewNode;)Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillRule {
|
||||
public synthetic fun <init> (Ljava/util/List;ZZLjava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun match (Ljava/util/List;Ljava/util/List;Ljava/util/List;ZZ)Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillRule$AutofillRuleMatcher {
|
||||
public fun <init> (Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;Lcom/github/androidpasswordstore/autofillparser/FieldMatcher;ZZ)V
|
||||
public final fun component1 ()Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
public final fun component2 ()Lcom/github/androidpasswordstore/autofillparser/FieldMatcher;
|
||||
public final fun component3 ()Z
|
||||
public final fun component4 ()Z
|
||||
public final fun copy (Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;Lcom/github/androidpasswordstore/autofillparser/FieldMatcher;ZZ)Lcom/github/androidpasswordstore/autofillparser/AutofillRule$AutofillRuleMatcher;
|
||||
public static synthetic fun copy$default (Lcom/github/androidpasswordstore/autofillparser/AutofillRule$AutofillRuleMatcher;Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;Lcom/github/androidpasswordstore/autofillparser/FieldMatcher;ZZILjava/lang/Object;)Lcom/github/androidpasswordstore/autofillparser/AutofillRule$AutofillRuleMatcher;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getMatchHidden ()Z
|
||||
public final fun getMatcher ()Lcom/github/androidpasswordstore/autofillparser/FieldMatcher;
|
||||
public final fun getOptional ()Z
|
||||
public final fun getType ()Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillRule$Builder {
|
||||
public static final field Companion Lcom/github/androidpasswordstore/autofillparser/AutofillRule$Builder$Companion;
|
||||
public fun <init> (ZZ)V
|
||||
public final fun build ()Lcom/github/androidpasswordstore/autofillparser/AutofillRule;
|
||||
public final fun currentPassword (ZZLkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun currentPassword$default (Lcom/github/androidpasswordstore/autofillparser/AutofillRule$Builder;ZZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public final fun genericPassword (ZLkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun genericPassword$default (Lcom/github/androidpasswordstore/autofillparser/AutofillRule$Builder;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public final fun getName ()Ljava/lang/String;
|
||||
public final fun newPassword (ZLkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun newPassword$default (Lcom/github/androidpasswordstore/autofillparser/AutofillRule$Builder;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public final fun otp (ZLkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun otp$default (Lcom/github/androidpasswordstore/autofillparser/AutofillRule$Builder;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public final fun setName (Ljava/lang/String;)V
|
||||
public final fun username (ZZLkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun username$default (Lcom/github/androidpasswordstore/autofillparser/AutofillRule$Builder;ZZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillRule$Builder$Companion {
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType : java/lang/Enum {
|
||||
public static final field CurrentPassword Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
public static final field GenericPassword Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
public static final field NewPassword Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
public static final field Otp Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
public static final field Username Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
public static fun valueOf (Ljava/lang/String;)Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
public static fun values ()[Lcom/github/androidpasswordstore/autofillparser/AutofillRule$FillableFieldType;
|
||||
}
|
||||
|
||||
public abstract class com/github/androidpasswordstore/autofillparser/AutofillScenario {
|
||||
public static final field BUNDLE_KEY_CURRENT_PASSWORD_IDS Ljava/lang/String;
|
||||
public static final field BUNDLE_KEY_FILL_USERNAME Ljava/lang/String;
|
||||
public static final field BUNDLE_KEY_GENERIC_PASSWORD_IDS Ljava/lang/String;
|
||||
public static final field BUNDLE_KEY_NEW_PASSWORD_IDS Ljava/lang/String;
|
||||
public static final field BUNDLE_KEY_OTP_ID Ljava/lang/String;
|
||||
public static final field BUNDLE_KEY_USERNAME_ID Ljava/lang/String;
|
||||
public static final field Companion Lcom/github/androidpasswordstore/autofillparser/AutofillScenario$Companion;
|
||||
public final fun fieldsToFillOn (Lcom/github/androidpasswordstore/autofillparser/AutofillAction;)Ljava/util/List;
|
||||
public final fun getAllFields ()Ljava/util/List;
|
||||
public abstract fun getAllPasswordFields ()Ljava/util/List;
|
||||
public final fun getFieldsToSave ()Ljava/util/List;
|
||||
public abstract fun getFillUsername ()Z
|
||||
public abstract fun getOtp ()Ljava/lang/Object;
|
||||
public abstract fun getPasswordFieldsToFillOnGenerate ()Ljava/util/List;
|
||||
public abstract fun getPasswordFieldsToFillOnMatch ()Ljava/util/List;
|
||||
public abstract fun getPasswordFieldsToFillOnSearch ()Ljava/util/List;
|
||||
public final fun getHasFieldsToSave ()Z
|
||||
public final fun getHasPasswordFieldsToSave ()Z
|
||||
public final fun getHasUsername ()Z
|
||||
public abstract fun getPasswordFieldsToSave ()Ljava/util/List;
|
||||
public abstract fun getUsername ()Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillScenario$Builder {
|
||||
public fun <init> ()V
|
||||
public final fun build ()Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;
|
||||
public final fun getCurrentPassword ()Ljava/util/List;
|
||||
public final fun getFillUsername ()Z
|
||||
public final fun getGenericPassword ()Ljava/util/List;
|
||||
public final fun getNewPassword ()Ljava/util/List;
|
||||
public final fun getOtp ()Ljava/lang/Object;
|
||||
public final fun getUsername ()Ljava/lang/Object;
|
||||
public final fun setFillUsername (Z)V
|
||||
public final fun setOtp (Ljava/lang/Object;)V
|
||||
public final fun setUsername (Ljava/lang/Object;)V
|
||||
public final fun hasFieldsToFillOn (Lcom/github/androidpasswordstore/autofillparser/AutofillAction;)Z
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillScenario$Companion {
|
||||
public final fun fromBundle (Landroid/os/Bundle;)Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;
|
||||
public final fun fromClientState (Landroid/os/Bundle;)Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillScenarioKt {
|
||||
public static final fun fillWithAutofillId (Landroid/service/autofill/Dataset$Builder;Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;Lcom/github/androidpasswordstore/autofillparser/AutofillAction;Lcom/github/androidpasswordstore/autofillparser/Credentials;)V
|
||||
public static final fun fillWithFormField (Landroid/service/autofill/Dataset$Builder;Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;Lcom/github/androidpasswordstore/autofillparser/AutofillAction;Lcom/github/androidpasswordstore/autofillparser/Credentials;)V
|
||||
public static final fun getPasswordValue (Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;)Ljava/lang/String;
|
||||
public static final fun getUsernameValue (Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;)Ljava/lang/String;
|
||||
public static final fun map (Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;Lkotlin/jvm/functions/Function1;)Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;
|
||||
public static final fun passesOriginCheck (Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;Z)Z
|
||||
public static final fun recoverNodes (Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;Landroid/app/assist/AssistStructure;)Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;
|
||||
public static final fun toBundleFormField (Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;)Landroid/os/Bundle;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillStrategy {
|
||||
public synthetic fun <init> (Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun match (Ljava/util/List;ZZ)Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillStrategy$Builder {
|
||||
public fun <init> ()V
|
||||
public final fun build ()Lcom/github/androidpasswordstore/autofillparser/AutofillStrategy;
|
||||
public final fun rule (ZZLkotlin/jvm/functions/Function1;)V
|
||||
public static synthetic fun rule$default (Lcom/github/androidpasswordstore/autofillparser/AutofillStrategy$Builder;ZZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillStrategyDslKt {
|
||||
public static final fun strategy (Lkotlin/jvm/functions/Function1;)Lcom/github/androidpasswordstore/autofillparser/AutofillStrategy;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/AutofillStrategyKt {
|
||||
public static final fun getAutofillStrategy ()Lcom/github/androidpasswordstore/autofillparser/AutofillStrategy;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/BrowserAutofillSupportInfo {
|
||||
public fun <init> (Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;Ljava/lang/Integer;)V
|
||||
public final fun component1 ()Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;
|
||||
public final fun component2 ()Ljava/lang/Integer;
|
||||
public final fun copy (Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;Ljava/lang/Integer;)Lcom/github/androidpasswordstore/autofillparser/BrowserAutofillSupportInfo;
|
||||
public static synthetic fun copy$default (Lcom/github/androidpasswordstore/autofillparser/BrowserAutofillSupportInfo;Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;Ljava/lang/Integer;ILjava/lang/Object;)Lcom/github/androidpasswordstore/autofillparser/BrowserAutofillSupportInfo;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getMultiOriginMethod ()Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;
|
||||
public final fun getSaveFlags ()Ljava/lang/Integer;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/BrowserAutofillSupportLevel : java/lang/Enum {
|
||||
@ -162,47 +44,6 @@ public final class com/github/androidpasswordstore/autofillparser/BrowserAutofil
|
||||
public static fun values ()[Lcom/github/androidpasswordstore/autofillparser/BrowserAutofillSupportLevel;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod : java/lang/Enum {
|
||||
public static final field Field Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;
|
||||
public static final field None Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;
|
||||
public static final field WebView Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;
|
||||
public static fun valueOf (Ljava/lang/String;)Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;
|
||||
public static fun values ()[Lcom/github/androidpasswordstore/autofillparser/BrowserMultiOriginMethod;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/CertaintyLevel : java/lang/Enum {
|
||||
public static final field Certain Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
public static final field Impossible Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
public static final field Likely Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
public static final field Possible Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
public static fun valueOf (Ljava/lang/String;)Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
public static fun values ()[Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/ClassifiedAutofillScenario : com/github/androidpasswordstore/autofillparser/AutofillScenario {
|
||||
public fun <init> (Ljava/lang/Object;ZLjava/lang/Object;Ljava/util/List;Ljava/util/List;)V
|
||||
public final fun component1 ()Ljava/lang/Object;
|
||||
public final fun component2 ()Z
|
||||
public final fun component3 ()Ljava/lang/Object;
|
||||
public final fun component4 ()Ljava/util/List;
|
||||
public final fun component5 ()Ljava/util/List;
|
||||
public final fun copy (Ljava/lang/Object;ZLjava/lang/Object;Ljava/util/List;Ljava/util/List;)Lcom/github/androidpasswordstore/autofillparser/ClassifiedAutofillScenario;
|
||||
public static synthetic fun copy$default (Lcom/github/androidpasswordstore/autofillparser/ClassifiedAutofillScenario;Ljava/lang/Object;ZLjava/lang/Object;Ljava/util/List;Ljava/util/List;ILjava/lang/Object;)Lcom/github/androidpasswordstore/autofillparser/ClassifiedAutofillScenario;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun getAllPasswordFields ()Ljava/util/List;
|
||||
public final fun getCurrentPassword ()Ljava/util/List;
|
||||
public fun getFillUsername ()Z
|
||||
public final fun getNewPassword ()Ljava/util/List;
|
||||
public fun getOtp ()Ljava/lang/Object;
|
||||
public fun getPasswordFieldsToFillOnGenerate ()Ljava/util/List;
|
||||
public fun getPasswordFieldsToFillOnMatch ()Ljava/util/List;
|
||||
public fun getPasswordFieldsToFillOnSearch ()Ljava/util/List;
|
||||
public fun getPasswordFieldsToSave ()Ljava/util/List;
|
||||
public fun getUsername ()Ljava/lang/Object;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/Credentials {
|
||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||
public final fun component1 ()Ljava/lang/String;
|
||||
@ -219,25 +60,9 @@ public final class com/github/androidpasswordstore/autofillparser/Credentials {
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/FeatureAndTrustDetectionKt {
|
||||
public static final fun getBrowserAutofillSupportInfoIfTrusted (Landroid/content/Context;Ljava/lang/String;)Lcom/github/androidpasswordstore/autofillparser/BrowserAutofillSupportInfo;
|
||||
public static final fun getInstalledBrowsersWithAutofillSupportLevel (Landroid/content/Context;)Ljava/util/List;
|
||||
}
|
||||
|
||||
public abstract interface class com/github/androidpasswordstore/autofillparser/FieldMatcher {
|
||||
public abstract fun match (Ljava/util/List;Ljava/util/List;)Ljava/util/List;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/FieldMatcher$Builder {
|
||||
public fun <init> ()V
|
||||
public final fun breakTieOnPair (Lkotlin/jvm/functions/Function2;)V
|
||||
public final fun breakTieOnSingle (Lkotlin/jvm/functions/Function2;)V
|
||||
public final fun build ()Lcom/github/androidpasswordstore/autofillparser/FieldMatcher;
|
||||
public final fun takePair (Lkotlin/jvm/functions/Function2;)V
|
||||
public static synthetic fun takePair$default (Lcom/github/androidpasswordstore/autofillparser/FieldMatcher$Builder;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
|
||||
public final fun takeSingle (Lkotlin/jvm/functions/Function2;)V
|
||||
public static synthetic fun takeSingle$default (Lcom/github/androidpasswordstore/autofillparser/FieldMatcher$Builder;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/FillableForm {
|
||||
public static final field Companion Lcom/github/androidpasswordstore/autofillparser/FillableForm$Companion;
|
||||
public synthetic fun <init> (Lcom/github/androidpasswordstore/autofillparser/FormOrigin;Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;Ljava/util/List;Ljava/lang/Integer;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
@ -259,39 +84,6 @@ public final class com/github/androidpasswordstore/autofillparser/FixedSaveCallb
|
||||
public final fun onSuccess (Landroid/content/IntentSender;)V
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/FormField {
|
||||
public static final field Companion Lcom/github/androidpasswordstore/autofillparser/FormField$Companion;
|
||||
public fun <init> (Landroid/app/assist/AssistStructure$ViewNode;IZLjava/lang/String;)V
|
||||
public synthetic fun <init> (Landroid/app/assist/AssistStructure$ViewNode;IZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun directlyFollows (Lcom/github/androidpasswordstore/autofillparser/FormField;)Z
|
||||
public final fun directlyFollows (Ljava/lang/Iterable;)Z
|
||||
public final fun directlyPrecedes (Lcom/github/androidpasswordstore/autofillparser/FormField;)Z
|
||||
public final fun directlyPrecedes (Ljava/lang/Iterable;)Z
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public final fun getAutofillId ()Landroid/view/autofill/AutofillId;
|
||||
public final fun getCouldBeTwoStepHiddenPassword ()Z
|
||||
public final fun getCouldBeTwoStepHiddenUsername ()Z
|
||||
public final fun getHasAutocompleteHintCurrentPassword ()Z
|
||||
public final fun getHasAutofillHintPassword ()Z
|
||||
public final fun getHasHintNewPassword ()Z
|
||||
public final fun getHasHintOtp ()Z
|
||||
public final fun getHasHintPassword ()Z
|
||||
public final fun getHasHintUsername ()Z
|
||||
public final fun getOtpCertainty ()Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
public final fun getPasswordCertainty ()Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
public final fun getRelevantField ()Z
|
||||
public final fun getUsernameCertainty ()Lcom/github/androidpasswordstore/autofillparser/CertaintyLevel;
|
||||
public final fun getWebOrigin ()Ljava/lang/String;
|
||||
public final fun getWebOriginToPassDown ()Ljava/lang/String;
|
||||
public fun hashCode ()I
|
||||
public final fun isFocused ()Z
|
||||
public final fun isVisible ()Z
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/FormField$Companion {
|
||||
}
|
||||
|
||||
public abstract class com/github/androidpasswordstore/autofillparser/FormOrigin {
|
||||
public static final field Companion Lcom/github/androidpasswordstore/autofillparser/FormOrigin$Companion;
|
||||
public synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
@ -327,55 +119,7 @@ public final class com/github/androidpasswordstore/autofillparser/FormOrigin$Web
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/GenericAutofillScenario : com/github/androidpasswordstore/autofillparser/AutofillScenario {
|
||||
public fun <init> (Ljava/lang/Object;ZLjava/lang/Object;Ljava/util/List;)V
|
||||
public final fun component1 ()Ljava/lang/Object;
|
||||
public final fun component2 ()Z
|
||||
public final fun component3 ()Ljava/lang/Object;
|
||||
public final fun component4 ()Ljava/util/List;
|
||||
public final fun copy (Ljava/lang/Object;ZLjava/lang/Object;Ljava/util/List;)Lcom/github/androidpasswordstore/autofillparser/GenericAutofillScenario;
|
||||
public static synthetic fun copy$default (Lcom/github/androidpasswordstore/autofillparser/GenericAutofillScenario;Ljava/lang/Object;ZLjava/lang/Object;Ljava/util/List;ILjava/lang/Object;)Lcom/github/androidpasswordstore/autofillparser/GenericAutofillScenario;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun getAllPasswordFields ()Ljava/util/List;
|
||||
public fun getFillUsername ()Z
|
||||
public final fun getGenericPassword ()Ljava/util/List;
|
||||
public fun getOtp ()Ljava/lang/Object;
|
||||
public fun getPasswordFieldsToFillOnGenerate ()Ljava/util/List;
|
||||
public fun getPasswordFieldsToFillOnMatch ()Ljava/util/List;
|
||||
public fun getPasswordFieldsToFillOnSearch ()Ljava/util/List;
|
||||
public fun getPasswordFieldsToSave ()Ljava/util/List;
|
||||
public fun getUsername ()Ljava/lang/Object;
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/PublicSuffixListCacheKt {
|
||||
public static final fun cachePublicSuffixList (Landroid/content/Context;)V
|
||||
public static final fun getCanonicalSuffix (Landroid/content/Context;Ljava/lang/String;Lkotlin/sequences/Sequence;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static final fun getPublicSuffixPlusOne (Landroid/content/Context;Ljava/lang/String;Lkotlin/sequences/Sequence;)Ljava/lang/String;
|
||||
public static final fun getSuffixPlusUpToOne (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/SingleFieldMatcher : com/github/androidpasswordstore/autofillparser/FieldMatcher {
|
||||
public fun <init> (Lkotlin/jvm/functions/Function2;Ljava/util/List;)V
|
||||
public fun match (Ljava/util/List;Ljava/util/List;)Ljava/util/List;
|
||||
}
|
||||
|
||||
public final class com/github/androidpasswordstore/autofillparser/SingleFieldMatcher$Builder {
|
||||
public fun <init> ()V
|
||||
public final fun breakTieOnSingle (Lkotlin/jvm/functions/Function2;)V
|
||||
public final fun build ()Lcom/github/androidpasswordstore/autofillparser/SingleFieldMatcher;
|
||||
public final fun takeSingle (Lkotlin/jvm/functions/Function2;)V
|
||||
public static synthetic fun takeSingle$default (Lcom/github/androidpasswordstore/autofillparser/SingleFieldMatcher$Builder;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class mozilla/components/lib/publicsuffixlist/PublicSuffixList {
|
||||
public fun <init> (Landroid/content/Context;Lkotlinx/coroutines/CoroutineDispatcher;Lkotlinx/coroutines/CoroutineScope;)V
|
||||
public synthetic fun <init> (Landroid/content/Context;Lkotlinx/coroutines/CoroutineDispatcher;Lkotlinx/coroutines/CoroutineScope;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public final fun getPublicSuffix (Ljava/lang/String;)Lkotlinx/coroutines/Deferred;
|
||||
public final fun getPublicSuffixPlusOne (Ljava/lang/String;)Lkotlinx/coroutines/Deferred;
|
||||
public final fun isPublicSuffix (Ljava/lang/String;)Lkotlinx/coroutines/Deferred;
|
||||
public final fun prefetch ()Lkotlinx/coroutines/Deferred;
|
||||
public final fun stripPublicSuffix (Ljava/lang/String;)Lkotlinx/coroutines/Deferred;
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,20 @@ fun getCredential(type: String): String {
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
versionCode = 2
|
||||
versionName = "2.0"
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
explicitApi()
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = freeCompilerArgs + listOf(
|
||||
"-Xexplicit-api=strict"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
|
@ -17,17 +17,17 @@ import com.github.ajalt.timberkt.d
|
||||
/**
|
||||
* A unique identifier for either an Android app (package name) or a website (origin minus port).
|
||||
*/
|
||||
sealed class FormOrigin(open val identifier: String) {
|
||||
public sealed class FormOrigin(public open val identifier: String) {
|
||||
|
||||
data class Web(override val identifier: String) : FormOrigin(identifier)
|
||||
data class App(override val identifier: String) : FormOrigin(identifier)
|
||||
public data class Web(override val identifier: String) : FormOrigin(identifier)
|
||||
public data class App(override val identifier: String) : FormOrigin(identifier)
|
||||
|
||||
companion object {
|
||||
public companion object {
|
||||
|
||||
private const val BUNDLE_KEY_WEB_IDENTIFIER = "webIdentifier"
|
||||
private const val BUNDLE_KEY_APP_IDENTIFIER = "appIdentifier"
|
||||
|
||||
fun fromBundle(bundle: Bundle): FormOrigin? {
|
||||
public fun fromBundle(bundle: Bundle): FormOrigin? {
|
||||
val webIdentifier = bundle.getString(BUNDLE_KEY_WEB_IDENTIFIER)
|
||||
if (webIdentifier != null) {
|
||||
return Web(webIdentifier)
|
||||
@ -37,18 +37,19 @@ sealed class FormOrigin(open val identifier: String) {
|
||||
}
|
||||
}
|
||||
|
||||
fun getPrettyIdentifier(context: Context, untrusted: Boolean = true) = when (this) {
|
||||
is Web -> identifier
|
||||
is App -> {
|
||||
val info = context.packageManager.getApplicationInfo(
|
||||
identifier, PackageManager.GET_META_DATA
|
||||
)
|
||||
val label = context.packageManager.getApplicationLabel(info)
|
||||
if (untrusted) "“$label”" else "$label"
|
||||
public fun getPrettyIdentifier(context: Context, untrusted: Boolean = true): String =
|
||||
when (this) {
|
||||
is Web -> identifier
|
||||
is App -> {
|
||||
val info = context.packageManager.getApplicationInfo(
|
||||
identifier, PackageManager.GET_META_DATA
|
||||
)
|
||||
val label = context.packageManager.getApplicationLabel(info)
|
||||
if (untrusted) "“$label”" else "$label"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun toBundle() = Bundle().apply {
|
||||
public fun toBundle(): Bundle = Bundle().apply {
|
||||
when (this@FormOrigin) {
|
||||
is Web -> putString(BUNDLE_KEY_WEB_IDENTIFIER, identifier)
|
||||
is App -> putString(BUNDLE_KEY_APP_IDENTIFIER, identifier)
|
||||
@ -183,24 +184,24 @@ private class AutofillFormParser(
|
||||
}
|
||||
}
|
||||
|
||||
data class Credentials(val username: String?, val password: String?, val otp: String?)
|
||||
public data class Credentials(val username: String?, val password: String?, val otp: String?)
|
||||
|
||||
/**
|
||||
* 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)
|
||||
class FillableForm private constructor(
|
||||
val formOrigin: FormOrigin,
|
||||
val scenario: AutofillScenario<FormField>,
|
||||
val ignoredIds: List<AutofillId>,
|
||||
val saveFlags: Int?
|
||||
public class FillableForm private constructor(
|
||||
public val formOrigin: FormOrigin,
|
||||
public val scenario: AutofillScenario<AutofillId>,
|
||||
public val ignoredIds: List<AutofillId>,
|
||||
public val saveFlags: Int?
|
||||
) {
|
||||
companion object {
|
||||
public companion object {
|
||||
/**
|
||||
* Returns a [FillableForm] if a login form could be detected in [structure].
|
||||
*/
|
||||
fun parseAssistStructure(
|
||||
public fun parseAssistStructure(
|
||||
context: Context,
|
||||
structure: AssistStructure,
|
||||
isManualRequest: Boolean,
|
||||
@ -208,11 +209,11 @@ class FillableForm private constructor(
|
||||
): FillableForm? {
|
||||
val form = AutofillFormParser(context, structure, isManualRequest, customSuffixes)
|
||||
if (form.formOrigin == null || form.scenario == null) return null
|
||||
return FillableForm(form.formOrigin, form.scenario, form.ignoredIds, form.saveFlags)
|
||||
return FillableForm(form.formOrigin, form.scenario.map { it.autofillId }, form.ignoredIds, form.saveFlags)
|
||||
}
|
||||
}
|
||||
|
||||
fun toClientState() = scenario.toBundle().apply {
|
||||
public fun toClientState(): Bundle = scenario.toBundle().apply {
|
||||
putAll(formOrigin.toBundle())
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ private fun stableHash(array: Collection<ByteArray>): String {
|
||||
* In most cases apps will only have a single certificate. If there are multiple, this functions
|
||||
* returns all of them in sorted order and separated with `;`.
|
||||
*/
|
||||
fun computeCertificatesHash(context: Context, appPackage: String): String {
|
||||
public fun computeCertificatesHash(context: Context, appPackage: String): String {
|
||||
// The warning does not apply since 1) we are specifically hashing **all** signatures and 2) it
|
||||
// no longer applies to Android 4.4+.
|
||||
// Even though there is a new way to get the certificates as of Android Pie, we need to keep
|
||||
@ -68,18 +68,18 @@ fun computeCertificatesHash(context: Context, appPackage: String): String {
|
||||
* Returns the "origin" (without port information) of the [AssistStructure.ViewNode] derived from
|
||||
* its `webDomain` and `webScheme`, if available.
|
||||
*/
|
||||
val AssistStructure.ViewNode.webOrigin: String?
|
||||
internal val AssistStructure.ViewNode.webOrigin: String?
|
||||
@RequiresApi(Build.VERSION_CODES.O) get() = webDomain?.let { domain ->
|
||||
val scheme = (if (Build.VERSION.SDK_INT >= 28) webScheme else null) ?: "https"
|
||||
"$scheme://$domain"
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class FixedSaveCallback(context: Context, private val callback: SaveCallback) {
|
||||
public class FixedSaveCallback(context: Context, private val callback: SaveCallback) {
|
||||
|
||||
private val applicationContext = context.applicationContext
|
||||
|
||||
fun onFailure(message: CharSequence) {
|
||||
public fun onFailure(message: CharSequence) {
|
||||
callback.onFailure(message)
|
||||
// When targeting SDK 29, the message is no longer shown as a toast.
|
||||
// See https://developer.android.com/reference/android/service/autofill/SaveCallback#onFailure(java.lang.CharSequence)
|
||||
@ -88,7 +88,7 @@ class FixedSaveCallback(context: Context, private val callback: SaveCallback) {
|
||||
}
|
||||
}
|
||||
|
||||
fun onSuccess(intentSender: IntentSender) {
|
||||
public fun onSuccess(intentSender: IntentSender) {
|
||||
if (Build.VERSION.SDK_INT >= 28) {
|
||||
callback.onSuccess(intentSender)
|
||||
} else {
|
||||
@ -117,7 +117,7 @@ private fun visitViewNode(
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun AssistStructure.findNodeByAutofillId(autofillId: AutofillId): AssistStructure.ViewNode? {
|
||||
internal fun AssistStructure.findNodeByAutofillId(autofillId: AutofillId): AssistStructure.ViewNode? {
|
||||
var node: AssistStructure.ViewNode? = null
|
||||
visitViewNodes(this) {
|
||||
if (it.autofillId == autofillId)
|
||||
|
@ -13,7 +13,7 @@ import android.view.autofill.AutofillValue
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.ajalt.timberkt.e
|
||||
|
||||
enum class AutofillAction {
|
||||
public enum class AutofillAction {
|
||||
Match, Search, Generate, FillOtpFromSms
|
||||
}
|
||||
|
||||
@ -24,18 +24,23 @@ enum class AutofillAction {
|
||||
* field is needed and available in the particular situation.
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
sealed class AutofillScenario<out T : Any> {
|
||||
public sealed class AutofillScenario<out T : Any> {
|
||||
|
||||
companion object {
|
||||
public companion object {
|
||||
|
||||
const val BUNDLE_KEY_USERNAME_ID = "usernameId"
|
||||
const val BUNDLE_KEY_FILL_USERNAME = "fillUsername"
|
||||
const val BUNDLE_KEY_OTP_ID = "otpId"
|
||||
const val BUNDLE_KEY_CURRENT_PASSWORD_IDS = "currentPasswordIds"
|
||||
const val BUNDLE_KEY_NEW_PASSWORD_IDS = "newPasswordIds"
|
||||
const val BUNDLE_KEY_GENERIC_PASSWORD_IDS = "genericPasswordIds"
|
||||
internal const val BUNDLE_KEY_USERNAME_ID = "usernameId"
|
||||
internal const val BUNDLE_KEY_FILL_USERNAME = "fillUsername"
|
||||
internal const val BUNDLE_KEY_OTP_ID = "otpId"
|
||||
internal const val BUNDLE_KEY_CURRENT_PASSWORD_IDS = "currentPasswordIds"
|
||||
internal const val BUNDLE_KEY_NEW_PASSWORD_IDS = "newPasswordIds"
|
||||
internal const val BUNDLE_KEY_GENERIC_PASSWORD_IDS = "genericPasswordIds"
|
||||
|
||||
fun fromBundle(clientState: Bundle): AutofillScenario<AutofillId>? {
|
||||
@Deprecated("Use `fromClientState` instead.", ReplaceWith("fromClientState(clientState)", "com.github.androidpasswordstore.autofillparser.AutofillScenario.Companion.fromClientState"))
|
||||
public fun fromBundle(clientState: Bundle): AutofillScenario<AutofillId>? {
|
||||
return fromClientState(clientState)
|
||||
}
|
||||
|
||||
public fun fromClientState(clientState: Bundle): AutofillScenario<AutofillId>? {
|
||||
return try {
|
||||
Builder<AutofillId>().apply {
|
||||
username = clientState.getParcelable(BUNDLE_KEY_USERNAME_ID)
|
||||
@ -64,7 +69,7 @@ sealed class AutofillScenario<out T : Any> {
|
||||
}
|
||||
}
|
||||
|
||||
class Builder<T : Any> {
|
||||
internal class Builder<T : Any> {
|
||||
|
||||
var username: T? = null
|
||||
var fillUsername = false
|
||||
@ -94,22 +99,23 @@ sealed class AutofillScenario<out T : Any> {
|
||||
}
|
||||
}
|
||||
|
||||
abstract val username: T?
|
||||
abstract val fillUsername: Boolean
|
||||
abstract val otp: T?
|
||||
abstract val allPasswordFields: List<T>
|
||||
abstract val passwordFieldsToFillOnMatch: List<T>
|
||||
abstract val passwordFieldsToFillOnSearch: List<T>
|
||||
abstract val passwordFieldsToFillOnGenerate: List<T>
|
||||
abstract val passwordFieldsToSave: List<T>
|
||||
public abstract val username: T?
|
||||
public abstract val passwordFieldsToSave: List<T>
|
||||
|
||||
val fieldsToSave
|
||||
internal abstract val otp: T?
|
||||
internal abstract val allPasswordFields: List<T>
|
||||
internal abstract val fillUsername: Boolean
|
||||
internal abstract val passwordFieldsToFillOnMatch: List<T>
|
||||
internal abstract val passwordFieldsToFillOnSearch: List<T>
|
||||
internal abstract val passwordFieldsToFillOnGenerate: List<T>
|
||||
|
||||
public val fieldsToSave: List<T>
|
||||
get() = listOfNotNull(username) + passwordFieldsToSave
|
||||
|
||||
val allFields
|
||||
internal val allFields: List<T>
|
||||
get() = listOfNotNull(username, otp) + allPasswordFields
|
||||
|
||||
fun fieldsToFillOn(action: AutofillAction): List<T> {
|
||||
internal fun fieldsToFillOn(action: AutofillAction): List<T> {
|
||||
val credentialFieldsToFill = when (action) {
|
||||
AutofillAction.Match -> passwordFieldsToFillOnMatch + listOfNotNull(otp)
|
||||
AutofillAction.Search -> passwordFieldsToFillOnSearch + listOfNotNull(otp)
|
||||
@ -134,10 +140,23 @@ sealed class AutofillScenario<out T : Any> {
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
public fun hasFieldsToFillOn(action: AutofillAction): Boolean {
|
||||
return fieldsToFillOn(action).isNotEmpty()
|
||||
}
|
||||
|
||||
public val hasFieldsToSave: Boolean
|
||||
get() = fieldsToSave.isNotEmpty()
|
||||
|
||||
public val hasPasswordFieldsToSave: Boolean
|
||||
get() = fieldsToSave.minus(listOfNotNull(username)).isNotEmpty()
|
||||
|
||||
public val hasUsername: Boolean
|
||||
get() = username != null
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
data class ClassifiedAutofillScenario<T : Any>(
|
||||
internal data class ClassifiedAutofillScenario<T : Any>(
|
||||
override val username: T?,
|
||||
override val fillUsername: Boolean,
|
||||
override val otp: T?,
|
||||
@ -158,7 +177,7 @@ data class ClassifiedAutofillScenario<T : Any>(
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
data class GenericAutofillScenario<T : Any>(
|
||||
internal data class GenericAutofillScenario<T : Any>(
|
||||
override val username: T?,
|
||||
override val fillUsername: Boolean,
|
||||
override val otp: T?,
|
||||
@ -177,7 +196,7 @@ data class GenericAutofillScenario<T : Any>(
|
||||
get() = genericPassword
|
||||
}
|
||||
|
||||
fun AutofillScenario<FormField>.passesOriginCheck(singleOriginMode: Boolean): Boolean {
|
||||
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
|
||||
// a webOrigin.
|
||||
@ -191,7 +210,7 @@ fun AutofillScenario<FormField>.passesOriginCheck(singleOriginMode: Boolean): Bo
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
@JvmName("fillWithAutofillId")
|
||||
fun Dataset.Builder.fillWith(
|
||||
public fun Dataset.Builder.fillWith(
|
||||
scenario: AutofillScenario<AutofillId>,
|
||||
action: AutofillAction,
|
||||
credentials: Credentials?
|
||||
@ -211,17 +230,7 @@ fun Dataset.Builder.fillWith(
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
@JvmName("fillWithFormField")
|
||||
fun Dataset.Builder.fillWith(
|
||||
scenario: AutofillScenario<FormField>,
|
||||
action: AutofillAction,
|
||||
credentials: Credentials?
|
||||
) {
|
||||
fillWith(scenario.map { it.autofillId }, action, credentials)
|
||||
}
|
||||
|
||||
inline fun <T : Any, S : Any> AutofillScenario<T>.map(transform: (T) -> S): AutofillScenario<S> {
|
||||
internal inline fun <T : Any, S : Any> AutofillScenario<T>.map(transform: (T) -> S): AutofillScenario<S> {
|
||||
val builder = AutofillScenario.Builder<S>()
|
||||
builder.username = username?.let(transform)
|
||||
builder.fillUsername = fillUsername
|
||||
@ -240,7 +249,7 @@ inline fun <T : Any, S : Any> AutofillScenario<T>.map(transform: (T) -> S): Auto
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
@JvmName("toBundleAutofillId")
|
||||
private fun AutofillScenario<AutofillId>.toBundle(): Bundle = when (this) {
|
||||
internal fun AutofillScenario<AutofillId>.toBundle(): Bundle = when (this) {
|
||||
is ClassifiedAutofillScenario<AutofillId> -> {
|
||||
Bundle(5).apply {
|
||||
putParcelable(AutofillScenario.BUNDLE_KEY_USERNAME_ID, username)
|
||||
@ -267,22 +276,18 @@ private fun AutofillScenario<AutofillId>.toBundle(): Bundle = when (this) {
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
@JvmName("toBundleFormField")
|
||||
fun AutofillScenario<FormField>.toBundle(): Bundle = map { it.autofillId }.toBundle()
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun AutofillScenario<AutofillId>.recoverNodes(structure: AssistStructure): AutofillScenario<AssistStructure.ViewNode>? {
|
||||
public fun AutofillScenario<AutofillId>.recoverNodes(structure: AssistStructure): AutofillScenario<AssistStructure.ViewNode>? {
|
||||
return map { autofillId ->
|
||||
structure.findNodeByAutofillId(autofillId) ?: return null
|
||||
}
|
||||
}
|
||||
|
||||
val AutofillScenario<AssistStructure.ViewNode>.usernameValue: String?
|
||||
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
|
||||
}
|
||||
val AutofillScenario<AssistStructure.ViewNode>.passwordValue: String?
|
||||
public val AutofillScenario<AssistStructure.ViewNode>.passwordValue: String?
|
||||
@RequiresApi(Build.VERSION_CODES.O) get() {
|
||||
val distinctValues = passwordFieldsToSave.map {
|
||||
if (it.autofillValue?.isText == true) {
|
||||
|
@ -23,7 +23,7 @@ private inline fun <T> Pair<T, T>.none(predicate: T.() -> Boolean) =
|
||||
* [AutofillDsl].
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
val autofillStrategy = strategy {
|
||||
internal val autofillStrategy = strategy {
|
||||
|
||||
// Match two new password fields, an optional current password field right below or above, and
|
||||
// an optional username field with autocomplete hint.
|
||||
@ -65,7 +65,7 @@ val autofillStrategy = strategy {
|
||||
}
|
||||
}
|
||||
currentPassword {
|
||||
takeSingle { _ ->
|
||||
takeSingle {
|
||||
hasAutocompleteHintCurrentPassword && isFocused
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,10 @@ import com.github.ajalt.timberkt.d
|
||||
import com.github.ajalt.timberkt.w
|
||||
|
||||
@DslMarker
|
||||
annotation class AutofillDsl
|
||||
internal annotation class AutofillDsl
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
interface FieldMatcher {
|
||||
internal interface FieldMatcher {
|
||||
|
||||
fun match(fields: List<FormField>, alreadyMatched: List<FormField>): List<FormField>?
|
||||
|
||||
@ -63,7 +63,7 @@ interface FieldMatcher {
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class SingleFieldMatcher(
|
||||
internal class SingleFieldMatcher(
|
||||
private val take: (FormField, List<FormField>) -> Boolean,
|
||||
private val tieBreakers: List<(FormField, List<FormField>) -> Boolean>
|
||||
) : FieldMatcher {
|
||||
@ -157,7 +157,7 @@ private class PairOfFieldsMatcher(
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class AutofillRule private constructor(
|
||||
internal class AutofillRule private constructor(
|
||||
private val matchers: List<AutofillRuleMatcher>,
|
||||
private val applyInSingleOriginMode: Boolean,
|
||||
private val applyOnManualRequestOnly: Boolean,
|
||||
@ -332,7 +332,7 @@ class AutofillRule private constructor(
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class AutofillStrategy private constructor(private val rules: List<AutofillRule>) {
|
||||
internal class AutofillStrategy private constructor(private val rules: List<AutofillRule>) {
|
||||
|
||||
@AutofillDsl
|
||||
class Builder {
|
||||
@ -385,5 +385,5 @@ class AutofillStrategy private constructor(private val rules: List<AutofillRule>
|
||||
}
|
||||
}
|
||||
|
||||
fun strategy(block: AutofillStrategy.Builder.() -> Unit) =
|
||||
internal fun strategy(block: AutofillStrategy.Builder.() -> Unit) =
|
||||
AutofillStrategy.Builder().apply(block).build()
|
||||
|
@ -87,7 +87,7 @@ private fun isTrustedBrowser(context: Context, appPackage: String): Boolean {
|
||||
return certificateHash in expectedCertificateHashes
|
||||
}
|
||||
|
||||
enum class BrowserMultiOriginMethod {
|
||||
internal enum class BrowserMultiOriginMethod {
|
||||
None, WebView, Field
|
||||
}
|
||||
|
||||
@ -145,13 +145,13 @@ private val BROWSER_SAVE_FLAG = mapOf(
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun getBrowserSaveFlag(appPackage: String): Int? = BROWSER_SAVE_FLAG[appPackage]
|
||||
|
||||
data class BrowserAutofillSupportInfo(
|
||||
internal data class BrowserAutofillSupportInfo(
|
||||
val multiOriginMethod: BrowserMultiOriginMethod,
|
||||
val saveFlags: Int?
|
||||
)
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun getBrowserAutofillSupportInfoIfTrusted(
|
||||
internal fun getBrowserAutofillSupportInfoIfTrusted(
|
||||
context: Context,
|
||||
appPackage: String
|
||||
): BrowserAutofillSupportInfo? {
|
||||
@ -172,7 +172,7 @@ private val FLAKY_BROWSERS = listOf(
|
||||
"com.kiwibrowser.browser",
|
||||
)
|
||||
|
||||
enum class BrowserAutofillSupportLevel {
|
||||
public enum class BrowserAutofillSupportLevel {
|
||||
None,
|
||||
FlakyFill,
|
||||
PasswordFill,
|
||||
@ -196,7 +196,7 @@ private fun getBrowserAutofillSupportLevel(
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
fun getInstalledBrowsersWithAutofillSupportLevel(context: Context): List<Pair<String, BrowserAutofillSupportLevel>> {
|
||||
public fun getInstalledBrowsersWithAutofillSupportLevel(context: Context): List<Pair<String, BrowserAutofillSupportLevel>> {
|
||||
val testWebIntent = Intent(Intent.ACTION_VIEW).apply {
|
||||
data = Uri.parse("http://example.org")
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import androidx.annotation.RequiresApi
|
||||
import androidx.autofill.HintConstants
|
||||
import java.util.Locale
|
||||
|
||||
enum class CertaintyLevel {
|
||||
internal enum class CertaintyLevel {
|
||||
Impossible, Possible, Likely, Certain
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ enum class CertaintyLevel {
|
||||
* extracted from its [AssistStructure.ViewNode].
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
class FormField(
|
||||
internal class FormField(
|
||||
node: AssistStructure.ViewNode,
|
||||
private val index: Int,
|
||||
passDownWebViewOrigins: Boolean,
|
||||
|
@ -24,7 +24,7 @@ private object PublicSuffixListCache {
|
||||
}
|
||||
}
|
||||
|
||||
fun cachePublicSuffixList(context: Context) {
|
||||
public fun cachePublicSuffixList(context: Context) {
|
||||
PublicSuffixListCache.getOrCachePublicSuffixList(context)
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ fun cachePublicSuffixList(context: Context) {
|
||||
* Note: Invalid domains, such as IP addresses, are returned unchanged and thus never collide with
|
||||
* the return value for valid domains.
|
||||
*/
|
||||
fun getPublicSuffixPlusOne(context: Context, domain: String, customSuffixes: Sequence<String>) = runBlocking {
|
||||
internal fun getPublicSuffixPlusOne(context: Context, domain: String, customSuffixes: Sequence<String>) = runBlocking {
|
||||
// We only feed valid domain names which are not IP addresses into 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,
|
||||
@ -55,7 +55,7 @@ fun getPublicSuffixPlusOne(context: Context, domain: String, customSuffixes: Seq
|
||||
* - null, if [domain] does not have [suffix] as a domain suffix or only with an empty prefix;
|
||||
* - the direct subdomain of [suffix] of which [domain] is a subdomain.
|
||||
*/
|
||||
fun getSuffixPlusUpToOne(domain: String, suffix: String): String? {
|
||||
private fun getSuffixPlusUpToOne(domain: String, suffix: String): String? {
|
||||
if (domain == suffix)
|
||||
return domain
|
||||
val prefix = domain.removeSuffix(".$suffix")
|
||||
@ -65,7 +65,8 @@ fun getSuffixPlusUpToOne(domain: String, suffix: String): String? {
|
||||
return "$lastPrefixPart.$suffix"
|
||||
}
|
||||
|
||||
suspend fun getCanonicalSuffix(context: Context, domain: String, customSuffixes: Sequence<String>): String {
|
||||
private suspend fun getCanonicalSuffix(
|
||||
context: Context, domain: String, customSuffixes: Sequence<String>): String {
|
||||
val publicSuffixList = PublicSuffixListCache.getOrCachePublicSuffixList(context)
|
||||
val publicSuffixPlusOne = publicSuffixList.getPublicSuffixPlusOne(domain).await()
|
||||
?: return domain
|
||||
|
@ -26,7 +26,7 @@ import kotlinx.coroutines.async
|
||||
* https://publicsuffix.org/
|
||||
* https://github.com/publicsuffix/list
|
||||
*/
|
||||
class PublicSuffixList(
|
||||
internal class PublicSuffixList(
|
||||
context: Context,
|
||||
dispatcher: CoroutineDispatcher = Dispatchers.IO,
|
||||
private val scope: CoroutineScope = CoroutineScope(dispatcher)
|
||||
@ -41,30 +41,6 @@ class PublicSuffixList(
|
||||
data.run { Unit }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given [domain] is a public suffix; false otherwise.
|
||||
*
|
||||
* E.g.:
|
||||
* ```
|
||||
* co.uk -> true
|
||||
* com -> true
|
||||
* mozilla.org -> false
|
||||
* org -> true
|
||||
* ```
|
||||
*
|
||||
* Note that this method ignores the default "prevailing rule" described in the formal public suffix list algorithm:
|
||||
* If no rule matches then the passed [domain] is assumed to *not* be a public suffix.
|
||||
*
|
||||
* @param [domain] _must_ be a valid domain. [PublicSuffixList] performs no validation, and if any unexpected values
|
||||
* are passed (e.g., a full URL, a domain with a trailing '/', etc) this may return an incorrect result.
|
||||
*/
|
||||
fun isPublicSuffix(domain: String): Deferred<Boolean> = scope.async {
|
||||
when (data.getPublicSuffixOffset(domain)) {
|
||||
is PublicSuffixOffset.PublicSuffix -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the public suffix and one more level; known as the registrable domain. Returns `null` if
|
||||
* [domain] is a public suffix itself.
|
||||
@ -89,51 +65,4 @@ class PublicSuffixList(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the public suffix of the given [domain]; known as the effective top-level domain (eTLD). Returns `null`
|
||||
* if the [domain] is a public suffix itself.
|
||||
*
|
||||
* E.g.:
|
||||
* ```
|
||||
* wwww.mozilla.org -> org
|
||||
* www.bcc.co.uk -> co.uk
|
||||
* a.b.ide.kyoto.jp -> ide.kyoto.jp
|
||||
* ```
|
||||
*
|
||||
* @param [domain] _must_ be a valid domain. [PublicSuffixList] performs no validation, and if any unexpected values
|
||||
* are passed (e.g., a full URL, a domain with a trailing '/', etc) this may return an incorrect result.
|
||||
*/
|
||||
fun getPublicSuffix(domain: String) = scope.async {
|
||||
when (val offset = data.getPublicSuffixOffset(domain)) {
|
||||
is PublicSuffixOffset.Offset -> domain
|
||||
.split('.')
|
||||
.drop(offset.value + 1)
|
||||
.joinToString(separator = ".")
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the public suffix from the given [domain]. Returns the original domain if no public suffix could be
|
||||
* stripped.
|
||||
*
|
||||
* E.g.:
|
||||
* ```
|
||||
* wwww.mozilla.org -> www.mozilla
|
||||
* www.bcc.co.uk -> www.bbc
|
||||
* a.b.ide.kyoto.jp -> a.b
|
||||
* ```
|
||||
*
|
||||
* @param [domain] _must_ be a valid domain. [PublicSuffixList] performs no validation, and if any unexpected values
|
||||
* are passed (e.g., a full URL, a domain with a trailing '/', etc) this may return an incorrect result.
|
||||
*/
|
||||
fun stripPublicSuffix(domain: String) = scope.async {
|
||||
when (val offset = data.getPublicSuffixOffset(domain)) {
|
||||
is PublicSuffixOffset.Offset -> domain
|
||||
.split('.')
|
||||
.joinToString(separator = ".", limit = offset.value + 1, truncated = "")
|
||||
.dropLast(1)
|
||||
else -> domain
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user