diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/AutofillImportLaunchSource.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/AutofillImportLaunchSource.kt index ca66bb9c11e9..3114d45fbce6 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/AutofillImportLaunchSource.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/AutofillImportLaunchSource.kt @@ -16,8 +16,14 @@ package com.duckduckgo.autofill.impl.importing -enum class AutofillImportLaunchSource(val value: String) { - PasswordManagementPromo("passwords_management_promo"), - AutofillSettings("autofill_settings"), - PasswordManagementEmpty("passwords_management_empty"), +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +enum class AutofillImportLaunchSource(val value: String) : Parcelable { + PasswordManagementPromo("password_management_promo"), + PasswordManagementEmptyState("password_management_empty_state"), + PasswordManagementOverflow("password_management_overflow"), + AutofillSettings("autofill_settings_button"), + Unknown("unknown"), } diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/promo/ImportInPasswordsPromotionViewModel.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/promo/ImportInPasswordsPromotionViewModel.kt index 35876340328e..2dddde067d94 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/promo/ImportInPasswordsPromotionViewModel.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/promo/ImportInPasswordsPromotionViewModel.kt @@ -20,7 +20,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel import com.duckduckgo.app.statistics.pixels.Pixel -import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementPromo import com.duckduckgo.autofill.impl.importing.promo.ImportInPasswordsPromotionViewModel.Command.DismissImport import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_TAPPED @@ -56,7 +56,7 @@ class ImportInPasswordsPromotionViewModel @Inject constructor( fun onPromoShown() { if (!promoDisplayedPixelSent) { promoDisplayedPixelSent = true - val params = mapOf("source" to AutofillImportLaunchSource.PasswordManagementPromo.value) + val params = mapOf("source" to PasswordManagementPromo.value) pixel.fire(AutofillPixelNames.AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_SHOWN, params) } } @@ -65,10 +65,10 @@ class ImportInPasswordsPromotionViewModel @Inject constructor( viewModelScope.launch(dispatchers.io()) { promoEventDispatcher.emit( AutofillEffect.LaunchImportPasswords( - source = AutofillImportLaunchSource.PasswordManagementPromo, + source = PasswordManagementPromo, ), ) - val params = mapOf("source" to AutofillImportLaunchSource.PasswordManagementPromo.value) + val params = mapOf("source" to PasswordManagementPromo.value) pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_TAPPED, params) } } @@ -77,6 +77,11 @@ class ImportInPasswordsPromotionViewModel @Inject constructor( viewModelScope.launch(dispatchers.io()) { importInPasswordsVisibility.onPromoDismissed() command.send(DismissImport) + pixel.fire( + pixel = AutofillPixelNames.AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_DISMISSED, + parameters = mapOf("source" to PasswordManagementPromo.value), + encodedParameters = emptyMap(), + ) } } } diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/pixel/AutofillPixelNames.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/pixel/AutofillPixelNames.kt index 7377170b2524..fac5e10352e2 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/pixel/AutofillPixelNames.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/pixel/AutofillPixelNames.kt @@ -161,6 +161,7 @@ enum class AutofillPixelNames(override val pixelName: String) : Pixel.PixelName AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_TAPPED("autofill_import_google_passwords_import_button_tapped"), AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_SHOWN("autofill_import_google_passwords_import_button_shown"), + AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_DISMISSED("autofill_import_google_passwords_import_button_dismissed"), AUTOFILL_IMPORT_GOOGLE_PASSWORDS_OVERFLOW_MENU("autofill_import_google_passwords_overflow_menu_tapped"), AUTOFILL_IMPORT_GOOGLE_PASSWORDS_PREIMPORT_PROMPT_DISPLAYED("autofill_import_google_passwords_preimport_prompt_displayed"), AUTOFILL_IMPORT_GOOGLE_PASSWORDS_PREIMPORT_PROMPT_CONFIRMED("autofill_import_google_passwords_preimport_prompt_confirmed"), diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillPasswordsManagementViewModel.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillPasswordsManagementViewModel.kt index ce1e161fe650..ba86ef3ed82b 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillPasswordsManagementViewModel.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillPasswordsManagementViewModel.kt @@ -34,6 +34,7 @@ import com.duckduckgo.autofill.impl.asString import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator.AuthConfiguration import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementPromo import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_DELETE_LOGIN import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_ENABLE_AUTOFILL_TOGGLE_MANUALLY_DISABLED @@ -454,7 +455,7 @@ class AutofillPasswordsManagementViewModel @Inject constructor( viewModelScope.launch(dispatchers.io()) { autofillEffectDispatcher.effects.collect { effect -> when { - effect is LaunchImportPasswords -> addCommand(LaunchImportGooglePasswords(showImportInstructions = false)) + effect is LaunchImportPasswords -> addCommand(LaunchImportGooglePasswords(PasswordManagementPromo)) } } } @@ -738,9 +739,9 @@ class AutofillPasswordsManagementViewModel @Inject constructor( } } - fun onImportPasswordsFromGooglePasswordManager() { + fun onImportPasswordsFromGooglePasswordManager(importSource: AutofillImportLaunchSource) { viewModelScope.launch(dispatchers.io()) { - addCommand(LaunchImportGooglePasswords(showImportInstructions = true)) + addCommand(LaunchImportGooglePasswords(importSource)) } } @@ -814,7 +815,7 @@ class AutofillPasswordsManagementViewModel @Inject constructor( fun recordImportGooglePasswordButtonShown() { if (!importGooglePasswordButtonShownPixelSent) { importGooglePasswordButtonShownPixelSent = true - val params = mapOf("source" to AutofillImportLaunchSource.PasswordManagementEmpty.value) + val params = mapOf("source" to AutofillImportLaunchSource.PasswordManagementEmptyState.value) pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_SHOWN, params) } } @@ -904,7 +905,7 @@ class AutofillPasswordsManagementViewModel @Inject constructor( data object LaunchResetNeverSaveListConfirmation : ListModeCommand() data class LaunchDeleteAllPasswordsConfirmation(val numberToDelete: Int) : ListModeCommand() data class PromptUserToAuthenticateMassDeletion(val authConfiguration: AuthConfiguration) : ListModeCommand() - data class LaunchImportGooglePasswords(val showImportInstructions: Boolean) : ListModeCommand() + data class LaunchImportGooglePasswords(val importSource: AutofillImportLaunchSource) : ListModeCommand() data class LaunchReportAutofillBreakageConfirmation(val eTldPlusOne: String) : ListModeCommand() data object ShowUserReportSentMessage : ListModeCommand() data object ReevalutePromotions : ListModeCommand() diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/ImportPasswordsPixelSender.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/ImportPasswordsPixelSender.kt index fa8fbdc14670..e357ba65a159 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/ImportPasswordsPixelSender.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/ImportPasswordsPixelSender.kt @@ -35,12 +35,12 @@ import com.squareup.anvil.annotations.ContributesBinding import javax.inject.Inject interface ImportPasswordsPixelSender { - fun onImportPasswordsDialogDisplayed() - fun onImportPasswordsDialogImportButtonClicked() - fun onUserCancelledImportPasswordsDialog() - fun onUserCancelledImportWebFlow(stage: String) - fun onImportSuccessful(savedCredentials: Int, numberSkipped: Int) - fun onImportFailed(reason: UserCannotImportReason) + fun onImportPasswordsDialogDisplayed(source: AutofillImportLaunchSource) + fun onImportPasswordsDialogImportButtonClicked(source: AutofillImportLaunchSource) + fun onUserCancelledImportPasswordsDialog(source: AutofillImportLaunchSource) + fun onUserCancelledImportWebFlow(stage: String, source: AutofillImportLaunchSource) + fun onImportSuccessful(savedCredentials: Int, numberSkipped: Int, source: AutofillImportLaunchSource) + fun onImportFailed(reason: UserCannotImportReason, source: AutofillImportLaunchSource) fun onImportPasswordsButtonTapped(launchSource: AutofillImportLaunchSource) fun onImportPasswordsOverflowMenuTapped() fun onImportPasswordsViaDesktopSyncButtonTapped() @@ -53,39 +53,49 @@ class ImportPasswordsPixelSenderImpl @Inject constructor( private val engagementBucketing: AutofillEngagementBucketing, ) : ImportPasswordsPixelSender { - override fun onImportPasswordsDialogDisplayed() { - pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_PREIMPORT_PROMPT_DISPLAYED) + override fun onImportPasswordsDialogDisplayed(source: AutofillImportLaunchSource) { + val params = mapOf(SOURCE_KEY to source.value) + pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_PREIMPORT_PROMPT_DISPLAYED, params) } - override fun onImportPasswordsDialogImportButtonClicked() { - pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_PREIMPORT_PROMPT_CONFIRMED) + override fun onImportPasswordsDialogImportButtonClicked(source: AutofillImportLaunchSource) { + val params = mapOf(SOURCE_KEY to source.value) + pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_PREIMPORT_PROMPT_CONFIRMED, params) } - override fun onUserCancelledImportPasswordsDialog() { - val params = mapOf(CANCELLATION_STAGE_KEY to PRE_IMPORT_DIALOG_STAGE) + override fun onUserCancelledImportPasswordsDialog(source: AutofillImportLaunchSource) { + val params = mapOf( + CANCELLATION_STAGE_KEY to PRE_IMPORT_DIALOG_STAGE, + SOURCE_KEY to source.value, + ) pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_RESULT_FAILURE_USER_CANCELLED, params) } - override fun onUserCancelledImportWebFlow(stage: String) { - val params = mapOf(CANCELLATION_STAGE_KEY to stage) + override fun onUserCancelledImportWebFlow(stage: String, source: AutofillImportLaunchSource) { + val params = mapOf( + CANCELLATION_STAGE_KEY to stage, + SOURCE_KEY to source.value, + ) pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_RESULT_FAILURE_USER_CANCELLED, params) } - override fun onImportSuccessful(savedCredentials: Int, numberSkipped: Int) { + override fun onImportSuccessful(savedCredentials: Int, numberSkipped: Int, source: AutofillImportLaunchSource) { val savedCredentialsBucketed = engagementBucketing.bucketNumberOfCredentials(savedCredentials) val skippedCredentialsBucketed = engagementBucketing.bucketNumberOfCredentials(numberSkipped) val params = mapOf( "saved_credentials" to savedCredentialsBucketed, "skipped_credentials" to skippedCredentialsBucketed, + SOURCE_KEY to source.value, ) pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_RESULT_SUCCESS, params) } - override fun onImportFailed(reason: UserCannotImportReason) { + override fun onImportFailed(reason: UserCannotImportReason, source: AutofillImportLaunchSource) { val pixelName = when (reason) { ErrorParsingCsv -> AUTOFILL_IMPORT_GOOGLE_PASSWORDS_RESULT_FAILURE_ERROR_PARSING } - pixel.fire(pixelName) + val params = mapOf(SOURCE_KEY to source.value) + pixel.fire(pixelName, params) } override fun onImportPasswordsButtonTapped(launchSource: AutofillImportLaunchSource) { @@ -94,7 +104,8 @@ class ImportPasswordsPixelSenderImpl @Inject constructor( } override fun onImportPasswordsOverflowMenuTapped() { - pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_OVERFLOW_MENU) + val params = mapOf(SOURCE_KEY to AutofillImportLaunchSource.PasswordManagementOverflow.value) + pixel.fire(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_OVERFLOW_MENU, params) } override fun onImportPasswordsViaDesktopSyncButtonTapped() { diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialog.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialog.kt index c7cf72dc48d5..3faf1a445a31 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialog.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialog.kt @@ -27,6 +27,7 @@ import android.view.ViewGroup import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import androidx.core.content.IntentCompat +import androidx.core.os.BundleCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider @@ -37,6 +38,9 @@ import com.duckduckgo.app.browser.favicon.FaviconManager import com.duckduckgo.autofill.impl.R import com.duckduckgo.autofill.impl.databinding.ContentImportFromGooglePasswordDialogBinding import com.duckduckgo.autofill.impl.deviceauth.AutofillAuthorizationGracePeriod +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementPromo +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.Unknown import com.duckduckgo.autofill.impl.importing.CredentialImporter import com.duckduckgo.autofill.impl.importing.gpm.webflow.ImportGooglePassword import com.duckduckgo.autofill.impl.importing.gpm.webflow.ImportGooglePasswordResult @@ -102,18 +106,26 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() { if (activityResult.resultCode == Activity.RESULT_OK) { lifecycleScope.launch { activityResult.data?.let { data -> - processImportFlowResult(data) + val launchSource = getLaunchSource() + processImportFlowResult(data, launchSource) } } } } - private fun ImportFromGooglePasswordsDialog.processImportFlowResult(data: Intent) { + private fun getLaunchSource() = + BundleCompat.getParcelable(arguments ?: Bundle(), KEY_LAUNCH_SOURCE, AutofillImportLaunchSource::class.java) ?: Unknown + + private fun ImportFromGooglePasswordsDialog.processImportFlowResult(data: Intent, launchSource: AutofillImportLaunchSource) { (IntentCompat.getParcelableExtra(data, ImportGooglePasswordResult.RESULT_KEY_DETAILS, ImportGooglePasswordResult::class.java)).let { when (it) { - is ImportGooglePasswordResult.Success -> viewModel.onImportFlowFinishedSuccessfully() - is ImportGooglePasswordResult.Error -> viewModel.onImportFlowFinishedWithError(it.reason) - is ImportGooglePasswordResult.UserCancelled -> viewModel.onImportFlowCancelledByUser(it.stage, canShowPreImportDialog()) + is ImportGooglePasswordResult.Success -> viewModel.onImportFlowFinishedSuccessfully(launchSource) + is ImportGooglePasswordResult.Error -> viewModel.onImportFlowFinishedWithError(it.reason, launchSource) + is ImportGooglePasswordResult.UserCancelled -> viewModel.onImportFlowCancelledByUser( + it.stage, + canShowPreImportDialog(launchSource), + launchSource, + ) else -> {} } } @@ -203,14 +215,20 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() { } // check if we should show the initial instructional prompt - if (canShowPreImportDialog()) { - viewModel.shouldShowInitialInstructionalPrompt() + val launchSource = getLaunchSource() + if (canShowPreImportDialog(launchSource)) { + viewModel.shouldShowInitialInstructionalPrompt(launchSource) } else { startImportWebFlow() } } - private fun canShowPreImportDialog() = arguments?.getBoolean(KEY_SHOW_INITIAL_INSTRUCTIONAL_PROMPT, true) ?: true + private fun canShowPreImportDialog(launchSource: AutofillImportLaunchSource): Boolean { + return when (launchSource) { + PasswordManagementPromo -> false + else -> true + } + } override fun onCreateView( inflater: LayoutInflater, @@ -263,7 +281,7 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() { private fun onImportGcmButtonClicked() { startImportWebFlow() - importPasswordsPixelSender.onImportPasswordsDialogImportButtonClicked() + importPasswordsPixelSender.onImportPasswordsDialogImportButtonClicked(getLaunchSource()) } private fun startImportWebFlow() { @@ -285,7 +303,7 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() { return } - importPasswordsPixelSender.onUserCancelledImportPasswordsDialog() + importPasswordsPixelSender.onUserCancelledImportPasswordsDialog(getLaunchSource()) dismiss() } @@ -298,12 +316,12 @@ class ImportFromGooglePasswordsDialog : BottomSheetDialogFragment() { companion object { - private const val KEY_SHOW_INITIAL_INSTRUCTIONAL_PROMPT = "showInitialInstructionalPrompt" + private const val KEY_LAUNCH_SOURCE = "launchSource" - fun instance(showInitialInstructionalPrompt: Boolean): ImportFromGooglePasswordsDialog { + fun instance(importSource: AutofillImportLaunchSource): ImportFromGooglePasswordsDialog { val fragment = ImportFromGooglePasswordsDialog() fragment.arguments = Bundle().apply { - putBoolean(KEY_SHOW_INITIAL_INSTRUCTIONAL_PROMPT, showInitialInstructionalPrompt) + putParcelable(KEY_LAUNCH_SOURCE, importSource) } return fragment } diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModel.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModel.kt index bdd3e40d1a4b..d106a2f32e54 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModel.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModel.kt @@ -19,6 +19,7 @@ package com.duckduckgo.autofill.impl.ui.credential.management.importpassword.goo import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource import com.duckduckgo.autofill.impl.importing.CredentialImporter import com.duckduckgo.autofill.impl.importing.CredentialImporter.ImportResult import com.duckduckgo.autofill.impl.importing.gpm.webflow.ImportGooglePasswordsWebFlowViewModel.UserCannotImportReason @@ -41,13 +42,13 @@ class ImportFromGooglePasswordsDialogViewModel @Inject constructor( private val importPasswordsPixelSender: ImportPasswordsPixelSender, ) : ViewModel() { - fun onImportFlowFinishedSuccessfully() { + fun onImportFlowFinishedSuccessfully(importSource: AutofillImportLaunchSource) { viewModelScope.launch(dispatchers.main()) { - observeImportJob() + observeImportJob(importSource) } } - private suspend fun observeImportJob() { + private suspend fun observeImportJob(importSource: AutofillImportLaunchSource) { credentialImporter.getImportStatus().collect { when (it) { is ImportResult.InProgress -> { @@ -57,36 +58,40 @@ class ImportFromGooglePasswordsDialogViewModel @Inject constructor( is ImportResult.Finished -> { logcat { "Import finished: ${it.savedCredentials} imported. ${it.numberSkipped} skipped." } - fireImportSuccessPixel(savedCredentials = it.savedCredentials, numberSkipped = it.numberSkipped) + fireImportSuccessPixel(savedCredentials = it.savedCredentials, numberSkipped = it.numberSkipped, importSource = importSource) _viewState.value = ViewState(viewMode = ViewMode.ImportSuccess(it)) } } } } - fun onImportFlowFinishedWithError(reason: UserCannotImportReason) { - fireImportFailedPixel(reason) + fun onImportFlowFinishedWithError(reason: UserCannotImportReason, importSource: AutofillImportLaunchSource) { + fireImportFailedPixel(reason, importSource) _viewState.value = ViewState(viewMode = ViewMode.ImportError) } - fun onImportFlowCancelledByUser(stage: String, canShowPreImportDialog: Boolean) { - importPasswordsPixelSender.onUserCancelledImportWebFlow(stage) + fun onImportFlowCancelledByUser(stage: String, canShowPreImportDialog: Boolean, importSource: AutofillImportLaunchSource) { + importPasswordsPixelSender.onUserCancelledImportWebFlow(stage, importSource) if (!canShowPreImportDialog) { _viewState.value = ViewState(viewMode = ViewMode.FlowTerminated) } } - private fun fireImportSuccessPixel(savedCredentials: Int, numberSkipped: Int) { - importPasswordsPixelSender.onImportSuccessful(savedCredentials = savedCredentials, numberSkipped = numberSkipped) + private fun fireImportSuccessPixel(savedCredentials: Int, numberSkipped: Int, importSource: AutofillImportLaunchSource) { + importPasswordsPixelSender.onImportSuccessful( + savedCredentials = savedCredentials, + numberSkipped = numberSkipped, + source = importSource, + ) } - private fun fireImportFailedPixel(reason: UserCannotImportReason) { - importPasswordsPixelSender.onImportFailed(reason) + private fun fireImportFailedPixel(reason: UserCannotImportReason, importSource: AutofillImportLaunchSource) { + importPasswordsPixelSender.onImportFailed(reason, importSource) } - fun shouldShowInitialInstructionalPrompt() { - importPasswordsPixelSender.onImportPasswordsDialogDisplayed() + fun shouldShowInitialInstructionalPrompt(importSource: AutofillImportLaunchSource) { + importPasswordsPixelSender.onImportPasswordsDialogDisplayed(importSource) _viewState.value = viewState.value.copy(viewMode = PreImport) } diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListMode.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListMode.kt index a1d4f26af076..6c2db8ea9f1a 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListMode.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListMode.kt @@ -37,7 +37,9 @@ import com.duckduckgo.autofill.impl.databinding.FragmentAutofillManagementListMo import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator.AuthConfiguration import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator.AuthResult.Success -import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementEmpty +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementEmptyState +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementOverflow import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementActivity import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementRecyclerAdapter import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementRecyclerAdapter.AutofillToggleState @@ -233,7 +235,7 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill } R.id.importGooglePasswords -> { - viewModel.onImportPasswordsFromGooglePasswordManager() + viewModel.onImportPasswordsFromGooglePasswordManager(importSource = PasswordManagementOverflow) importPasswordsPixelSender.onImportPasswordsOverflowMenuTapped() true } @@ -339,7 +341,7 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill LaunchResetNeverSaveListConfirmation -> launchResetNeverSavedSitesConfirmation() is LaunchDeleteAllPasswordsConfirmation -> launchDeleteAllLoginsConfirmationDialog(command.numberToDelete) is PromptUserToAuthenticateMassDeletion -> promptUserToAuthenticateMassDeletion(command.authConfiguration) - is LaunchImportGooglePasswords -> launchImportPasswordsScreen(showInitialInstructionalPrompt = command.showImportInstructions) + is LaunchImportGooglePasswords -> launchImportPasswordsScreen(importSource = command.importSource) is LaunchReportAutofillBreakageConfirmation -> launchReportBreakageConfirmation(command.eTldPlusOne) is ShowUserReportSentMessage -> showUserReportSentMessage() is ReevalutePromotions -> evaluatePromotions() @@ -357,9 +359,9 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill Snackbar.make(binding.root, R.string.autofillManagementReportBreakageSuccessMessage, Snackbar.LENGTH_LONG).show() } - private fun launchImportPasswordsScreen(showInitialInstructionalPrompt: Boolean) { + private fun launchImportPasswordsScreen(importSource: AutofillImportLaunchSource) { context?.let { - val dialog = ImportFromGooglePasswordsDialog.instance(showInitialInstructionalPrompt = showInitialInstructionalPrompt) + val dialog = ImportFromGooglePasswordsDialog.instance(importSource = importSource) dialog.show(parentFragmentManager, IMPORT_FROM_GPM_DIALOG_TAG) } } @@ -523,7 +525,7 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill onReportBreakageClicked = { viewModel.onReportBreakageClicked() }, launchHelpPageClicked = this::launchHelpPage, onAutofillToggleClicked = this::onAutofillToggledChanged, - onImportFromGoogleClicked = this::onImportFromGoogleClicked, + onImportFromGoogleClicked = this::onImportFromGoogleClickedFromEmptyList, onImportViaDesktopSyncClicked = this::onImportViaDesktopSyncClicked, ).also { binding.logins.adapter = it } } @@ -536,9 +538,9 @@ class AutofillManagementListMode : DuckDuckGoFragment(R.layout.fragment_autofill } } - private fun onImportFromGoogleClicked() { - viewModel.onImportPasswordsFromGooglePasswordManager() - importPasswordsPixelSender.onImportPasswordsButtonTapped(PasswordManagementEmpty) + private fun onImportFromGoogleClickedFromEmptyList() { + viewModel.onImportPasswordsFromGooglePasswordManager(PasswordManagementEmptyState) + importPasswordsPixelSender.onImportPasswordsButtonTapped(PasswordManagementEmptyState) } private fun onImportViaDesktopSyncClicked() { diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListModeLegacy.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListModeLegacy.kt index 85c5b11d8081..fb4745c2f3a0 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListModeLegacy.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/viewing/AutofillManagementListModeLegacy.kt @@ -46,7 +46,9 @@ import com.duckduckgo.autofill.impl.databinding.FragmentAutofillManagementListMo import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator.AuthConfiguration import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator.AuthResult.Success -import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementEmpty +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementEmptyState +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementOverflow import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementActivity import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementRecyclerAdapterLegacy import com.duckduckgo.autofill.impl.ui.credential.management.AutofillManagementRecyclerAdapterLegacy.ContextMenuAction.CopyPassword @@ -244,8 +246,8 @@ class AutofillManagementListModeLegacy : DuckDuckGoFragment(R.layout.fragment_au private fun configureImportPasswordsButton() { binding.emptyStateLayout.importPasswordsFromGoogleButton.setOnClickListener { - viewModel.onImportPasswordsFromGooglePasswordManager() - importPasswordsPixelSender.onImportPasswordsButtonTapped(PasswordManagementEmpty) + viewModel.onImportPasswordsFromGooglePasswordManager(PasswordManagementEmptyState) + importPasswordsPixelSender.onImportPasswordsButtonTapped(launchSource = PasswordManagementEmptyState) } binding.emptyStateLayout.importPasswordsViaDesktopSyncButton.setOnClickListener { @@ -298,7 +300,7 @@ class AutofillManagementListModeLegacy : DuckDuckGoFragment(R.layout.fragment_au } R.id.importGooglePasswords -> { - viewModel.onImportPasswordsFromGooglePasswordManager() + viewModel.onImportPasswordsFromGooglePasswordManager(PasswordManagementOverflow) importPasswordsPixelSender.onImportPasswordsOverflowMenuTapped() true } @@ -421,7 +423,7 @@ class AutofillManagementListModeLegacy : DuckDuckGoFragment(R.layout.fragment_au LaunchResetNeverSaveListConfirmation -> launchResetNeverSavedSitesConfirmation() is LaunchDeleteAllPasswordsConfirmation -> launchDeleteAllLoginsConfirmationDialog(command.numberToDelete) is PromptUserToAuthenticateMassDeletion -> promptUserToAuthenticateMassDeletion(command.authConfiguration) - is LaunchImportGooglePasswords -> launchImportPasswordsScreen(command.showImportInstructions) + is LaunchImportGooglePasswords -> launchImportPasswordsScreen(command.importSource) is LaunchReportAutofillBreakageConfirmation -> launchReportBreakageConfirmation(command.eTldPlusOne) is ShowUserReportSentMessage -> showUserReportSentMessage() is ReevalutePromotions -> configurePromotionsContainer() @@ -433,9 +435,9 @@ class AutofillManagementListModeLegacy : DuckDuckGoFragment(R.layout.fragment_au Snackbar.make(binding.root, R.string.autofillManagementReportBreakageSuccessMessage, Snackbar.LENGTH_LONG).show() } - private fun launchImportPasswordsScreen(showImportInstructions: Boolean) { + private fun launchImportPasswordsScreen(importSource: AutofillImportLaunchSource) { context?.let { - val dialog = ImportFromGooglePasswordsDialog.instance(showInitialInstructionalPrompt = showImportInstructions) + val dialog = ImportFromGooglePasswordsDialog.instance(importSource) dialog.show(parentFragmentManager, IMPORT_FROM_GPM_DIALOG_TAG) } } diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsActivity.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsActivity.kt index 3a35ff28f046..b83a959ae384 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsActivity.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsActivity.kt @@ -33,6 +33,7 @@ import com.duckduckgo.autofill.api.AutofillScreens.AutofillPasswordsManagementSc import com.duckduckgo.autofill.api.AutofillScreens.AutofillSettingsScreen import com.duckduckgo.autofill.impl.R import com.duckduckgo.autofill.impl.databinding.ActivityAutofillSettingsBinding +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.ImportPasswordActivityParams import com.duckduckgo.autofill.impl.ui.credential.management.importpassword.google.ImportFromGooglePasswordsDialog import com.duckduckgo.autofill.impl.ui.credential.management.viewing.AutofillManagementDeviceUnsupportedMode @@ -174,7 +175,7 @@ class AutofillSettingsActivity : DuckDuckGoActivity() { viewModel.onPasswordListClicked() } binding.autofillAvailable.importPasswordsOption.setOnClickListener { - viewModel.onImportPasswordsClicked(getAutofillSettingsLaunchSource()) + viewModel.onImportPasswordsClicked(AutofillImportLaunchSource.AutofillSettings) } binding.autofillAvailable.syncDesktopPasswordsOption.setOnClickListener { viewModel.onImportFromDesktopWithSyncClicked(getAutofillSettingsLaunchSource()) @@ -223,7 +224,7 @@ class AutofillSettingsActivity : DuckDuckGoActivity() { } private fun launchImportPasswordsScreen() { - val dialog = ImportFromGooglePasswordsDialog.instance(showInitialInstructionalPrompt = true) + val dialog = ImportFromGooglePasswordsDialog.instance(AutofillImportLaunchSource.AutofillSettings) dialog.show(supportFragmentManager, IMPORT_FROM_GPM_DIALOG_TAG) } diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModel.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModel.kt index 7c9621aa1c63..e98d920b2191 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModel.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModel.kt @@ -190,13 +190,13 @@ class AutofillSettingsViewModel @Inject constructor( } } - fun onImportPasswordsClicked(autofillScreenLaunchSource: AutofillScreenLaunchSource?) { + fun onImportPasswordsClicked(launchSource: AutofillImportLaunchSource) { viewModelScope.launch { _commands.send(ImportPasswordsFromGoogle) // we use AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_TAPPED for consistency with iOS pixel.fire( AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_TAPPED, - mapOf("source" to AutofillImportLaunchSource.AutofillSettings.value), + mapOf("source" to launchSource.value), ) } } diff --git a/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillSettingsActivityScreenViewModelTest.kt b/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillSettingsActivityScreenViewModelTest.kt index 8bdb6fc102d6..f079fa54e16e 100644 --- a/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillSettingsActivityScreenViewModelTest.kt +++ b/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillSettingsActivityScreenViewModelTest.kt @@ -38,6 +38,7 @@ import com.duckduckgo.autofill.api.domain.app.LoginCredentials import com.duckduckgo.autofill.api.email.EmailManager import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator import com.duckduckgo.autofill.impl.encoding.UrlUnicodeNormalizerImpl +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.PasswordManagementEmptyState import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_COPY_PASSWORD import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_COPY_USERNAME @@ -1065,11 +1066,11 @@ class AutofillSettingsActivityScreenViewModelTest { @Test fun whenOnImportPasswordsFromGooglePasswordManagerCalledThenCorrectCommandIsAdded() = runTest { - testee.onImportPasswordsFromGooglePasswordManager() + testee.onImportPasswordsFromGooglePasswordManager(PasswordManagementEmptyState) testee.commandsListView.test { val commands = awaitItem() - assertTrue(commands.contains(LaunchImportGooglePasswords(true))) + assertTrue(commands.contains(LaunchImportGooglePasswords(PasswordManagementEmptyState))) cancelAndIgnoreRemainingEvents() } } diff --git a/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModelTest.kt b/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModelTest.kt index 91333786cec1..9001d918c636 100644 --- a/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModelTest.kt +++ b/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/credential/management/importpassword/google/ImportFromGooglePasswordsDialogViewModelTest.kt @@ -2,6 +2,7 @@ package com.duckduckgo.autofill.impl.ui.credential.management.importpassword.goo import app.cash.turbine.TurbineTestContext import app.cash.turbine.test +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource import com.duckduckgo.autofill.impl.importing.CredentialImporter import com.duckduckgo.autofill.impl.importing.CredentialImporter.ImportResult.Finished import com.duckduckgo.autofill.impl.importing.CredentialImporter.ImportResult.InProgress @@ -46,7 +47,7 @@ class ImportFromGooglePasswordsDialogViewModelTest { @Test fun whenParsingErrorOnImportThenViewModeUpdatedToError() = runTest { - testee.onImportFlowFinishedWithError(ErrorParsingCsv) + testee.onImportFlowFinishedWithError(reason = ErrorParsingCsv, importSource = TEST_SOURCE) testee.viewState.test { assertTrue(awaitItem().viewMode is ViewMode.ImportError) } @@ -55,8 +56,8 @@ class ImportFromGooglePasswordsDialogViewModelTest { @Test fun whenSuccessfulImportThenViewModeUpdatedToInProgress() = runTest { configureImportInProgress() - testee.shouldShowInitialInstructionalPrompt() - testee.onImportFlowFinishedSuccessfully() + testee.shouldShowInitialInstructionalPrompt(importSource = TEST_SOURCE) + testee.onImportFlowFinishedSuccessfully(importSource = TEST_SOURCE) testee.viewState.test { awaitImportInProgress() } @@ -65,8 +66,8 @@ class ImportFromGooglePasswordsDialogViewModelTest { @Test fun whenSuccessfulImportFlowThenImportFinishesNothingImportedThenViewModeUpdatedToResults() = runTest { configureImportFinished(savedCredentials = 0, numberSkipped = 0) - testee.shouldShowInitialInstructionalPrompt() - testee.onImportFlowFinishedSuccessfully() + testee.shouldShowInitialInstructionalPrompt(importSource = TEST_SOURCE) + testee.onImportFlowFinishedSuccessfully(importSource = TEST_SOURCE) testee.viewState.test { awaitImportSuccess() } @@ -75,8 +76,8 @@ class ImportFromGooglePasswordsDialogViewModelTest { @Test fun whenSuccessfulImportFlowThenImportFinishesCredentialsImportedNoDuplicatesThenViewModeUpdatedToResults() = runTest { configureImportFinished(savedCredentials = 10, numberSkipped = 0) - testee.shouldShowInitialInstructionalPrompt() - testee.onImportFlowFinishedSuccessfully() + testee.shouldShowInitialInstructionalPrompt(importSource = TEST_SOURCE) + testee.onImportFlowFinishedSuccessfully(importSource = TEST_SOURCE) testee.viewState.test { val result = awaitImportSuccess() assertEquals(10, result.importResult.savedCredentials) @@ -87,8 +88,8 @@ class ImportFromGooglePasswordsDialogViewModelTest { @Test fun whenSuccessfulImportFlowThenImportFinishesOnlyDuplicatesThenViewModeUpdatedToResults() = runTest { configureImportFinished(savedCredentials = 0, numberSkipped = 2) - testee.shouldShowInitialInstructionalPrompt() - testee.onImportFlowFinishedSuccessfully() + testee.shouldShowInitialInstructionalPrompt(importSource = TEST_SOURCE) + testee.onImportFlowFinishedSuccessfully(importSource = TEST_SOURCE) testee.viewState.test { val result = awaitImportSuccess() assertEquals(0, result.importResult.savedCredentials) @@ -98,8 +99,8 @@ class ImportFromGooglePasswordsDialogViewModelTest { @Test fun whenSuccessfulImportNoUpdatesThenThenViewModeFirstInitialisedToPreImport() = runTest { - testee.shouldShowInitialInstructionalPrompt() - testee.onImportFlowFinishedSuccessfully() + testee.shouldShowInitialInstructionalPrompt(importSource = TEST_SOURCE) + testee.onImportFlowFinishedSuccessfully(importSource = TEST_SOURCE) testee.viewState.test { awaitItem().assertIsPreImport() } @@ -114,7 +115,7 @@ class ImportFromGooglePasswordsDialogViewModelTest { @Test fun whenFirstCreatedPreImportRequiredThenViewModeFirstInitialisedToPreImportView() = runTest { - testee.shouldShowInitialInstructionalPrompt() + testee.shouldShowInitialInstructionalPrompt(importSource = TEST_SOURCE) testee.viewState.test { awaitItem().assertIsPreImport() } @@ -158,4 +159,8 @@ class ImportFromGooglePasswordsDialogViewModelTest { private fun ViewState.assertIsDeterminingFirstViewToShow() { assertTrue(viewMode is DeterminingFirstView) } + + companion object { + private val TEST_SOURCE = AutofillImportLaunchSource.PasswordManagementEmptyState + } } diff --git a/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModelTest.kt b/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModelTest.kt index 7dd92a74f248..17dca6832f51 100644 --- a/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModelTest.kt +++ b/autofill/autofill-impl/src/test/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModelTest.kt @@ -9,7 +9,9 @@ import com.duckduckgo.app.browser.api.WebViewCapabilityChecker.WebViewCapability import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.autofill.api.AutofillFeature import com.duckduckgo.autofill.api.AutofillScreenLaunchSource +import com.duckduckgo.autofill.api.AutofillScreenLaunchSource.SettingsActivity import com.duckduckgo.autofill.impl.deviceauth.DeviceAuthenticator +import com.duckduckgo.autofill.impl.importing.AutofillImportLaunchSource.AutofillSettings import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_ENABLE_AUTOFILL_TOGGLE_MANUALLY_DISABLED import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_ENABLE_AUTOFILL_TOGGLE_MANUALLY_ENABLED import com.duckduckgo.autofill.impl.pixel.AutofillPixelNames.AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_SHOWN @@ -84,7 +86,7 @@ class AutofillSettingsViewModelTest { fun whenScreenRendersIfImportButtonAvailableThenPixelIsSent() = runTest { testee.viewState(launchSource).test { awaitItem() - val expectedParams = mapOf("source" to "autofill_settings") + val expectedParams = mapOf("source" to AutofillSettings.value) verify(pixel).fire( pixel = eq(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_SHOWN), parameters = eq(expectedParams), @@ -273,10 +275,10 @@ class AutofillSettingsViewModelTest { @Test fun whenUserClickOnImportGooglePasswordsThenCommandIsSent() = runTest { - testee.onImportPasswordsClicked(AutofillScreenLaunchSource.SettingsActivity) + testee.onImportPasswordsClicked(AutofillSettings) testee.commands.test { assertEquals(AutofillSettingsViewModel.Command.ImportPasswordsFromGoogle, awaitItem()) - val expectedParams = mapOf("source" to "autofill_settings") + val expectedParams = mapOf("source" to AutofillSettings.value) verify(pixel).fire( pixel = eq(AUTOFILL_IMPORT_GOOGLE_PASSWORDS_EMPTY_STATE_CTA_BUTTON_TAPPED), parameters = eq(expectedParams),