Skip to content

Add pixel instrumentation for NTP after idle feature#8177

Merged
YoussefKeyrouz merged 2 commits intodevelopfrom
feature/david/hatch_pixels
Apr 17, 2026
Merged

Add pixel instrumentation for NTP after idle feature#8177
YoussefKeyrouz merged 2 commits intodevelopfrom
feature/david/hatch_pixels

Conversation

@malmstein
Copy link
Copy Markdown
Contributor

@malmstein malmstein commented Apr 1, 2026

Task/Issue URL: https://app.asana.com/1/137249556945/project/1174433894299346/task/1213542861384504?focus=true

Description

Adds pixel instrumentation to measure user behaviour for the "NTP after idle" feature. Tracks whether the NTP was shown due to inactivity or by the user, and attributes downstream interactions accordingly.

New pixels (count + daily for each):

  • m_ntp_after_idle_ntp_shown_after_idle — NTP shown because idle threshold was met
  • m_ntp_after_idle_ntp_shown_user_initiated — NTP opened by the user
  • m_ntp_after_idle_return_to_page_tapped_after_idle/user_initiated — hatch card tapped
  • m_ntp_after_idle_bar_used_from_ntp_after_idle/user_initiated — search submitted from NTP
  • m_ntp_after_idle_timeout_selected_[seconds] + daily — user selects an idle timeout value

Implementation:

  • NtpAfterIdleRepository (new-tab-page-api) stores whether the last NTP was shown after idle, propagating context to downstream events in other modules
  • FirstScreenHandler sets the flag and fires shown pixels at the decision point
  • BrowserTabFragment and InputScreenFragment fire hatch tapped pixels in their HatchListener.onHatchPressed() implementations
  • OmnibarLayoutViewModel fires bar used pixels on onEnterKeyPressed when in NTP context
  • ShowOnAppLaunchViewModel fires timeout selected pixels alongside the existing m_settings_after_inactivity_timeout_changed pixel

Steps to test this PR

  • Enable showNTPAfterIdleReturn feature flag via remote config or internal override
  • Background the app, wait past the idle threshold, re-open — verify m_ntp_after_idle_ntp_shown_after_idle fires in logs
  • Open a new tab manually — verify m_ntp_after_idle_ntp_shown_user_initiated fires
  • Tap the hatch card — verify the appropriate return_to_page_tapped_* pixel fires based on how the NTP was shown
  • Submit a search from the NTP — verify the appropriate bar_used_from_ntp_* pixel fires
  • Change the idle timeout in Settings → After Inactivity — verify m_ntp_after_idle_timeout_selected_[seconds] fires

Updates since review

While reviewing the initial version I spotted a few issues and decided to address them in this PR rather than defer to another one. The main fix is a bug where hatch/search pixels on any NTP opened after the initial idle-return were still being classified as after-idle, and where pixels fired incorrectly when other options (LastOpenedTab, SpecificPage) are selected. The rest is scope that fell out of that.

  • Bug fix: hatch/search pixels were misclassified on NTPs opened after the initial idle return. Manual user switching was not fully covered. Classification now happens correctly per-render.
  • API redesign: NtpAfterIdleManager methods renamed to clean them up and hide implementation details.
  • Unified NTP detection: BrowserViewModel observes flowSelectedTab and notifies the manager whenever the selected tab becomes an NTP. This covers all scenarios such as new tabs, tab-switcher selections, and NTP transitions in the same tab.
  • onIdleReturnTriggered() now fires from ShowOnAppLaunchOptionHandler's NewTabPage branch, so the shown pixel only fires when an NTP actually renders.
  • Search coverage expanded: hook moved to BrowserTabViewModel.onUserSubmittedQuery, so omnibar Enter, autocomplete taps, voice search, and InputScreen search mode all count. Duck.ai chats excluded.
  • Pixel rename: ..._timeout_selected_1 → ..._timeout_selected_always (stored 1L unchanged, will change it to 0 in next PR to avoid noise here).
  • Tests: added test coverage for all new call sites and new test for the manager.

UI changes

N/A


Note

Medium Risk
Adds new cross-module event tracking tied into tab selection, app-launch routing, and omnibar submission paths; while mostly analytics, the new hooks and state classification could misfire or regress NTP/launch behavior if edge cases are missed.

Overview
Adds a new NtpAfterIdleManager (+ impl) that classifies NTP renders as after-idle vs user-initiated and fires new count+daily pixels for NTP shown, return-to-page hatch taps, NTP searches, and idle-timeout selections.

Wires this manager into app launch and browsing flows: ShowOnAppLaunchOptionHandler now marks true idle-triggered returns before creating an NTP tab, BrowserViewModel observes selected-tab changes to detect NTP visibility, BrowserTabViewModel records searches submitted from an NTP, and hatch tap handlers in BrowserTabFragment/InputScreenFragment notify the manager. Tests are updated/added to cover the new notifications and classification behavior, and a pixel param-removal plugin is added for the new pixel set.

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

@YoussefKeyrouz YoussefKeyrouz force-pushed the feature/david/hatch_pixels branch from fafc2a4 to cab9144 Compare April 17, 2026 03:25
Copy link
Copy Markdown
Collaborator

YoussefKeyrouz commented Apr 17, 2026

@YoussefKeyrouz YoussefKeyrouz marked this pull request as ready for review April 17, 2026 03:37
@YoussefKeyrouz YoussefKeyrouz force-pushed the feature/david/hatch_pixels branch from cab9144 to 21fd2c2 Compare April 17, 2026 04:21
Comment thread app/src/main/java/com/duckduckgo/app/browser/BrowserViewModel.kt
@github-actions
Copy link
Copy Markdown
Contributor

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

Copy link
Copy Markdown
Contributor

@joshliebe joshliebe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested, LGTM 🚀

@YoussefKeyrouz YoussefKeyrouz force-pushed the feature/david/hatch_pixels branch from 4e2f5d5 to a021a5e Compare April 17, 2026 21:56
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a021a5e. Configure here.

@YoussefKeyrouz YoussefKeyrouz force-pushed the feature/david/hatch_pixels branch from a021a5e to 41ec2df Compare April 17, 2026 22:16
@YoussefKeyrouz YoussefKeyrouz merged commit d7a4ec9 into develop Apr 17, 2026
12 checks passed
@YoussefKeyrouz YoussefKeyrouz deleted the feature/david/hatch_pixels branch April 17, 2026 22:54
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.

3 participants