Skip to content

Commit

Permalink
Modify autofill update credential pixel to include backfilled parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
CDRussell committed Jan 14, 2025
1 parent 3d3a41e commit 5206a78
Showing 1 changed file with 48 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.setFragmentResult
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.duckduckgo.anvil.annotations.InjectWith
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.autofill.api.AutofillFeature
import com.duckduckgo.autofill.api.CredentialUpdateExistingCredentialsDialog
import com.duckduckgo.autofill.api.CredentialUpdateExistingCredentialsDialog.CredentialUpdateType
import com.duckduckgo.autofill.api.domain.app.LoginCredentials
Expand All @@ -41,13 +43,19 @@ import com.duckduckgo.autofill.impl.ui.credential.dialog.animateClosed
import com.duckduckgo.autofill.impl.ui.credential.updating.AutofillUpdatingExistingCredentialsDialogFragment.DialogEvent.Dismissed
import com.duckduckgo.autofill.impl.ui.credential.updating.AutofillUpdatingExistingCredentialsDialogFragment.DialogEvent.Shown
import com.duckduckgo.autofill.impl.ui.credential.updating.AutofillUpdatingExistingCredentialsDialogFragment.DialogEvent.Updated
import com.duckduckgo.common.utils.DispatcherProvider
import com.duckduckgo.common.utils.FragmentViewModelFactory
import com.duckduckgo.di.scopes.FragmentScope
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.android.support.AndroidSupportInjection
import javax.inject.Inject
import kotlinx.coroutines.CoroutineStart.LAZY
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber

@InjectWith(FragmentScope::class)
Expand All @@ -67,6 +75,12 @@ class AutofillUpdatingExistingCredentialsDialogFragment : BottomSheetDialogFragm
@Inject
lateinit var partialCredentialSaveStore: PartialCredentialSaveStore

@Inject
lateinit var autofillFeature: AutofillFeature

@Inject
lateinit var dispatchers: DispatcherProvider

/**
* To capture all the ways the BottomSheet can be dismissed, we might end up with onCancel being called when we don't want it
* This flag is set to true when taking an action which dismisses the dialog, but should not be treated as a cancellation.
Expand All @@ -77,6 +91,13 @@ class AutofillUpdatingExistingCredentialsDialogFragment : BottomSheetDialogFragm
ViewModelProvider(this, viewModelFactory)[AutofillUpdatingExistingCredentialViewModel::class.java]
}

private val wasUsernameBackFilled: Deferred<Boolean> = lifecycleScope.async(start = LAZY) {
val usernameToSave = getCredentialsToSave().username ?: return@async false
partialCredentialSaveStore.wasBackFilledRecently(url = getOriginalUrl(), username = usernameToSave).also {
Timber.v("Determined that username was %sbackFilled", if (it) "" else "not ")
}
}

override fun onAttach(context: Context) {
AndroidSupportInjection.inject(this)
super.onAttach(context)
Expand All @@ -96,7 +117,11 @@ class AutofillUpdatingExistingCredentialsDialogFragment : BottomSheetDialogFragm
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
pixelNameDialogEvent(Shown)?.let { pixel.fire(it) }
pixelNameDialogEvent(Shown)?.let {
lifecycleScope.launch {
pixel.fire(it, paramsForUpdateLoginPixel())
}
}

autofillFireproofDialogSuppressor.autofillSaveOrUpdateDialogVisibilityChanged(visible = true)

Expand Down Expand Up @@ -144,7 +169,11 @@ class AutofillUpdatingExistingCredentialsDialogFragment : BottomSheetDialogFragm
}

binding.updateCredentialsButton.setOnClickListener {
pixelNameDialogEvent(Updated)?.let { pixel.fire(it) }
pixelNameDialogEvent(Updated)?.let {
lifecycleScope.launch {
pixel.fire(it, paramsForUpdateLoginPixel())
}
}

val result = Bundle().also {
it.putString(CredentialUpdateExistingCredentialsDialog.KEY_URL, originalUrl)
Expand Down Expand Up @@ -186,7 +215,11 @@ class AutofillUpdatingExistingCredentialsDialogFragment : BottomSheetDialogFragm

Timber.v("onCancel: AutofillUpdatingExistingCredentialsDialogFragment. User declined to update credentials")
autofillFireproofDialogSuppressor.autofillSaveOrUpdateDialogVisibilityChanged(visible = false)
pixelNameDialogEvent(Dismissed)?.let { pixel.fire(it) }
pixelNameDialogEvent(Dismissed)?.let {
lifecycleScope.launch {
pixel.fire(it, paramsForUpdateLoginPixel())
}
}
}

private fun pixelNameDialogEvent(dialogEvent: DialogEvent): AutofillPixelNames? {
Expand All @@ -198,6 +231,16 @@ class AutofillUpdatingExistingCredentialsDialogFragment : BottomSheetDialogFragm
}
}

private suspend fun paramsForUpdateLoginPixel(): Map<String, String> {
return withContext(dispatchers.io()) {
if (autofillFeature.partialFormSaves().isEnabled()) {
mapOf(PIXEL_PARAM_WAS_USERNAME_BACKFILLED to wasUsernameBackFilled.await().toString())
} else {
emptyMap()
}
}
}

private interface DialogEvent {
object Shown : DialogEvent
object Dismissed : DialogEvent
Expand Down Expand Up @@ -228,5 +271,7 @@ class AutofillUpdatingExistingCredentialsDialogFragment : BottomSheetDialogFragm
}
return fragment
}

private const val PIXEL_PARAM_WAS_USERNAME_BACKFILLED = "backfilled"
}
}

0 comments on commit 5206a78

Please sign in to comment.