From 44f393a73d77b3adfe9905ed9c187c916e5d658a Mon Sep 17 00:00:00 2001 From: Lina Butler Date: Wed, 20 Dec 2023 14:47:44 -0800 Subject: [PATCH] Bug 1871156 - Report impressions and clicks for Firefox Suggestions in the `events` ping. Fenix currently reports AMP and Wikipedia impressions and clicks in the `fx-suggest` ping, which intentionally omits the `client_id`. This complicates experiment analysis, because our tooling relies on the `client_id`. This commit adds separate events for impressions and clicks on sponsored and non-sponsored suggestions to the `events` ping. * The new `awesomebar.{non_}sponsored_suggestion_clicked` events are collected the same way as the existing `fx-suggest` ping, and in line with the other `awesomebar.*_suggestion_clicked` events. * The new `awesomebar.{non_}sponsored_suggestion_impressed` events are collected for engaged and abandoned search sessions. In constrast, the `fx-suggest` ping is only sent for engaged search sessions. --- app/metrics.yaml | 98 +++++++++++++++++++ .../components/metrics/MetricController.kt | 86 ++++++++++++---- 2 files changed, 167 insertions(+), 17 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 6f9bb81f63..4edb0eb1af 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -9161,6 +9161,104 @@ awesomebar: metadata: tags: - Search + sponsored_suggestion_clicked: + type: event + description: | + A sponsored suggestion in the awesomebar was clicked. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1871156 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/4914#issuecomment-1874271848 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + - lina@mozilla.com + - ttran@mozilla.com + - najiang@mozilla.com + expires: never + extra_keys: + provider: &sponsored_suggestion_provider + description: | + The provider of the sponsored suggestion. Possible values: `amp` (for adMarketplace + suggestions). + type: string + metadata: + tags: + - Search + non_sponsored_suggestion_clicked: + type: event + description: | + A non-sponsored suggestion in the awesomebar was clicked. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1871156 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/4914#issuecomment-1874271848 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + - lina@mozilla.com + - ttran@mozilla.com + - najiang@mozilla.com + expires: never + extra_keys: + provider: &non_sponsored_suggestion_provider + description: | + The provider of the non-sponsored suggestion. Possible values: `wikipedia`. + type: string + metadata: + tags: + - Search + sponsored_suggestion_impressed: + type: event + description: | + A sponsored suggestion was visible when the user finished interacting with the awesomebar. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1871156 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/4914#issuecomment-1874271848 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + - lina@mozilla.com + - ttran@mozilla.com + - najiang@mozilla.com + expires: never + extra_keys: + provider: *sponsored_suggestion_provider + engagement_abandoned: &awesomebar_engagement_abandoned + description: | + If `true`, the user dismissed the awesomebar without navigating to a destination. If + `false`, the user finished engaging with the awesomebar by navigating to a destination, + like a URL, a search results page, or a suggestion. + type: boolean + metadata: + tags: + - Search + non_sponsored_suggestion_impressed: + type: event + description: | + A non-sponsored suggestion was visible when the user finished interacting with the awesomebar. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1871156 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/4914#issuecomment-1874271848 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + - lina@mozilla.com + - ttran@mozilla.com + - najiang@mozilla.com + expires: never + extra_keys: + provider: *non_sponsored_suggestion_provider + engagement_abandoned: *awesomebar_engagement_abandoned + metadata: + tags: + - Search android_autofill: supported: type: boolean diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt index 37bbc92813..453ff4750a 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt @@ -283,12 +283,33 @@ internal class ReleaseMetricController( Component.FEATURE_FXSUGGEST to FxSuggestFacts.Items.AMP_SUGGESTION_CLICKED, Component.FEATURE_FXSUGGEST to FxSuggestFacts.Items.WIKIPEDIA_SUGGESTION_CLICKED, -> { + val clickInfo = metadata?.get(FxSuggestFacts.MetadataKeys.INTERACTION_INFO) + + // Record an event for this click in the `events` ping. These events include the `client_id`. + when (clickInfo) { + is FxSuggestInteractionInfo.Amp -> { + Awesomebar.sponsoredSuggestionClicked.record( + Awesomebar.SponsoredSuggestionClickedExtra( + provider = "amp", + ), + ) + } + is FxSuggestInteractionInfo.Wikipedia -> { + Awesomebar.nonSponsoredSuggestionClicked.record( + Awesomebar.NonSponsoredSuggestionClickedExtra( + provider = "wikipedia", + ), + ) + } + } + + // Submit a separate `fx-suggest` ping for this click. These pings do not include the `client_id`. FxSuggest.pingType.set("fxsuggest-click") FxSuggest.isClicked.set(true) (metadata?.get(FxSuggestFacts.MetadataKeys.POSITION) as? Long)?.let { FxSuggest.position.set(it) } - when (val clickInfo = metadata?.get(FxSuggestFacts.MetadataKeys.INTERACTION_INFO)) { + when (clickInfo) { is FxSuggestInteractionInfo.Amp -> { FxSuggest.blockId.set(clickInfo.blockId) FxSuggest.advertiser.set(clickInfo.advertiser) @@ -307,27 +328,58 @@ internal class ReleaseMetricController( Component.FEATURE_FXSUGGEST to FxSuggestFacts.Items.AMP_SUGGESTION_IMPRESSED, Component.FEATURE_FXSUGGEST to FxSuggestFacts.Items.WIKIPEDIA_SUGGESTION_IMPRESSED, -> { - FxSuggest.pingType.set("fxsuggest-impression") - (metadata?.get(FxSuggestFacts.MetadataKeys.IS_CLICKED) as? Boolean)?.let { - FxSuggest.isClicked.set(it) - } - (metadata?.get(FxSuggestFacts.MetadataKeys.POSITION) as? Long)?.let { - FxSuggest.position.set(it) - } - when (val impressionInfo = metadata?.get(FxSuggestFacts.MetadataKeys.INTERACTION_INFO)) { + val impressionInfo = metadata?.get(FxSuggestFacts.MetadataKeys.INTERACTION_INFO) + val engagementAbandoned = metadata?.get(FxSuggestFacts.MetadataKeys.ENGAGEMENT_ABANDONED) as? Boolean + ?: false + + // Record an event for this impression in the `events` ping. These events include the `client_id`, and + // we record them for engaged and abandoned search sessions. + when (impressionInfo) { is FxSuggestInteractionInfo.Amp -> { - FxSuggest.blockId.set(impressionInfo.blockId) - FxSuggest.advertiser.set(impressionInfo.advertiser) - FxSuggest.reportingUrl.set(impressionInfo.reportingUrl) - FxSuggest.iabCategory.set(impressionInfo.iabCategory) - FxSuggest.contextId.set(UUID.fromString(impressionInfo.contextId)) + Awesomebar.sponsoredSuggestionImpressed.record( + Awesomebar.SponsoredSuggestionImpressedExtra( + provider = "amp", + engagementAbandoned = engagementAbandoned, + ), + ) } is FxSuggestInteractionInfo.Wikipedia -> { - FxSuggest.advertiser.set("wikipedia") - FxSuggest.contextId.set(UUID.fromString(impressionInfo.contextId)) + Awesomebar.nonSponsoredSuggestionImpressed.record( + Awesomebar.NonSponsoredSuggestionImpressedExtra( + provider = "wikipedia", + engagementAbandoned = engagementAbandoned, + ), + ) } } - Pings.fxSuggest.submit() + + // Submit a separate `fx-suggest` ping for this impression. These pings do not include the `client_id`, + // and we submit them for engaged search sessions only. + if (!engagementAbandoned) { + FxSuggest.pingType.set("fxsuggest-impression") + (metadata?.get(FxSuggestFacts.MetadataKeys.IS_CLICKED) as? Boolean)?.let { + FxSuggest.isClicked.set(it) + } + (metadata?.get(FxSuggestFacts.MetadataKeys.POSITION) as? Long)?.let { + FxSuggest.position.set(it) + } + when (impressionInfo) { + is FxSuggestInteractionInfo.Amp -> { + FxSuggest.blockId.set(impressionInfo.blockId) + FxSuggest.advertiser.set(impressionInfo.advertiser) + FxSuggest.reportingUrl.set(impressionInfo.reportingUrl) + FxSuggest.iabCategory.set(impressionInfo.iabCategory) + FxSuggest.contextId.set(UUID.fromString(impressionInfo.contextId)) + } + is FxSuggestInteractionInfo.Wikipedia -> { + FxSuggest.advertiser.set("wikipedia") + FxSuggest.contextId.set(UUID.fromString(impressionInfo.contextId)) + } + } + Pings.fxSuggest.submit() + } + + Unit } Component.FEATURE_PWA to ProgressiveWebAppFacts.Items.HOMESCREEN_ICON_TAP -> {