Skip to content

Create dialog inside autofill-impl instead of BTF being responsible for it #6368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,10 @@ import com.duckduckgo.autoconsent.api.AutoconsentCallback
import com.duckduckgo.autofill.api.AutofillCapabilityChecker
import com.duckduckgo.autofill.api.AutofillEventListener
import com.duckduckgo.autofill.api.AutofillFragmentResultsPlugin
import com.duckduckgo.autofill.api.AutofillImportLaunchSource.InBrowserPromo
import com.duckduckgo.autofill.api.AutofillPrompt
import com.duckduckgo.autofill.api.AutofillPrompt.ImportPasswords
import com.duckduckgo.autofill.api.AutofillPrompt.UrlMatchType.AnyUrl
import com.duckduckgo.autofill.api.AutofillPrompt.UrlMatchType.ExactUrl
import com.duckduckgo.autofill.api.AutofillScreenLaunchSource
import com.duckduckgo.autofill.api.AutofillScreens.AutofillPasswordsManagementScreenWithSuggestions
import com.duckduckgo.autofill.api.AutofillScreens.AutofillPasswordsManagementViewCredential
Expand Down Expand Up @@ -764,18 +765,22 @@ class BrowserTabFragment :
viewModel.onShowUserCredentialsSaved(savedCredentials)
}

override suspend fun promptUserTo(event: AutofillPrompt) {
override suspend fun showAutofillPrompt(event: AutofillPrompt) {
logcat { "showAutofillPrompt called: ${event.javaClass.simpleName}" }

// some prompts requiring the guard that we're still on the same URL before showing the dialog
val requiredUrl = when (val matchType = event.urlMatchType) {
is AnyUrl -> null
is ExactUrl -> matchType.requiredUrl
}

withContext(dispatchers.main()) {
when (event) {
is ImportPasswords -> {
showDialogHidingPrevious(
credentialAutofillDialogFactory.autofillImportPasswordsPromoDialog(
importSource = InBrowserPromo,
tabId = tabId,
url = event.currentUrl,
),
AUTOFILL_DIALOG_TAB,
event.currentUrl,
dialog = event.prompt,
tag = AUTOFILL_DIALOG_TAB,
requiredUrl = requiredUrl,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,6 @@ interface CredentialAutofillDialogFactory {
* Creates a dialog which prompts the user to sign up for Email Protection
*/
fun emailProtectionInContextSignUpDialog(tabId: String): DialogFragment

/**
* Creates a dialog which prompts the user to import passwords from Google Passwords
*/
fun autofillImportPasswordsPromoDialog(importSource: AutofillImportLaunchSource, tabId: String, url: String): DialogFragment
}

private fun prefix(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.duckduckgo.autofill.api

import android.webkit.WebView
import androidx.fragment.app.DialogFragment
import com.duckduckgo.autofill.api.domain.app.LoginCredentials
import com.duckduckgo.autofill.api.domain.app.LoginTriggerType

Expand Down Expand Up @@ -159,9 +160,21 @@ interface Callback {
*/
fun onCredentialsSaved(savedCredentials: LoginCredentials)

suspend fun promptUserTo(event: AutofillPrompt)
/**
* Called when the user should be shown an autofill prompt
*/
suspend fun showAutofillPrompt(event: AutofillPrompt)
}

sealed interface AutofillPrompt {
data class ImportPasswords(val currentUrl: String) : AutofillPrompt
sealed class AutofillPrompt(open val urlMatchType: UrlMatchType) {

data class ImportPasswords(
val prompt: DialogFragment,
override val urlMatchType: UrlMatchType,
) : AutofillPrompt(urlMatchType)

sealed interface UrlMatchType {
data object AnyUrl : UrlMatchType
data class ExactUrl(val requiredUrl: String) : UrlMatchType
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import android.webkit.JavascriptInterface
import android.webkit.WebView
import com.duckduckgo.app.di.AppCoroutineScope
import com.duckduckgo.autofill.api.AutofillCapabilityChecker
import com.duckduckgo.autofill.api.AutofillImportLaunchSource.InBrowserPromo
import com.duckduckgo.autofill.api.AutofillPrompt.ImportPasswords
import com.duckduckgo.autofill.api.AutofillPrompt.UrlMatchType.ExactUrl
import com.duckduckgo.autofill.api.Callback
import com.duckduckgo.autofill.api.CredentialUpdateExistingCredentialsDialog.CredentialUpdateType
import com.duckduckgo.autofill.api.EmailProtectionInContextSignupFlowListener
Expand Down Expand Up @@ -196,8 +198,15 @@ class AutofillStoredBackJavascriptInterface @Inject constructor(
}

private fun handlePromoteImport(url: String) {
coroutineScope.launch {
callback?.promptUserTo(ImportPasswords(url))
tabId?.let {
coroutineScope.launch(dispatcherProvider.io()) {
val dialog = inBrowserImportPromo.autofillImportPasswordsPromoDialog(
importSource = InBrowserPromo,
tabId = it,
url = url,
)
callback?.showAutofillPrompt(ImportPasswords(dialog, ExactUrl(url)))
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@

package com.duckduckgo.autofill.impl.importing

import androidx.fragment.app.DialogFragment
import com.duckduckgo.autofill.api.AutofillFeature
import com.duckduckgo.autofill.api.AutofillImportLaunchSource
import com.duckduckgo.autofill.impl.store.InternalAutofillStore
import com.duckduckgo.autofill.impl.store.NeverSavedSiteRepository
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialog
import com.duckduckgo.common.utils.DispatcherProvider
import com.duckduckgo.di.scopes.AppScope
import com.squareup.anvil.annotations.ContributesBinding
Expand All @@ -31,6 +34,11 @@ interface InBrowserImportPromo {
credentialsAvailableForCurrentPage: Boolean,
url: String?,
): Boolean

/**
* Creates a dialog which prompts the user to import passwords from Google Passwords
*/
fun autofillImportPasswordsPromoDialog(importSource: AutofillImportLaunchSource, tabId: String, url: String): DialogFragment
}

@ContributesBinding(AppScope::class)
Expand Down Expand Up @@ -78,6 +86,14 @@ class RealInBrowserImportPromo @Inject constructor(
}
}

override fun autofillImportPasswordsPromoDialog(
importSource: AutofillImportLaunchSource,
tabId: String,
url: String,
): DialogFragment {
return ImportFromGooglePasswordsDialog.instance(importSource = importSource, tabId = tabId, originalUrl = url)
}

companion object {
const val MAX_PROMO_SHOWN_COUNT = 5
const val MAX_CREDENTIALS_FOR_PROMO = 25
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ class ImportGooglePasswordsWebFlowFragment :
}
}

override suspend fun promptUserTo(event: AutofillPrompt) {
override suspend fun showAutofillPrompt(event: AutofillPrompt) {
// no-op, we don't prompt the user for anything in this flow
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@
package com.duckduckgo.autofill.impl.ui

import androidx.fragment.app.DialogFragment
import com.duckduckgo.autofill.api.AutofillImportLaunchSource
import com.duckduckgo.autofill.api.CredentialAutofillDialogFactory
import com.duckduckgo.autofill.api.CredentialUpdateExistingCredentialsDialog.CredentialUpdateType
import com.duckduckgo.autofill.api.domain.app.LoginCredentials
import com.duckduckgo.autofill.api.domain.app.LoginTriggerType
import com.duckduckgo.autofill.impl.email.EmailProtectionChooseEmailFragment
import com.duckduckgo.autofill.impl.email.incontext.prompt.EmailProtectionInContextSignUpPromptFragment
import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialog
import com.duckduckgo.autofill.impl.ui.credential.passwordgeneration.AutofillUseGeneratedPasswordDialogFragment
import com.duckduckgo.autofill.impl.ui.credential.saving.AutofillSavingCredentialsDialogFragment
import com.duckduckgo.autofill.impl.ui.credential.selecting.AutofillSelectCredentialsDialogFragment
Expand Down Expand Up @@ -103,8 +101,4 @@ class CredentialAutofillDialogAndroidFactory @Inject constructor() : CredentialA
override fun emailProtectionInContextSignUpDialog(tabId: String): DialogFragment {
return EmailProtectionInContextSignUpPromptFragment.instance(tabId)
}

override fun autofillImportPasswordsPromoDialog(importSource: AutofillImportLaunchSource, tabId: String, url: String): DialogFragment {
return ImportFromGooglePasswordsDialog.instance(importSource = importSource, tabId = tabId, originalUrl = url)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ class AutofillStoredBackJavascriptInterfaceTest {
onCredentialsSavedCalled = true
}

override suspend fun promptUserTo(event: AutofillPrompt) {
override suspend fun showAutofillDialgo(event: AutofillPrompt) {
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class InlineBrowserAutofillTest {
override fun onCredentialsSaved(savedCredentials: LoginCredentials) {
}

override suspend fun promptUserTo(event: AutofillPrompt) {
override suspend fun showAutofillDialgo(event: AutofillPrompt) {
}
}

Expand Down
Loading