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 2427010
Show file tree
Hide file tree
Showing 12 changed files with 308 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",
]
}
94 changes: 94 additions & 0 deletions components/speedreader/speedreader_metrics.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* 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;

if (is_enabled_for_all_sites) {
value = EnabledSitesMetricValue::kAll;
} else {
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 == 0) {
value = EnabledSitesMetricValue::kNone;
} else if (enabled_sites_count == 1) {
value = EnabledSitesMetricValue::kOne;
} else {
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_
Loading

0 comments on commit 2427010

Please sign in to comment.