Skip to content

Update password import onboarding pixels - #9746

Open
catalinradoiu wants to merge 2 commits into
developfrom
feature/cradoiu/onboarding-import-pixels
Open

Update password import onboarding pixels#9746
catalinradoiu wants to merge 2 commits into
developfrom
feature/cradoiu/onboarding-import-pixels

Conversation

@catalinradoiu

@catalinradoiu catalinradoiu commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Task/Issue URL: https://app.asana.com/1/137249556945/project/72649045549333/task/1217265967787217
Tech Design URL (if applicable):
API Proposals URL(s) (if applicable): None

Description

The following pixels are now sent for the import passwords step in the linear onboarding.

wire name event value
onboarding_password-import shown
clicked engage (Import) / dismiss (Skip)
onboarding_password-import-complete shown
clicked engage (Continue)
onboarding_password-import-error shown transient (retry alert) / permanent (failed screen)
clicked retry / dismiss (retry alert buttons), engage (Continue on the failed screen)

All three carry the usual onboarding params (installType, daysSinceInstall, flow, pixelSource, variant) and are unique per install per (event, value).

Steps to test this PR

Apply the following patch to force the passwords import in the onboarding:

📄 Patch: NewUserOnboardingPlanProvider.kt
Index: app/src/main/java/com/duckduckgo/app/onboarding/orchestrator/NewUserOnboardingPlanProvider.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app/src/main/java/com/duckduckgo/app/onboarding/orchestrator/NewUserOnboardingPlanProvider.kt b/app/src/main/java/com/duckduckgo/app/onboarding/orchestrator/NewUserOnboardingPlanProvider.kt
--- a/app/src/main/java/com/duckduckgo/app/onboarding/orchestrator/NewUserOnboardingPlanProvider.kt	(revision 3e9e40cda1e5ccb18f16b73e9852812cb598459b)
+++ b/app/src/main/java/com/duckduckgo/app/onboarding/orchestrator/NewUserOnboardingPlanProvider.kt	(date 1788876984615)
@@ -203,7 +203,7 @@
                     add(widgetPromptStep(ctx))
                     add(addWidgetStep(ctx))
                 }
-                if (showPasswordImport) {
+                if (true) {
                     add(passwordImportStep(ctx))
                     add(passwordImportLaunchStep(ctx))
                     add(passwordImportCompleteStep(ctx))

Successful import

  • Cleain install the app
  • Walk the onboarding to the "import passwords" card and confirm onboarding_password-import fires with event=shown
  • Tap Import and confirm event=clicked, value=engage
  • Complete the import flow and confirm onboarding_password-import-complete fires with event=shown once the card resolves
  • Tap Continue and confirm onboarding_password-import-complete fires with event=clicked, value=engage

Skipping the prompt

  • Reach the import card and tap Skip
  • Confirm onboarding_password-import fires event=clicked, value=dismiss and that no complete or error pixel follows

Transient failure (retry alert)

Apply the following patch:

📄 Patch: RealImportPasswordsFromGoogle.kt
Index: autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt
--- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt	(revision 3e9e40cda1e5ccb18f16b73e9852812cb598459b)
+++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt	(date 1788873046522)
@@ -38,9 +38,16 @@
     private val credentialImporter: CredentialImporter,
 ) : ImportPasswordsFromGoogle {
 
+    // TODO: LOCAL ONLY - REVERT BEFORE COMMITTING.
+    // Forces every returned web flow to report this result.
+    // null for the real result; Error.Transient for the retry alert; Error.Permanent for the failed outcome card.
+    private val simulatedResult: ImportPasswordsResult? = ImportPasswordsResult.Error.Transient
+
     override suspend fun isSupported(): Boolean = capabilityChecker.webViewCapableOfImporting()
 
     override fun parseResult(data: Intent?): ImportPasswordsResult {
+        simulatedResult?.let { return it }
+
         val result = data?.let {
             IntentCompat.getParcelableExtra(it, ImportGooglePasswordResult.RESULT_KEY_DETAILS, ImportGooglePasswordResult::class.java)
         }
  • Force the web flow to return a transient error (e.g. temporarily return ImportPasswordsResult.Error.Transient from RealImportPasswordsFromGoogle)
  • Confirm onboarding_password-import-error fires event=shown, value=transient and the retry alert appears over the import card
  • Tap Retry: confirm event=clicked, value=retry, the web flow relaunches, and no second onboarding_password-import clicked=engage is fired
  • Repeat and tap Cancel instead: confirm event=clicked, value=dismiss and that onboarding continues past the import step
  • Repeat and dismiss the alert by tapping outside it: confirm no pixel is fired

Permanent failure

📄 Patch: RealImportPasswordsFromGoogle.kt

Apply the following patch and clean install the app.

Index: autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt
--- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt	(revision 3e9e40cda1e5ccb18f16b73e9852812cb598459b)
+++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/RealImportPasswordsFromGoogle.kt	(date 1788873046522)
@@ -38,9 +38,16 @@
     private val credentialImporter: CredentialImporter,
 ) : ImportPasswordsFromGoogle {
 
+    // TODO: LOCAL ONLY - REVERT BEFORE COMMITTING.
+    // Forces every returned web flow to report this result.
+    // null for the real result; Error.Transient for the retry alert; Error.Permanent for the failed outcome card.
+    private val simulatedResult: ImportPasswordsResult? = ImportPasswordsResult.Error.Permanent
+
     override suspend fun isSupported(): Boolean = capabilityChecker.webViewCapableOfImporting()
 
     override fun parseResult(data: Intent?): ImportPasswordsResult {
+        simulatedResult?.let { return it }
+
         val result = data?.let {
             IntentCompat.getParcelableExtra(it, ImportGooglePasswordResult.RESULT_KEY_DETAILS, ImportGooglePasswordResult::class.java)
         }
  • Reach the import flow and press back inside the web flow
  • Confirm the outcome card shows the failed state and onboarding_password-import-error fires event=shown, value=permanent
  • Tap Continue and confirm event=clicked, value=engage

Cancelling the web flow

Revert the previous changes.

  • Reach the import card, tap Import, then back out of the Google export page
  • Confirm you land back on the import card and that no onboarding_password-import-complete or -error pixel is fired

UI changes

Before After
No UI changes No UI changes

Note

Low Risk
Changes are limited to onboarding analytics and event routing; user-facing flow behavior is intentionally preserved with no auth or data-path changes.

Overview
Password import onboarding telemetry is split from one pixel with confirmed outcomes into three wire names: onboarding_password-import (initial Import/Skip only), onboarding_password-import-complete (success screen shown + Continue), and onboarding_password-import-error (transient retry alert vs permanent failure, with retry / dismiss / engage clicks). Pixel definitions in onboarding.json5 and OnboardingPixelName are updated to match.

The orchestrator and OnboardingPixelSender stop emitting PasswordImportConfirmed / event=confirmed; launch and complete steps fire the new pixels at the right lifecycle points (e.g. transient error on web-flow failure, permanent error when the outcome card is failed, no complete/error pixel when the user backs out of the Google export). Retry and Cancel on the error alert use dedicated events (PasswordImportErrorRetryRequested / PasswordImportErrorCancelled) so retry does not double-count an Import engage and cancel on the alert skips the flow without a main-pixel dismiss.

Unit tests for the plan provider, pixel sender, and config-driven view model are updated for the new events and parameter values.

Reviewed by Cursor Bugbot for commit 2629eaf. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@catalinradoiu catalinradoiu changed the title Split onboarding password-import telemetry into three pixels Update password-import onboarding pixels Sep 8, 2026
@catalinradoiu catalinradoiu changed the title Update password-import onboarding pixels Update password import onboarding pixels Sep 8, 2026
Report the initial import prompt, the import-complete screen and import
failures as separate shown/clicked pixels instead of one pixel carrying a
confirmed outcome, and leave the export web flow to its own pixels. The
retry alert's buttons now emit their own events so they are no longer
indistinguishable from the prompt's Import/Skip CTAs.

https://app.asana.com/1/137249556945/project/72649045549333/task/1217265967787217

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@catalinradoiu
catalinradoiu force-pushed the feature/cradoiu/onboarding-import-pixels branch from 908778d to 3e9e40c Compare September 8, 2026 14:12
@catalinradoiu
catalinradoiu marked this pull request as ready for review September 8, 2026 14:26
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Privacy Review task: https://app.asana.com/0/69071770703008/1218276218300847

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants