mirror of
https://github.com/android-password-store/Android-Password-Store
synced 2025-08-29 05:17:43 +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()
|
private val clientState = form.toClientState()
|
||||||
|
|
||||||
// We do not offer save when the only relevant field is a username field or there is no field.
|
// We do not offer save when the only relevant field is a username field or there is no field.
|
||||||
private val scenarioSupportsSave =
|
private val scenarioSupportsSave = scenario.hasPasswordFieldsToSave
|
||||||
scenario.fieldsToSave.minus(listOfNotNull(scenario.username)).isNotEmpty()
|
|
||||||
private val canBeSaved = saveFlags != null && scenarioSupportsSave
|
private val canBeSaved = saveFlags != null && scenarioSupportsSave
|
||||||
|
|
||||||
private fun makeIntentDataset(
|
private fun makeIntentDataset(
|
||||||
@ -63,14 +62,14 @@ class AutofillResponseBuilder(form: FillableForm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun makeMatchDataset(context: Context, file: File, imeSpec: InlinePresentationSpec?): Dataset? {
|
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 metadata = makeFillMatchMetadata(context, file)
|
||||||
val intentSender = AutofillDecryptActivity.makeDecryptFileIntentSender(file, context)
|
val intentSender = AutofillDecryptActivity.makeDecryptFileIntentSender(file, context)
|
||||||
return makeIntentDataset(context, AutofillAction.Match, intentSender, metadata, imeSpec)
|
return makeIntentDataset(context, AutofillAction.Match, intentSender, metadata, imeSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeSearchDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? {
|
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 metadata = makeSearchAndFillMetadata(context)
|
||||||
val intentSender =
|
val intentSender =
|
||||||
AutofillFilterView.makeMatchAndDecryptFileIntentSender(context, formOrigin)
|
AutofillFilterView.makeMatchAndDecryptFileIntentSender(context, formOrigin)
|
||||||
@ -78,14 +77,14 @@ class AutofillResponseBuilder(form: FillableForm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun makeGenerateDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? {
|
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 metadata = makeGenerateAndFillMetadata(context)
|
||||||
val intentSender = AutofillSaveActivity.makeSaveIntentSender(context, null, formOrigin)
|
val intentSender = AutofillSaveActivity.makeSaveIntentSender(context, null, formOrigin)
|
||||||
return makeIntentDataset(context, AutofillAction.Generate, intentSender, metadata, imeSpec)
|
return makeIntentDataset(context, AutofillAction.Generate, intentSender, metadata, imeSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeFillOtpFromSmsDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? {
|
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
|
if (!AutofillSmsActivity.shouldOfferFillFromSms(context)) return null
|
||||||
val metadata = makeFillOtpFromSmsMetadata(context)
|
val metadata = makeFillOtpFromSmsMetadata(context)
|
||||||
val intentSender = AutofillSmsActivity.makeFillOtpFromSmsIntentSender(context)
|
val intentSender = AutofillSmsActivity.makeFillOtpFromSmsIntentSender(context)
|
||||||
@ -131,10 +130,10 @@ class AutofillResponseBuilder(form: FillableForm) {
|
|||||||
private fun makeSaveInfo(): SaveInfo? {
|
private fun makeSaveInfo(): SaveInfo? {
|
||||||
if (!canBeSaved) return null
|
if (!canBeSaved) return null
|
||||||
check(saveFlags != null)
|
check(saveFlags != null)
|
||||||
val idsToSave = scenario.fieldsToSave.map { it.autofillId }.toTypedArray()
|
val idsToSave = scenario.fieldsToSave.toTypedArray()
|
||||||
if (idsToSave.isEmpty()) return null
|
if (idsToSave.isEmpty()) return null
|
||||||
var saveDataTypes = SaveInfo.SAVE_DATA_TYPE_PASSWORD
|
var saveDataTypes = SaveInfo.SAVE_DATA_TYPE_PASSWORD
|
||||||
if (scenario.username != null) {
|
if (scenario.hasUsername) {
|
||||||
saveDataTypes = saveDataTypes or SaveInfo.SAVE_DATA_TYPE_USERNAME
|
saveDataTypes = saveDataTypes or SaveInfo.SAVE_DATA_TYPE_USERNAME
|
||||||
}
|
}
|
||||||
return SaveInfo.Builder(saveDataTypes, idsToSave).run {
|
return SaveInfo.Builder(saveDataTypes, idsToSave).run {
|
||||||
@ -202,7 +201,7 @@ class AutofillResponseBuilder(form: FillableForm) {
|
|||||||
clientState: Bundle,
|
clientState: Bundle,
|
||||||
action: AutofillAction
|
action: AutofillAction
|
||||||
): Dataset {
|
): 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
|
// Before Android P, Datasets used for fill-in had to come with a RemoteViews, even
|
||||||
// though they are rarely shown.
|
// though they are rarely shown.
|
||||||
// FIXME: We should clone the original dataset here and add the credentials to be filled
|
// 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))
|
callback.onFailure(getString(R.string.oreo_autofill_save_internal_error))
|
||||||
return
|
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" }
|
e { "Failed to recover client state or nodes from client state" }
|
||||||
callback.onFailure(getString(R.string.oreo_autofill_save_internal_error))
|
callback.onFailure(getString(R.string.oreo_autofill_save_internal_error))
|
||||||
return
|
return
|
||||||
|
@ -7,149 +7,31 @@ public final class com/github/androidpasswordstore/autofillparser/AutofillAction
|
|||||||
public static fun values ()[Lcom/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 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 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 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 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 final fun getFieldsToSave ()Ljava/util/List;
|
||||||
public abstract fun getFillUsername ()Z
|
public final fun getHasFieldsToSave ()Z
|
||||||
public abstract fun getOtp ()Ljava/lang/Object;
|
public final fun getHasPasswordFieldsToSave ()Z
|
||||||
public abstract fun getPasswordFieldsToFillOnGenerate ()Ljava/util/List;
|
public final fun getHasUsername ()Z
|
||||||
public abstract fun getPasswordFieldsToFillOnMatch ()Ljava/util/List;
|
|
||||||
public abstract fun getPasswordFieldsToFillOnSearch ()Ljava/util/List;
|
|
||||||
public abstract fun getPasswordFieldsToSave ()Ljava/util/List;
|
public abstract fun getPasswordFieldsToSave ()Ljava/util/List;
|
||||||
public abstract fun getUsername ()Ljava/lang/Object;
|
public abstract fun getUsername ()Ljava/lang/Object;
|
||||||
}
|
public final fun hasFieldsToFillOn (Lcom/github/androidpasswordstore/autofillparser/AutofillAction;)Z
|
||||||
|
|
||||||
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 class com/github/androidpasswordstore/autofillparser/AutofillScenario$Companion {
|
public final class com/github/androidpasswordstore/autofillparser/AutofillScenario$Companion {
|
||||||
public final fun fromBundle (Landroid/os/Bundle;)Lcom/github/androidpasswordstore/autofillparser/AutofillScenario;
|
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 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 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 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 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 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 {
|
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 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 final class com/github/androidpasswordstore/autofillparser/Credentials {
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public final fun component1 ()Ljava/lang/String;
|
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 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 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 final class com/github/androidpasswordstore/autofillparser/FillableForm {
|
||||||
public static final field Companion Lcom/github/androidpasswordstore/autofillparser/FillableForm$Companion;
|
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
|
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 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 abstract class com/github/androidpasswordstore/autofillparser/FormOrigin {
|
||||||
public static final field Companion Lcom/github/androidpasswordstore/autofillparser/FormOrigin$Companion;
|
public static final field Companion Lcom/github/androidpasswordstore/autofillparser/FormOrigin$Companion;
|
||||||
public synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
|
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 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 final class com/github/androidpasswordstore/autofillparser/PublicSuffixListCacheKt {
|
||||||
public static final fun cachePublicSuffixList (Landroid/content/Context;)V
|
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 {
|
android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
versionCode = 1
|
versionCode = 2
|
||||||
versionName = "1.0"
|
versionName = "2.0"
|
||||||
consumerProguardFiles("consumer-rules.pro")
|
consumerProguardFiles("consumer-rules.pro")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
explicitApi()
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
freeCompilerArgs = freeCompilerArgs + listOf(
|
||||||
|
"-Xexplicit-api=strict"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
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).
|
* 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)
|
public data class Web(override val identifier: String) : FormOrigin(identifier)
|
||||||
data class App(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_WEB_IDENTIFIER = "webIdentifier"
|
||||||
private const val BUNDLE_KEY_APP_IDENTIFIER = "appIdentifier"
|
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)
|
val webIdentifier = bundle.getString(BUNDLE_KEY_WEB_IDENTIFIER)
|
||||||
if (webIdentifier != null) {
|
if (webIdentifier != null) {
|
||||||
return Web(webIdentifier)
|
return Web(webIdentifier)
|
||||||
@ -37,7 +37,8 @@ sealed class FormOrigin(open val identifier: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPrettyIdentifier(context: Context, untrusted: Boolean = true) = when (this) {
|
public fun getPrettyIdentifier(context: Context, untrusted: Boolean = true): String =
|
||||||
|
when (this) {
|
||||||
is Web -> identifier
|
is Web -> identifier
|
||||||
is App -> {
|
is App -> {
|
||||||
val info = context.packageManager.getApplicationInfo(
|
val info = context.packageManager.getApplicationInfo(
|
||||||
@ -48,7 +49,7 @@ sealed class FormOrigin(open val identifier: String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toBundle() = Bundle().apply {
|
public fun toBundle(): Bundle = Bundle().apply {
|
||||||
when (this@FormOrigin) {
|
when (this@FormOrigin) {
|
||||||
is Web -> putString(BUNDLE_KEY_WEB_IDENTIFIER, identifier)
|
is Web -> putString(BUNDLE_KEY_WEB_IDENTIFIER, identifier)
|
||||||
is App -> putString(BUNDLE_KEY_APP_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
|
* 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.
|
* entry point to all fill and save features.
|
||||||
*/
|
*/
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
class FillableForm private constructor(
|
public class FillableForm private constructor(
|
||||||
val formOrigin: FormOrigin,
|
public val formOrigin: FormOrigin,
|
||||||
val scenario: AutofillScenario<FormField>,
|
public val scenario: AutofillScenario<AutofillId>,
|
||||||
val ignoredIds: List<AutofillId>,
|
public val ignoredIds: List<AutofillId>,
|
||||||
val saveFlags: Int?
|
public val saveFlags: Int?
|
||||||
) {
|
) {
|
||||||
companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
* Returns a [FillableForm] if a login form could be detected in [structure].
|
* Returns a [FillableForm] if a login form could be detected in [structure].
|
||||||
*/
|
*/
|
||||||
fun parseAssistStructure(
|
public fun parseAssistStructure(
|
||||||
context: Context,
|
context: Context,
|
||||||
structure: AssistStructure,
|
structure: AssistStructure,
|
||||||
isManualRequest: Boolean,
|
isManualRequest: Boolean,
|
||||||
@ -208,11 +209,11 @@ class FillableForm private constructor(
|
|||||||
): FillableForm? {
|
): FillableForm? {
|
||||||
val form = AutofillFormParser(context, structure, isManualRequest, customSuffixes)
|
val form = AutofillFormParser(context, structure, isManualRequest, customSuffixes)
|
||||||
if (form.formOrigin == null || form.scenario == null) return null
|
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())
|
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
|
* 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 `;`.
|
* 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
|
// The warning does not apply since 1) we are specifically hashing **all** signatures and 2) it
|
||||||
// no longer applies to Android 4.4+.
|
// 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
|
// 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
|
* Returns the "origin" (without port information) of the [AssistStructure.ViewNode] derived from
|
||||||
* its `webDomain` and `webScheme`, if available.
|
* 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 ->
|
@RequiresApi(Build.VERSION_CODES.O) get() = webDomain?.let { domain ->
|
||||||
val scheme = (if (Build.VERSION.SDK_INT >= 28) webScheme else null) ?: "https"
|
val scheme = (if (Build.VERSION.SDK_INT >= 28) webScheme else null) ?: "https"
|
||||||
"$scheme://$domain"
|
"$scheme://$domain"
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@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
|
private val applicationContext = context.applicationContext
|
||||||
|
|
||||||
fun onFailure(message: CharSequence) {
|
public fun onFailure(message: CharSequence) {
|
||||||
callback.onFailure(message)
|
callback.onFailure(message)
|
||||||
// When targeting SDK 29, the message is no longer shown as a toast.
|
// 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)
|
// 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) {
|
if (Build.VERSION.SDK_INT >= 28) {
|
||||||
callback.onSuccess(intentSender)
|
callback.onSuccess(intentSender)
|
||||||
} else {
|
} else {
|
||||||
@ -117,7 +117,7 @@ private fun visitViewNode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@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
|
var node: AssistStructure.ViewNode? = null
|
||||||
visitViewNodes(this) {
|
visitViewNodes(this) {
|
||||||
if (it.autofillId == autofillId)
|
if (it.autofillId == autofillId)
|
||||||
|
@ -13,7 +13,7 @@ import android.view.autofill.AutofillValue
|
|||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import com.github.ajalt.timberkt.e
|
import com.github.ajalt.timberkt.e
|
||||||
|
|
||||||
enum class AutofillAction {
|
public enum class AutofillAction {
|
||||||
Match, Search, Generate, FillOtpFromSms
|
Match, Search, Generate, FillOtpFromSms
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,18 +24,23 @@ enum class AutofillAction {
|
|||||||
* field is needed and available in the particular situation.
|
* field is needed and available in the particular situation.
|
||||||
*/
|
*/
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@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"
|
internal const val BUNDLE_KEY_USERNAME_ID = "usernameId"
|
||||||
const val BUNDLE_KEY_FILL_USERNAME = "fillUsername"
|
internal const val BUNDLE_KEY_FILL_USERNAME = "fillUsername"
|
||||||
const val BUNDLE_KEY_OTP_ID = "otpId"
|
internal const val BUNDLE_KEY_OTP_ID = "otpId"
|
||||||
const val BUNDLE_KEY_CURRENT_PASSWORD_IDS = "currentPasswordIds"
|
internal const val BUNDLE_KEY_CURRENT_PASSWORD_IDS = "currentPasswordIds"
|
||||||
const val BUNDLE_KEY_NEW_PASSWORD_IDS = "newPasswordIds"
|
internal const val BUNDLE_KEY_NEW_PASSWORD_IDS = "newPasswordIds"
|
||||||
const val BUNDLE_KEY_GENERIC_PASSWORD_IDS = "genericPasswordIds"
|
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 {
|
return try {
|
||||||
Builder<AutofillId>().apply {
|
Builder<AutofillId>().apply {
|
||||||
username = clientState.getParcelable(BUNDLE_KEY_USERNAME_ID)
|
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 username: T? = null
|
||||||
var fillUsername = false
|
var fillUsername = false
|
||||||
@ -94,22 +99,23 @@ sealed class AutofillScenario<out T : Any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract val username: T?
|
public abstract val username: T?
|
||||||
abstract val fillUsername: Boolean
|
public abstract val passwordFieldsToSave: List<T>
|
||||||
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>
|
|
||||||
|
|
||||||
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
|
get() = listOfNotNull(username) + passwordFieldsToSave
|
||||||
|
|
||||||
val allFields
|
internal val allFields: List<T>
|
||||||
get() = listOfNotNull(username, otp) + allPasswordFields
|
get() = listOfNotNull(username, otp) + allPasswordFields
|
||||||
|
|
||||||
fun fieldsToFillOn(action: AutofillAction): List<T> {
|
internal fun fieldsToFillOn(action: AutofillAction): List<T> {
|
||||||
val credentialFieldsToFill = when (action) {
|
val credentialFieldsToFill = when (action) {
|
||||||
AutofillAction.Match -> passwordFieldsToFillOnMatch + listOfNotNull(otp)
|
AutofillAction.Match -> passwordFieldsToFillOnMatch + listOfNotNull(otp)
|
||||||
AutofillAction.Search -> passwordFieldsToFillOnSearch + listOfNotNull(otp)
|
AutofillAction.Search -> passwordFieldsToFillOnSearch + listOfNotNull(otp)
|
||||||
@ -134,10 +140,23 @@ sealed class AutofillScenario<out T : Any> {
|
|||||||
else -> emptyList()
|
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)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
data class ClassifiedAutofillScenario<T : Any>(
|
internal data class ClassifiedAutofillScenario<T : Any>(
|
||||||
override val username: T?,
|
override val username: T?,
|
||||||
override val fillUsername: Boolean,
|
override val fillUsername: Boolean,
|
||||||
override val otp: T?,
|
override val otp: T?,
|
||||||
@ -158,7 +177,7 @@ data class ClassifiedAutofillScenario<T : Any>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
data class GenericAutofillScenario<T : Any>(
|
internal data class GenericAutofillScenario<T : Any>(
|
||||||
override val username: T?,
|
override val username: T?,
|
||||||
override val fillUsername: Boolean,
|
override val fillUsername: Boolean,
|
||||||
override val otp: T?,
|
override val otp: T?,
|
||||||
@ -177,7 +196,7 @@ data class GenericAutofillScenario<T : Any>(
|
|||||||
get() = genericPassword
|
get() = genericPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
fun AutofillScenario<FormField>.passesOriginCheck(singleOriginMode: Boolean): Boolean {
|
internal fun AutofillScenario<FormField>.passesOriginCheck(singleOriginMode: Boolean): Boolean {
|
||||||
return if (singleOriginMode) {
|
return if (singleOriginMode) {
|
||||||
// In single origin mode, only the browsers URL bar (which is never filled) should have
|
// In single origin mode, only the browsers URL bar (which is never filled) should have
|
||||||
// a webOrigin.
|
// a webOrigin.
|
||||||
@ -191,7 +210,7 @@ fun AutofillScenario<FormField>.passesOriginCheck(singleOriginMode: Boolean): Bo
|
|||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
@JvmName("fillWithAutofillId")
|
@JvmName("fillWithAutofillId")
|
||||||
fun Dataset.Builder.fillWith(
|
public fun Dataset.Builder.fillWith(
|
||||||
scenario: AutofillScenario<AutofillId>,
|
scenario: AutofillScenario<AutofillId>,
|
||||||
action: AutofillAction,
|
action: AutofillAction,
|
||||||
credentials: Credentials?
|
credentials: Credentials?
|
||||||
@ -211,17 +230,7 @@ fun Dataset.Builder.fillWith(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
internal inline fun <T : Any, S : Any> AutofillScenario<T>.map(transform: (T) -> S): AutofillScenario<S> {
|
||||||
@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> {
|
|
||||||
val builder = AutofillScenario.Builder<S>()
|
val builder = AutofillScenario.Builder<S>()
|
||||||
builder.username = username?.let(transform)
|
builder.username = username?.let(transform)
|
||||||
builder.fillUsername = fillUsername
|
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)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
@JvmName("toBundleAutofillId")
|
@JvmName("toBundleAutofillId")
|
||||||
private fun AutofillScenario<AutofillId>.toBundle(): Bundle = when (this) {
|
internal fun AutofillScenario<AutofillId>.toBundle(): Bundle = when (this) {
|
||||||
is ClassifiedAutofillScenario<AutofillId> -> {
|
is ClassifiedAutofillScenario<AutofillId> -> {
|
||||||
Bundle(5).apply {
|
Bundle(5).apply {
|
||||||
putParcelable(AutofillScenario.BUNDLE_KEY_USERNAME_ID, username)
|
putParcelable(AutofillScenario.BUNDLE_KEY_USERNAME_ID, username)
|
||||||
@ -267,22 +276,18 @@ private fun AutofillScenario<AutofillId>.toBundle(): Bundle = when (this) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
@JvmName("toBundleFormField")
|
public fun AutofillScenario<AutofillId>.recoverNodes(structure: AssistStructure): AutofillScenario<AssistStructure.ViewNode>? {
|
||||||
fun AutofillScenario<FormField>.toBundle(): Bundle = map { it.autofillId }.toBundle()
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
|
||||||
fun AutofillScenario<AutofillId>.recoverNodes(structure: AssistStructure): AutofillScenario<AssistStructure.ViewNode>? {
|
|
||||||
return map { autofillId ->
|
return map { autofillId ->
|
||||||
structure.findNodeByAutofillId(autofillId) ?: return null
|
structure.findNodeByAutofillId(autofillId) ?: return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val AutofillScenario<AssistStructure.ViewNode>.usernameValue: String?
|
public val AutofillScenario<AssistStructure.ViewNode>.usernameValue: String?
|
||||||
@RequiresApi(Build.VERSION_CODES.O) get() {
|
@RequiresApi(Build.VERSION_CODES.O) get() {
|
||||||
val value = username?.autofillValue ?: return null
|
val value = username?.autofillValue ?: return null
|
||||||
return if (value.isText) value.textValue.toString() else 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() {
|
@RequiresApi(Build.VERSION_CODES.O) get() {
|
||||||
val distinctValues = passwordFieldsToSave.map {
|
val distinctValues = passwordFieldsToSave.map {
|
||||||
if (it.autofillValue?.isText == true) {
|
if (it.autofillValue?.isText == true) {
|
||||||
|
@ -23,7 +23,7 @@ private inline fun <T> Pair<T, T>.none(predicate: T.() -> Boolean) =
|
|||||||
* [AutofillDsl].
|
* [AutofillDsl].
|
||||||
*/
|
*/
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@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
|
// Match two new password fields, an optional current password field right below or above, and
|
||||||
// an optional username field with autocomplete hint.
|
// an optional username field with autocomplete hint.
|
||||||
@ -65,7 +65,7 @@ val autofillStrategy = strategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentPassword {
|
currentPassword {
|
||||||
takeSingle { _ ->
|
takeSingle {
|
||||||
hasAutocompleteHintCurrentPassword && isFocused
|
hasAutocompleteHintCurrentPassword && isFocused
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@ import com.github.ajalt.timberkt.d
|
|||||||
import com.github.ajalt.timberkt.w
|
import com.github.ajalt.timberkt.w
|
||||||
|
|
||||||
@DslMarker
|
@DslMarker
|
||||||
annotation class AutofillDsl
|
internal annotation class AutofillDsl
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
interface FieldMatcher {
|
internal interface FieldMatcher {
|
||||||
|
|
||||||
fun match(fields: List<FormField>, alreadyMatched: List<FormField>): List<FormField>?
|
fun match(fields: List<FormField>, alreadyMatched: List<FormField>): List<FormField>?
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ interface FieldMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
class SingleFieldMatcher(
|
internal class SingleFieldMatcher(
|
||||||
private val take: (FormField, List<FormField>) -> Boolean,
|
private val take: (FormField, List<FormField>) -> Boolean,
|
||||||
private val tieBreakers: List<(FormField, List<FormField>) -> Boolean>
|
private val tieBreakers: List<(FormField, List<FormField>) -> Boolean>
|
||||||
) : FieldMatcher {
|
) : FieldMatcher {
|
||||||
@ -157,7 +157,7 @@ private class PairOfFieldsMatcher(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
class AutofillRule private constructor(
|
internal class AutofillRule private constructor(
|
||||||
private val matchers: List<AutofillRuleMatcher>,
|
private val matchers: List<AutofillRuleMatcher>,
|
||||||
private val applyInSingleOriginMode: Boolean,
|
private val applyInSingleOriginMode: Boolean,
|
||||||
private val applyOnManualRequestOnly: Boolean,
|
private val applyOnManualRequestOnly: Boolean,
|
||||||
@ -332,7 +332,7 @@ class AutofillRule private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@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
|
@AutofillDsl
|
||||||
class Builder {
|
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()
|
AutofillStrategy.Builder().apply(block).build()
|
||||||
|
@ -87,7 +87,7 @@ private fun isTrustedBrowser(context: Context, appPackage: String): Boolean {
|
|||||||
return certificateHash in expectedCertificateHashes
|
return certificateHash in expectedCertificateHashes
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class BrowserMultiOriginMethod {
|
internal enum class BrowserMultiOriginMethod {
|
||||||
None, WebView, Field
|
None, WebView, Field
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,13 +145,13 @@ private val BROWSER_SAVE_FLAG = mapOf(
|
|||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
private fun getBrowserSaveFlag(appPackage: String): Int? = BROWSER_SAVE_FLAG[appPackage]
|
private fun getBrowserSaveFlag(appPackage: String): Int? = BROWSER_SAVE_FLAG[appPackage]
|
||||||
|
|
||||||
data class BrowserAutofillSupportInfo(
|
internal data class BrowserAutofillSupportInfo(
|
||||||
val multiOriginMethod: BrowserMultiOriginMethod,
|
val multiOriginMethod: BrowserMultiOriginMethod,
|
||||||
val saveFlags: Int?
|
val saveFlags: Int?
|
||||||
)
|
)
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
fun getBrowserAutofillSupportInfoIfTrusted(
|
internal fun getBrowserAutofillSupportInfoIfTrusted(
|
||||||
context: Context,
|
context: Context,
|
||||||
appPackage: String
|
appPackage: String
|
||||||
): BrowserAutofillSupportInfo? {
|
): BrowserAutofillSupportInfo? {
|
||||||
@ -172,7 +172,7 @@ private val FLAKY_BROWSERS = listOf(
|
|||||||
"com.kiwibrowser.browser",
|
"com.kiwibrowser.browser",
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class BrowserAutofillSupportLevel {
|
public enum class BrowserAutofillSupportLevel {
|
||||||
None,
|
None,
|
||||||
FlakyFill,
|
FlakyFill,
|
||||||
PasswordFill,
|
PasswordFill,
|
||||||
@ -196,7 +196,7 @@ private fun getBrowserAutofillSupportLevel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@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 {
|
val testWebIntent = Intent(Intent.ACTION_VIEW).apply {
|
||||||
data = Uri.parse("http://example.org")
|
data = Uri.parse("http://example.org")
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import androidx.annotation.RequiresApi
|
|||||||
import androidx.autofill.HintConstants
|
import androidx.autofill.HintConstants
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
enum class CertaintyLevel {
|
internal enum class CertaintyLevel {
|
||||||
Impossible, Possible, Likely, Certain
|
Impossible, Possible, Likely, Certain
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ enum class CertaintyLevel {
|
|||||||
* extracted from its [AssistStructure.ViewNode].
|
* extracted from its [AssistStructure.ViewNode].
|
||||||
*/
|
*/
|
||||||
@RequiresApi(Build.VERSION_CODES.O)
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
class FormField(
|
internal class FormField(
|
||||||
node: AssistStructure.ViewNode,
|
node: AssistStructure.ViewNode,
|
||||||
private val index: Int,
|
private val index: Int,
|
||||||
passDownWebViewOrigins: Boolean,
|
passDownWebViewOrigins: Boolean,
|
||||||
|
@ -24,7 +24,7 @@ private object PublicSuffixListCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cachePublicSuffixList(context: Context) {
|
public fun cachePublicSuffixList(context: Context) {
|
||||||
PublicSuffixListCache.getOrCachePublicSuffixList(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
|
* Note: Invalid domains, such as IP addresses, are returned unchanged and thus never collide with
|
||||||
* the return value for valid domains.
|
* 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 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
|
// 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,
|
// 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;
|
* - 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.
|
* - 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)
|
if (domain == suffix)
|
||||||
return domain
|
return domain
|
||||||
val prefix = domain.removeSuffix(".$suffix")
|
val prefix = domain.removeSuffix(".$suffix")
|
||||||
@ -65,7 +65,8 @@ fun getSuffixPlusUpToOne(domain: String, suffix: String): String? {
|
|||||||
return "$lastPrefixPart.$suffix"
|
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 publicSuffixList = PublicSuffixListCache.getOrCachePublicSuffixList(context)
|
||||||
val publicSuffixPlusOne = publicSuffixList.getPublicSuffixPlusOne(domain).await()
|
val publicSuffixPlusOne = publicSuffixList.getPublicSuffixPlusOne(domain).await()
|
||||||
?: return domain
|
?: return domain
|
||||||
|
@ -26,7 +26,7 @@ import kotlinx.coroutines.async
|
|||||||
* https://publicsuffix.org/
|
* https://publicsuffix.org/
|
||||||
* https://github.com/publicsuffix/list
|
* https://github.com/publicsuffix/list
|
||||||
*/
|
*/
|
||||||
class PublicSuffixList(
|
internal class PublicSuffixList(
|
||||||
context: Context,
|
context: Context,
|
||||||
dispatcher: CoroutineDispatcher = Dispatchers.IO,
|
dispatcher: CoroutineDispatcher = Dispatchers.IO,
|
||||||
private val scope: CoroutineScope = CoroutineScope(dispatcher)
|
private val scope: CoroutineScope = CoroutineScope(dispatcher)
|
||||||
@ -41,30 +41,6 @@ class PublicSuffixList(
|
|||||||
data.run { Unit }
|
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
|
* Returns the public suffix and one more level; known as the registrable domain. Returns `null` if
|
||||||
* [domain] is a public suffix itself.
|
* [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