Skip to content

Commit

Permalink
[fre][ntp][m102] Add opt in status metric for FRE
Browse files Browse the repository at this point in the history
We want to log implicit opt ins (8 impressions/1 day), explicit opt ins (clicking "Got It"), and explicit opt outs (clicking "Don't Show"). Each time we log this we also log how many impressions a user was at when they were opted in/out.

(cherry picked from commit 681f7f1)

Change-Id: I07445cd3e236f4e70142a281f2ba9b03919b7e85
Bug: 1303938
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3584424
Reviewed-by: Mohamad Ahmadi <mahmadi@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Justin DeWitt <dewittj@chromium.org>
Commit-Queue: Paul Adedeji <pauladedeji@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#993430}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3608124
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Auto-Submit: Paul Adedeji <pauladedeji@google.com>
Cr-Commit-Position: refs/branch-heads/5005@{#214}
Cr-Branched-From: 5b4d945-refs/heads/main@{#992738}
  • Loading branch information
Paul Adedeji authored and Chromium LUCI CQ committed Apr 28, 2022
1 parent 90cb186 commit 89d8d69
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 6 deletions.
7 changes: 7 additions & 0 deletions chrome/browser/resources/new_tab_page/modules/modules.ts
Expand Up @@ -12,6 +12,7 @@ import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';

import {loadTimeData} from '../i18n_setup.js';
import {OptInStatus} from '../new_tab_page.mojom-webui.js';
import {NewTabPageProxy} from '../new_tab_page_proxy.js';

import {Module, ModuleHeight} from './module_descriptor.js';
Expand Down Expand Up @@ -458,6 +459,9 @@ export class ModulesElement extends PolymerElement {

private onModulesFreOptIn_() {
this.hideFre_();

NewTabPageProxy.getInstance().handler.logModulesFreOptInStatus(
OptInStatus.kExplicitOptIn);
}

private onModulesFreOptOut_() {
Expand All @@ -476,6 +480,9 @@ export class ModulesElement extends PolymerElement {

// Notify the user
this.$.removeModuleFreToast.show();

NewTabPageProxy.getInstance().handler.logModulesFreOptInStatus(
OptInStatus.kOptOut);
}

private onUndoRemoveModuleFreButtonClick_() {
Expand Down
9 changes: 9 additions & 0 deletions chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom
Expand Up @@ -204,6 +204,13 @@ enum CustomizeDialogAction {
kShortcutsVisibilityToggleClicked,
};

// Opt in status. Used for metrics logging only.
enum OptInStatus {
kExplicitOptIn,
kImplicitOptIn,
kOptOut,
};

// Used by the WebUI page to bootstrap bidirectional communication.
interface PageHandlerFactory {
// The WebUI page's |BrowserProxy| singleton calls this method when the page
Expand Down Expand Up @@ -265,6 +272,8 @@ interface PageHandler {
SetModulesFreVisible(bool visible);
// Triggers a call to |SetModulesFreVisibility|.
UpdateModulesFreVisibility();
// Log user's FRE |optInStatus|.
LogModulesFreOptInStatus(OptInStatus opt_in_status);

// ======= METRICS =======
// Logs that the One Google Bar was added to the DOM / loaded in an iframe at
Expand Down
34 changes: 31 additions & 3 deletions chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc
Expand Up @@ -70,6 +70,7 @@
namespace {

const int64_t kMaxDownloadBytes = 1024 * 1024;
const int64_t kMaxModuleFreImpressions = 8;

new_tab_page::mojom::ThemePtr MakeTheme(
const ui::ColorProvider& color_provider,
Expand Down Expand Up @@ -690,16 +691,43 @@ void NewTabPageHandler::UpdateModulesFreVisibility() {
auto ntp_modules_fre_visible =
profile_->GetPrefs()->GetBoolean(prefs::kNtpModulesFreVisible);

// Hide Modular NTP Desktop v1 First Run Experience after 8 impressions or 1
// day, whichever comes first.
if (ntp_modules_shown_count >= 8 ||
// Hide Modular NTP Desktop v1 First Run Experience after
// |kMaxModuleFreImpressions| impressions or 1 day, whichever comes first.
if (ntp_modules_shown_count >= kMaxModuleFreImpressions ||
(!ntp_modules_first_shown_time.is_null() &&
(base::Time::Now() - ntp_modules_first_shown_time) > base::Days(1))) {
ntp_modules_fre_visible = false;
SetModulesFreVisible(ntp_modules_fre_visible);
} else {
page_->SetModulesFreVisibility(ntp_modules_fre_visible);
}

if (ntp_modules_shown_count == kMaxModuleFreImpressions ||
(!ntp_modules_first_shown_time.is_null() &&
(base::Time::Now() - ntp_modules_first_shown_time) == base::Days(1))) {
LogModulesFreOptInStatus(new_tab_page::mojom::OptInStatus::kImplicitOptIn);
}
}

void NewTabPageHandler::LogModulesFreOptInStatus(
new_tab_page::mojom::OptInStatus opt_in_status) {
const auto ntp_modules_shown_count =
profile_->GetPrefs()->GetInteger(prefs::kNtpModulesShownCount);
switch (opt_in_status) {
case new_tab_page::mojom::OptInStatus::kExplicitOptIn:
base::UmaHistogramExactLinear("NewTabPage.Modules.FreExplicitOptIn",
ntp_modules_shown_count,
kMaxModuleFreImpressions);
break;
case new_tab_page::mojom::OptInStatus::kImplicitOptIn:
base::UmaHistogramBoolean("NewTabPage.Modules.FreImplicitOptIn", true);
break;

case new_tab_page::mojom::OptInStatus::kOptOut:
base::UmaHistogramExactLinear("NewTabPage.Modules.FreOptOut",
ntp_modules_shown_count,
kMaxModuleFreImpressions);
}
}

void NewTabPageHandler::OnPromoDataUpdated() {
Expand Down
2 changes: 2 additions & 0 deletions chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h
Expand Up @@ -109,6 +109,8 @@ class NewTabPageHandler : public new_tab_page::mojom::PageHandler,
void IncrementModulesShownCount() override;
void SetModulesFreVisible(bool visible) override;
void UpdateModulesFreVisibility() override;
void LogModulesFreOptInStatus(
new_tab_page::mojom::OptInStatus opt_in_status) override;
void OnAppRendered(double time) override;
void OnOneGoogleBarRendered(double time) override;
void OnPromoRendered(double time,
Expand Down
Expand Up @@ -448,6 +448,22 @@ TEST_F(NewTabPageHandlerTest, Histograms) {
std::string(NewTabPageHandler::kModuleRestoredHistogram) +
".kaleidoscope",
1);

// NewTabPage.Modules.FreOptIn and NewTabPage.Modules.FreOptOut log how many
// times the FRE is shown, so we increment the shown count to make sure the
// histogram is logging correctly
handler_->IncrementModulesShownCount();
handler_->LogModulesFreOptInStatus(
new_tab_page::mojom::OptInStatus::kExplicitOptIn);
histogram_tester_.ExpectTotalCount("NewTabPage.Modules.FreExplicitOptIn", 1);
ASSERT_EQ(1, histogram_tester_.GetBucketCount(
"NewTabPage.Modules.FreExplicitOptIn", 1));

handler_->IncrementModulesShownCount();
handler_->LogModulesFreOptInStatus(new_tab_page::mojom::OptInStatus::kOptOut);
histogram_tester_.ExpectTotalCount("NewTabPage.Modules.FreOptOut", 1);
ASSERT_EQ(
1, histogram_tester_.GetBucketCount("NewTabPage.Modules.FreOptOut", 2));
}

TEST_F(NewTabPageHandlerTest, GetAnimatedDoodle) {
Expand Down Expand Up @@ -726,6 +742,9 @@ TEST_F(NewTabPageHandlerTest,

EXPECT_EQ(profile_->GetPrefs()->GetBoolean(prefs::kNtpModulesFreVisible),
false);
histogram_tester_.ExpectTotalCount("NewTabPage.Modules.FreImplicitOptIn", 1);
ASSERT_EQ(1, histogram_tester_.GetBucketCount(
"NewTabPage.Modules.FreImplicitOptIn", true));

mock_page_.FlushForTesting();
}
Expand Down
11 changes: 9 additions & 2 deletions chrome/test/data/webui/new_tab_page/modules/modules_test.ts
Expand Up @@ -179,7 +179,7 @@ suite('NewTabPageModulesModulesTest', () => {
assertTrue(customizeModule.received);
});

test(`fre can be opted out of and restored`, async () => {
test(`fre buttons work`, async () => {
// Arrange.
const fooDescriptor = new ModuleDescriptor('foo', 'Foo', initNullModule);
const barDescriptor = new ModuleDescriptor('bar', 'Bar', initNullModule);
Expand Down Expand Up @@ -221,8 +221,15 @@ suite('NewTabPageModulesModulesTest', () => {
assertFalse(modulesElement.$.removeModuleFreToast.open);
assertDeepEquals(true, handler.getArgs('setModulesFreVisible')[1]);
assertDeepEquals(true, handler.getArgs('setModulesVisible')[1]);
assertEquals(1, metrics.count('NewTabPage.Modules.FreImpression', true));
assertEquals(1, handler.getCallCount('logModulesFreOptInStatus'));
assertEquals(1, metrics.count('NewTabPage.Modules.FreLoaded', true));

// Act.
$$<HTMLElement>(modulesElement, '.action-button')!.click();

// Assert.
assertDeepEquals(false, handler.getArgs('setModulesFreVisible')[2]);
assertEquals(2, handler.getCallCount('logModulesFreOptInStatus'));
});
});

Expand Down
41 changes: 40 additions & 1 deletion tools/metrics/histograms/metadata/new_tab_page/histograms.xml
Expand Up @@ -1079,6 +1079,32 @@ chromium-metrics-reviews@google.com.
</token>
</histogram>

<histogram name="NewTabPage.Modules.FreExplicitOptIn" units="count"
expires_after="2022-09-15">
<owner>danpeng@google.com</owner>
<owner>pauladedeji@chromium.org</owner>
<owner>chrome-desktop-ntp@google.com</owner>
<summary>
Logs how many time a user saw the FRE when they opt in. Only logged on the
1P NTP. Note that even if the user has Google as their default search
engine, Incognito and Guest mode NTPs are not considered 1P and don't log
this histogram.
</summary>
</histogram>

<histogram name="NewTabPage.Modules.FreImplicitOptIn" enum="BooleanEnabled"
expires_after="2022-09-15">
<owner>danpeng@google.com</owner>
<owner>pauladedeji@chromium.org</owner>
<owner>chrome-desktop-ntp@google.com</owner>
<summary>
Logs when user is opted in to FRE without taking action. Only logged on the
1P NTP. Note that even if the user has Google as their default search
engine, Incognito and Guest mode NTPs are not considered 1P and don't log
this histogram.
</summary>
</histogram>

<histogram base="true" name="NewTabPage.Modules.FreImpression"
enum="BooleanEnabled" expires_after="2022-09-15">
<owner>danpeng@google.com</owner>
Expand All @@ -1093,7 +1119,7 @@ chromium-metrics-reviews@google.com.
</histogram>

<histogram base="true" name="NewTabPage.Modules.FreLoaded"
enum="BooleanEnabled" expires_after="2023-04-11">
enum="BooleanEnabled" expires_after="2022-09-15">
<owner>danpeng@google.com</owner>
<owner>pauladedeji@chromium.org</owner>
<owner>chrome-desktop-ntp@google.com</owner>
Expand All @@ -1105,6 +1131,19 @@ chromium-metrics-reviews@google.com.
</summary>
</histogram>

<histogram name="NewTabPage.Modules.FreOptOut" units="count"
expires_after="2022-09-15">
<owner>danpeng@google.com</owner>
<owner>pauladedeji@chromium.org</owner>
<owner>chrome-desktop-ntp@google.com</owner>
<summary>
Logs how many time a user saw the FRE when they opt out. Only logged on the
1P NTP. Note that even if the user has Google as their default search
engine, Incognito and Guest mode NTPs are not considered 1P and don't log
this histogram.
</summary>
</histogram>

<histogram name="NewTabPage.Modules.Hover" enum="NtpModules"
expires_after="2022-10-04">
<owner>danpeng@google.com</owner>
Expand Down

0 comments on commit 89d8d69

Please sign in to comment.