Skip to content

Commit

Permalink
Add Speedreader metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
DJAndries committed Feb 28, 2025
1 parent c3f6d66 commit 86b08d7
Show file tree
Hide file tree
Showing 12 changed files with 306 additions and 10 deletions.
2 changes: 2 additions & 0 deletions browser/brave_local_state_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "brave/components/p3a/p3a_service.h"
#include "brave/components/p3a/star_randomness_meta.h"
#include "brave/components/skus/browser/skus_utils.h"
#include "brave/components/speedreader/speedreader_service.h"
#include "brave/components/tor/buildflags/buildflags.h"
#include "brave/components/web_discovery/buildflags/buildflags.h"
#include "build/build_config.h"
Expand Down Expand Up @@ -179,6 +180,7 @@ void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
#if BUILDFLAG(ENABLE_WEB_DISCOVERY_NATIVE)
web_discovery::WebDiscoveryService::RegisterLocalStatePrefs(registry);
#endif
speedreader::SpeedreaderService::RegisterLocalStatePrefs(registry);
}

} // namespace brave
4 changes: 3 additions & 1 deletion browser/speedreader/speedreader_service_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "base/no_destructor.h"
#include "brave/components/speedreader/speedreader_service.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
Expand Down Expand Up @@ -49,7 +50,8 @@ SpeedreaderServiceFactory::BuildServiceInstanceForBrowserContext(
return {};
}
return std::make_unique<SpeedreaderService>(
context, HostContentSettingsMapFactory::GetForProfile(context));
g_browser_process->local_state(), context,
HostContentSettingsMapFactory::GetForProfile(context));
}

bool SpeedreaderServiceFactory::ServiceIsCreatedWithBrowserContext() const {
Expand Down
2 changes: 2 additions & 0 deletions components/p3a/metric_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ inline constexpr auto kCollectedSlowHistograms =
{"Brave.Rewards.TipsSent.2", MetricConfig{.ephemeral = true}},
{"Brave.Search.SearchSuggest", {}},
{"Brave.Shields.ForgetFirstParty", {}},
{"Brave.Speedreader.EnabledSites", {}},
{"Brave.Speedreader.PageViews", MetricConfig{.ephemeral = true}},
{"Brave.Sync.EnabledTypes", {}},
{"Brave.Sync.SyncedObjectsCount.2", {}},
{"Brave.Today.ChannelCount.2", MetricConfig{.ephemeral = true}},
Expand Down
28 changes: 28 additions & 0 deletions components/speedreader/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ static_library("speedreader") {
"speedreader_distilled_page_producer.h",
"speedreader_extended_info_handler.cc",
"speedreader_extended_info_handler.h",
"speedreader_metrics.cc",
"speedreader_metrics.h",
"speedreader_pref_names.h",
"speedreader_rewriter_service.cc",
"speedreader_rewriter_service.h",
Expand All @@ -36,6 +38,7 @@ static_library("speedreader") {
deps = [
"rust/ffi",
"//brave/components/body_sniffer",
"//brave/components/p3a_utils",
"//brave/components/resources",
"//brave/components/resources:static_resources_grit",
"//brave/components/speedreader/common:mojom",
Expand All @@ -55,3 +58,28 @@ static_library("speedreader") {
"//url",
]
}

source_set("unit_tests") {
testonly = true

sources = [
"speedreader_metrics_unittest.cc",
"speedreader_rewriter_unittest.cc",
"speedreader_util_unittest.cc",
]

deps = [
":speedreader",
"//base",
"//base/test:test_support",
"//brave/components/constants",
"//brave/components/p3a_utils",
"//brave/components/time_period_storage",
"//components/content_settings/core/browser",
"//components/content_settings/core/common",
"//components/prefs:test_support",
"//components/sync_preferences:test_support",
"//testing/gtest",
"//url",
]
}
92 changes: 92 additions & 0 deletions components/speedreader/speedreader_metrics.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "brave/components/speedreader/speedreader_metrics.h"

#include "base/metrics/histogram_macros.h"
#include "brave/components/p3a_utils/bucket.h"
#include "brave/components/speedreader/speedreader_pref_names.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"

namespace speedreader {

namespace {

constexpr int kPageViewsBuckets[] = {5, 10, 20, 30};

constexpr base::TimeDelta kUpdateInterval = base::Days(1);

enum class EnabledSitesMetricValue {
kNone = 0, // No sites enabled
kOne = 1, // 1 site enabled
kMultiple = 2, // 2+ sites enabled
kAll = 3, // All sites enabled
kMaxValue = kAll
};

} // namespace

SpeedreaderMetrics::SpeedreaderMetrics(
PrefService* local_state,
HostContentSettingsMap* host_content_settings_map,
bool is_enabled_for_all_sites)
: page_views_storage_(local_state, kSpeedreaderPageViewsStoragePref),
host_content_settings_map_(host_content_settings_map),
local_state_(local_state) {
ReportPageViews();
UpdateEnabledSitesMetric(is_enabled_for_all_sites);
}

SpeedreaderMetrics::~SpeedreaderMetrics() = default;

// static
void SpeedreaderMetrics::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterListPref(kSpeedreaderPageViewsStoragePref);
}

void SpeedreaderMetrics::RecordPageView() {
page_views_storage_.AddDelta(1);
ReportPageViews();
}

void SpeedreaderMetrics::UpdateEnabledSitesMetric(
bool is_enabled_for_all_sites) {
EnabledSitesMetricValue value = EnabledSitesMetricValue::kNone;

if (is_enabled_for_all_sites) {
value = EnabledSitesMetricValue::kAll;
} else if (host_content_settings_map_) {
auto settings = host_content_settings_map_->GetSettingsForOneType(
ContentSettingsType::BRAVE_SPEEDREADER);
size_t enabled_sites_count =
std::ranges::count_if(settings, [](const auto& setting) {
return setting.GetContentSetting() == CONTENT_SETTING_ALLOW;
});
if (enabled_sites_count == 1) {
value = EnabledSitesMetricValue::kOne;
} else if (enabled_sites_count > 1) {
value = EnabledSitesMetricValue::kMultiple;
}
}

UMA_HISTOGRAM_ENUMERATION(kSpeedreaderEnabledSitesHistogramName, value);
}

void SpeedreaderMetrics::ReportPageViews() {
int page_views = page_views_storage_.GetMonthlySum();
if (page_views > 0) {
p3a_utils::RecordToHistogramBucket(kSpeedreaderPageViewsHistogramName,
kPageViewsBuckets, page_views);
}

update_timer_.Start(FROM_HERE, base::Time::Now() + kUpdateInterval, this,
&SpeedreaderMetrics::ReportPageViews);
}

} // namespace speedreader
51 changes: 51 additions & 0 deletions components/speedreader/speedreader_metrics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_METRICS_H_
#define BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_METRICS_H_

#include "base/timer/wall_clock_timer.h"
#include "brave/components/time_period_storage/monthly_storage.h"

class PrefRegistrySimple;
class PrefService;
class HostContentSettingsMap;

namespace speedreader {

inline constexpr char kSpeedreaderPageViewsHistogramName[] =
"Brave.Speedreader.PageViews";
inline constexpr char kSpeedreaderEnabledSitesHistogramName[] =
"Brave.Speedreader.EnabledSites";

class SpeedreaderMetrics {
public:
SpeedreaderMetrics(PrefService* local_state,
HostContentSettingsMap* host_content_settings_map,
bool is_enabled_for_all_sites);
~SpeedreaderMetrics();

SpeedreaderMetrics(const SpeedreaderMetrics&) = delete;
SpeedreaderMetrics& operator=(const SpeedreaderMetrics&) = delete;

static void RegisterPrefs(PrefRegistrySimple* registry);

void RecordPageView();

void UpdateEnabledSitesMetric(bool is_enabled_for_all_sites);

private:
void ReportPageViews();

MonthlyStorage page_views_storage_;
raw_ptr<HostContentSettingsMap> host_content_settings_map_;
raw_ptr<PrefService> local_state_;

base::WallClockTimer update_timer_;
};

} // namespace speedreader

#endif // BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_METRICS_H_
100 changes: 100 additions & 0 deletions components/speedreader/speedreader_metrics_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */

#include "brave/components/speedreader/speedreader_metrics.h"

#include <memory>

#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/prefs/testing_pref_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace speedreader {

class SpeedreaderMetricsTest : public testing::Test {
public:
SpeedreaderMetricsTest()
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}

void SetUp() override {
SpeedreaderMetrics::RegisterPrefs(local_state_.registry());
HostContentSettingsMap::RegisterProfilePrefs(profile_prefs_.registry());

host_content_settings_map_ =
new HostContentSettingsMap(&profile_prefs_, /*is_off_the_record*/ false,
/*store_last_modified*/ false,
/*restore_session*/ false,
/*should_record_metrics*/ false);

metrics_ = std::make_unique<SpeedreaderMetrics>(
&local_state_, host_content_settings_map_.get(), false);
}

void TearDown() override { host_content_settings_map_->ShutdownOnUIThread(); }

protected:
base::test::TaskEnvironment task_environment_;
TestingPrefServiceSimple local_state_;
sync_preferences::TestingPrefServiceSyncable profile_prefs_;
scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
std::unique_ptr<SpeedreaderMetrics> metrics_;
base::HistogramTester histogram_tester_;
};

TEST_F(SpeedreaderMetricsTest, RecordPageViews) {
for (int i = 0; i < 5; i++) {
metrics_->RecordPageView();
}

histogram_tester_.ExpectUniqueSample(kSpeedreaderPageViewsHistogramName, 0,
5);

for (int i = 0; i < 5; i++) {
metrics_->RecordPageView();
}

histogram_tester_.ExpectBucketCount(kSpeedreaderPageViewsHistogramName, 1, 5);
histogram_tester_.ExpectTotalCount(kSpeedreaderPageViewsHistogramName, 10);

task_environment_.FastForwardBy(base::Days(45));

histogram_tester_.ExpectBucketCount(kSpeedreaderPageViewsHistogramName, 1,
34);
histogram_tester_.ExpectTotalCount(kSpeedreaderPageViewsHistogramName, 39);
}

TEST_F(SpeedreaderMetricsTest, EnabledSitesMetric) {
histogram_tester_.ExpectUniqueSample(kSpeedreaderEnabledSitesHistogramName, 0,
1);

ContentSettingsPattern pattern =
ContentSettingsPattern::FromString("*://example.com/*");
host_content_settings_map_->SetContentSettingCustomScope(
pattern, ContentSettingsPattern::Wildcard(),
ContentSettingsType::BRAVE_SPEEDREADER, CONTENT_SETTING_ALLOW);

metrics_->UpdateEnabledSitesMetric(false);
histogram_tester_.ExpectBucketCount(kSpeedreaderEnabledSitesHistogramName, 1,
1);

pattern = ContentSettingsPattern::FromString("*://brave.com/*");
host_content_settings_map_->SetContentSettingCustomScope(
pattern, ContentSettingsPattern::Wildcard(),
ContentSettingsType::BRAVE_SPEEDREADER, CONTENT_SETTING_ALLOW);

metrics_->UpdateEnabledSitesMetric(false);
histogram_tester_.ExpectBucketCount(kSpeedreaderEnabledSitesHistogramName, 2,
1);

metrics_->UpdateEnabledSitesMetric(true);
histogram_tester_.ExpectBucketCount(kSpeedreaderEnabledSitesHistogramName, 3,
1);
}

} // namespace speedreader
3 changes: 3 additions & 0 deletions components/speedreader/speedreader_pref_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ inline constexpr char kSpeedreaderPrefTtsVoice[] =
inline constexpr char kSpeedreaderPrefTtsSpeed[] =
"brave.speedreader.tts_speed";

inline constexpr char kSpeedreaderPageViewsStoragePref[] =
"brave.speedreader.page_views";

} // namespace speedreader

#endif // BRAVE_COMPONENTS_SPEEDREADER_SPEEDREADER_PREF_NAMES_H_
17 changes: 15 additions & 2 deletions components/speedreader/speedreader_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ bool IsSpeedreaderEnabled() {

} // namespace features

SpeedreaderService::SpeedreaderService(content::BrowserContext* browser_context,
SpeedreaderService::SpeedreaderService(PrefService* local_state,
content::BrowserContext* browser_context,
HostContentSettingsMap* content_rules)
: browser_context_(browser_context),
content_rules_(content_rules),
prefs_(user_prefs::UserPrefs::Get(browser_context_)) {
prefs_(user_prefs::UserPrefs::Get(browser_context_)),
metrics_(local_state, content_rules_, IsEnabledForAllSites()) {
DCHECK(features::IsSpeedreaderEnabled());
}

Expand Down Expand Up @@ -81,6 +83,11 @@ void SpeedreaderService::RegisterProfilePrefs(PrefRegistrySimple* registry) {
static_cast<int>(PlaybackSpeed::k100));
}

// static
void SpeedreaderService::RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
SpeedreaderMetrics::RegisterPrefs(registry);
}

void SpeedreaderService::AddObserver(Observer* observer) {
observers_.AddObserver(observer);
}
Expand Down Expand Up @@ -164,6 +171,8 @@ void SpeedreaderService::EnableForAllSites(bool enabled) {
for (auto& o : observers_) {
o.OnAllSitesEnableSettingChanged(enabled);
}

metrics_.UpdateEnabledSitesMetric(enabled);
}

void SpeedreaderService::EnableForSite(const GURL& url, bool enabled) {
Expand All @@ -188,6 +197,8 @@ void SpeedreaderService::EnableForSite(const GURL& url, bool enabled) {
content_rules_->SetContentSettingCustomScope(
pattern, ContentSettingsPattern::Wildcard(),
ContentSettingsType::BRAVE_SPEEDREADER, setting);

metrics_.UpdateEnabledSitesMetric(IsEnabledForAllSites());
}

void SpeedreaderService::EnableForSite(content::WebContents* contents,
Expand All @@ -198,6 +209,8 @@ void SpeedreaderService::EnableForSite(content::WebContents* contents,
o.OnSiteEnableSettingChanged(contents, enabled);
}
}

metrics_.UpdateEnabledSitesMetric(IsEnabledForAllSites());
}

void SpeedreaderService::SetAppearanceSettings(
Expand Down
Loading

0 comments on commit 86b08d7

Please sign in to comment.