diff options
| author | Harsh Shandilya <me@msfjarvis.dev> | 2022-07-15 00:53:48 +0530 |
|---|---|---|
| committer | Harsh Shandilya <me@msfjarvis.dev> | 2022-07-15 01:13:47 +0530 |
| commit | 549ee790d3e52bc62565ddf92e6a556e98b5195e (patch) | |
| tree | d5758e5eb80093704e683c8da926838e18182588 /app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt | |
| parent | 010c6e227c9cc27f4d01bc912311f977b2aeb3a7 (diff) | |
| download | HardenedPass-549ee790d3e52bc62565ddf92e6a556e98b5195e.tar.gz HardenedPass-549ee790d3e52bc62565ddf92e6a556e98b5195e.zip | |
all: re-do package structure yet again
Diffstat (limited to 'app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt')
| -rw-r--r-- | app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt | 236 |
1 files changed, 0 insertions, 236 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt b/app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt deleted file mode 100644 index 745bad73..00000000 --- a/app/src/main/java/dev/msfjarvis/aps/util/autofill/Api30AutofillResponseBuilder.kt +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved. - * SPDX-License-Identifier: GPL-3.0-only - */ - -package dev.msfjarvis.aps.util.autofill - -import android.content.Context -import android.content.IntentSender -import android.service.autofill.Dataset -import android.service.autofill.FillCallback -import android.service.autofill.FillResponse -import android.service.autofill.SaveInfo -import android.view.inputmethod.InlineSuggestionsRequest -import android.widget.inline.InlinePresentationSpec -import androidx.annotation.RequiresApi -import com.github.androidpasswordstore.autofillparser.AutofillAction -import com.github.androidpasswordstore.autofillparser.FillableForm -import com.github.androidpasswordstore.autofillparser.fillWith -import com.github.michaelbull.result.fold -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject -import dev.msfjarvis.aps.autofill.oreo.ui.AutofillSmsActivity -import dev.msfjarvis.aps.ui.autofill.AutofillDecryptActivity -import dev.msfjarvis.aps.ui.autofill.AutofillDecryptActivityV2 -import dev.msfjarvis.aps.ui.autofill.AutofillFilterView -import dev.msfjarvis.aps.ui.autofill.AutofillPublisherChangedActivity -import dev.msfjarvis.aps.ui.autofill.AutofillSaveActivity -import dev.msfjarvis.aps.util.features.Feature -import dev.msfjarvis.aps.util.features.Features -import java.io.File -import logcat.LogPriority.ERROR -import logcat.asLog -import logcat.logcat - -/** Implements [AutofillResponseBuilder]'s methods for API 30 and above */ -@RequiresApi(30) -class Api30AutofillResponseBuilder -@AssistedInject -constructor( - @Assisted form: FillableForm, - private val features: Features, -) { - - @AssistedFactory - interface Factory { - fun create(form: FillableForm): Api30AutofillResponseBuilder - } - - private val formOrigin = form.formOrigin - private val scenario = form.scenario - private val ignoredIds = form.ignoredIds - private val saveFlags = form.saveFlags - 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.hasPasswordFieldsToSave - private val canBeSaved = saveFlags != null && scenarioSupportsSave - - private fun makeIntentDataset( - context: Context, - action: AutofillAction, - intentSender: IntentSender, - metadata: DatasetMetadata, - imeSpec: InlinePresentationSpec?, - ): Dataset { - return Dataset.Builder(makeRemoteView(context, metadata)).run { - fillWith(scenario, action, credentials = null) - setAuthentication(intentSender) - if (imeSpec != null) { - val inlinePresentation = makeInlinePresentation(context, imeSpec, metadata) - if (inlinePresentation != null) { - setInlinePresentation(inlinePresentation) - } - } - build() - } - } - - private fun makeMatchDataset( - context: Context, - file: File, - imeSpec: InlinePresentationSpec? - ): Dataset? { - if (!scenario.hasFieldsToFillOn(AutofillAction.Match)) return null - val metadata = makeFillMatchMetadata(context, file) - val intentSender = - if (features.isEnabled(Feature.EnablePGPainlessBackend)) { - AutofillDecryptActivityV2.makeDecryptFileIntentSender(file, context) - } else { - AutofillDecryptActivity.makeDecryptFileIntentSender(file, context) - } - return makeIntentDataset(context, AutofillAction.Match, intentSender, metadata, imeSpec) - } - - private fun makeSearchDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? { - if (!scenario.hasFieldsToFillOn(AutofillAction.Search)) return null - val metadata = makeSearchAndFillMetadata(context) - val intentSender = AutofillFilterView.makeMatchAndDecryptFileIntentSender(context, formOrigin) - return makeIntentDataset(context, AutofillAction.Search, intentSender, metadata, imeSpec) - } - - private fun makeGenerateDataset(context: Context, imeSpec: InlinePresentationSpec?): Dataset? { - 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.hasFieldsToFillOn(AutofillAction.FillOtpFromSms)) return null - if (!AutofillSmsActivity.shouldOfferFillFromSms(context)) return null - val metadata = makeFillOtpFromSmsMetadata(context) - val intentSender = AutofillSmsActivity.makeFillOtpFromSmsIntentSender(context) - return makeIntentDataset( - context, - AutofillAction.FillOtpFromSms, - intentSender, - metadata, - imeSpec - ) - } - - private fun makePublisherChangedDataset( - context: Context, - publisherChangedException: AutofillPublisherChangedException, - imeSpec: InlinePresentationSpec? - ): Dataset { - val metadata = makeWarningMetadata(context) - // If the user decides to trust the new publisher, they can choose reset the list of - // matches. In this case we need to immediately show a new `FillResponse` as if the app were - // autofilled for the first time. This `FillResponse` needs to be returned as a result from - // `AutofillPublisherChangedActivity`, which is why we create and pass it on here. - val fillResponseAfterReset = makeFillResponse(context, null, emptyList()) - val intentSender = - AutofillPublisherChangedActivity.makePublisherChangedIntentSender( - context, - publisherChangedException, - fillResponseAfterReset - ) - return makeIntentDataset(context, AutofillAction.Match, intentSender, metadata, imeSpec) - } - - private fun makePublisherChangedResponse( - context: Context, - inlineSuggestionsRequest: InlineSuggestionsRequest?, - publisherChangedException: AutofillPublisherChangedException - ): FillResponse { - val imeSpec = inlineSuggestionsRequest?.inlinePresentationSpecs?.firstOrNull() - return FillResponse.Builder().run { - addDataset(makePublisherChangedDataset(context, publisherChangedException, imeSpec)) - setIgnoredIds(*ignoredIds.toTypedArray()) - build() - } - } - - private fun makeFillResponse( - context: Context, - inlineSuggestionsRequest: InlineSuggestionsRequest?, - matchedFiles: List<File> - ): FillResponse? { - var datasetCount = 0 - val imeSpecs = inlineSuggestionsRequest?.inlinePresentationSpecs ?: emptyList() - return FillResponse.Builder().run { - for (file in matchedFiles) { - makeMatchDataset(context, file, imeSpecs.getOrNull(datasetCount))?.let { - datasetCount++ - addDataset(it) - } - } - makeGenerateDataset(context, imeSpecs.getOrNull(datasetCount))?.let { - datasetCount++ - addDataset(it) - } - makeFillOtpFromSmsDataset(context, imeSpecs.getOrNull(datasetCount))?.let { - datasetCount++ - addDataset(it) - } - makeSearchDataset(context, imeSpecs.getOrNull(datasetCount))?.let { - datasetCount++ - addDataset(it) - } - if (datasetCount == 0) return null - setHeader( - makeRemoteView( - context, - makeHeaderMetadata(formOrigin.getPrettyIdentifier(context, untrusted = true)) - ) - ) - makeSaveInfo()?.let { setSaveInfo(it) } - setClientState(clientState) - setIgnoredIds(*ignoredIds.toTypedArray()) - build() - } - } - - // TODO: Support multi-step authentication flows in apps via FLAG_DELAY_SAVE - // See: - // https://developer.android.com/reference/android/service/autofill/SaveInfo#FLAG_DELAY_SAVE - private fun makeSaveInfo(): SaveInfo? { - if (!canBeSaved) return null - check(saveFlags != null) - val idsToSave = scenario.fieldsToSave.toTypedArray() - if (idsToSave.isEmpty()) return null - var saveDataTypes = SaveInfo.SAVE_DATA_TYPE_PASSWORD - if (scenario.hasUsername) { - saveDataTypes = saveDataTypes or SaveInfo.SAVE_DATA_TYPE_USERNAME - } - return SaveInfo.Builder(saveDataTypes, idsToSave).run { - setFlags(saveFlags) - build() - } - } - - /** Creates and returns a suitable [FillResponse] to the Autofill framework. */ - fun fillCredentials( - context: Context, - inlineSuggestionsRequest: InlineSuggestionsRequest?, - callback: FillCallback - ) { - AutofillMatcher.getMatchesFor(context, formOrigin) - .fold( - success = { matchedFiles -> - callback.onSuccess(makeFillResponse(context, inlineSuggestionsRequest, matchedFiles)) - }, - failure = { e -> - logcat(ERROR) { e.asLog() } - callback.onSuccess(makePublisherChangedResponse(context, inlineSuggestionsRequest, e)) - } - ) - } -} |
