Make autofill-parser API explicit and refactor (#1182)

This commit is contained in:
Fabian Henneke 2020-11-03 09:06:17 +01:00 committed by GitHub
parent 1d13a1fbd6
commit 73648b39d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 129 additions and 440 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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 {

View File

@ -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())
}
}

View File

@ -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)

View File

@ -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) {

View File

@ -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
}
}

View File

@ -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()

View File

@ -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")
}

View File

@ -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,

View File

@ -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

View File

@ -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
}
}
}