-
Notifications
You must be signed in to change notification settings - Fork 884
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
325 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* Copyright (c) 2024 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/brave_vpn/browser/brave_vpn_metrics.h" | ||
|
||
#include "base/metrics/histogram_macros.h" | ||
#include "brave/components/brave_vpn/common/brave_vpn_constants.h" | ||
#include "brave/components/brave_vpn/common/pref_names.h" | ||
#include "brave/components/constants/pref_names.h" | ||
#include "brave/components/p3a_utils/bucket.h" | ||
#include "brave/components/p3a_utils/feature_usage.h" | ||
#include "components/prefs/pref_change_registrar.h" | ||
#include "components/prefs/pref_service.h" | ||
|
||
namespace brave_vpn { | ||
|
||
namespace { | ||
|
||
constexpr int kWidgetUsageBuckets[] = {1, 10, 20}; | ||
|
||
} // namespace | ||
|
||
BraveVpnMetrics::BraveVpnMetrics(PrefService* local_state, | ||
PrefService* profile_prefs) | ||
: local_state_(local_state), | ||
profile_prefs_(profile_prefs), | ||
widget_usage_storage_(local_state_, | ||
prefs::kBraveVPNWidgetUsageWeeklyStorage) { | ||
pref_change_registrar_.Init(profile_prefs); | ||
pref_change_registrar_.Add( | ||
kNewTabPageShowBraveVPN, | ||
base::BindRepeating(&BraveVpnMetrics::HandleShowWidgetChange, | ||
base::Unretained(this))); | ||
RecordAllMetrics(false); | ||
} | ||
|
||
BraveVpnMetrics::~BraveVpnMetrics() = default; | ||
|
||
void BraveVpnMetrics::RecordAllMetrics(bool new_usage) { | ||
if (new_usage) { | ||
p3a_utils::RecordFeatureUsage(local_state_, prefs::kBraveVPNFirstUseTime, | ||
prefs::kBraveVPNLastUseTime); | ||
} | ||
p3a_utils::RecordFeatureNewUserReturning( | ||
local_state_, prefs::kBraveVPNFirstUseTime, prefs::kBraveVPNLastUseTime, | ||
prefs::kBraveVPNUsedSecondDay, kNewUserReturningHistogramName); | ||
p3a_utils::RecordFeatureDaysInMonthUsed( | ||
local_state_, new_usage, prefs::kBraveVPNLastUseTime, | ||
prefs::kBraveVPNDaysInMonthUsed, kDaysInMonthUsedHistogramName); | ||
p3a_utils::RecordFeatureLastUsageTimeMetric( | ||
local_state_, prefs::kBraveVPNLastUseTime, kLastUsageTimeHistogramName); | ||
RecordWidgetUsage(false); | ||
report_timer_.Start(FROM_HERE, | ||
base::Time::Now() + base::Hours(kP3AIntervalHours), | ||
base::BindOnce(&BraveVpnMetrics::RecordAllMetrics, | ||
base::Unretained(this), false)); | ||
} | ||
|
||
#if BUILDFLAG(IS_ANDROID) | ||
void BraveVpnMetrics::RecordAndroidBackgroundP3A(int64_t session_start_time_ms, | ||
int64_t session_end_time_ms) { | ||
if (session_start_time_ms < 0 || session_end_time_ms < 0) { | ||
RecordAllMetrics(false); | ||
return; | ||
} | ||
base::Time session_start_time = | ||
base::Time::FromMillisecondsSinceUnixEpoch( | ||
static_cast<double>(session_start_time_ms)) | ||
.LocalMidnight(); | ||
base::Time session_end_time = base::Time::FromMillisecondsSinceUnixEpoch( | ||
static_cast<double>(session_end_time_ms)) | ||
.LocalMidnight(); | ||
for (base::Time day = session_start_time; day <= session_end_time; | ||
day += base::Days(1)) { | ||
bool is_last_day = day == session_end_time; | ||
// Call functions for each day in the last session to ensure | ||
// p3a_util functions produce the correct result | ||
p3a_utils::RecordFeatureUsage(local_state_, prefs::kBraveVPNFirstUseTime, | ||
prefs::kBraveVPNLastUseTime, day); | ||
p3a_utils::RecordFeatureNewUserReturning( | ||
local_state_, prefs::kBraveVPNFirstUseTime, prefs::kBraveVPNLastUseTime, | ||
prefs::kBraveVPNUsedSecondDay, kNewUserReturningHistogramName, | ||
is_last_day); | ||
p3a_utils::RecordFeatureDaysInMonthUsed( | ||
local_state_, day, prefs::kBraveVPNLastUseTime, | ||
prefs::kBraveVPNDaysInMonthUsed, kDaysInMonthUsedHistogramName, | ||
is_last_day); | ||
} | ||
p3a_utils::RecordFeatureLastUsageTimeMetric( | ||
local_state_, prefs::kBraveVPNLastUseTime, kLastUsageTimeHistogramName); | ||
} | ||
#endif | ||
|
||
void BraveVpnMetrics::RecordWidgetUsage(bool new_usage) { | ||
if (new_usage) { | ||
widget_usage_storage_.AddDelta(1u); | ||
} | ||
auto total = widget_usage_storage_.GetWeeklySum(); | ||
if (total == 0) { | ||
return; | ||
} | ||
p3a_utils::RecordToHistogramBucket(kWidgetUsageHistogramName, | ||
kWidgetUsageBuckets, total); | ||
} | ||
|
||
void BraveVpnMetrics::HandleShowWidgetChange() { | ||
if (profile_prefs_->GetBoolean(kNewTabPageShowBraveVPN)) { | ||
return; | ||
} | ||
UMA_HISTOGRAM_BOOLEAN(kHideWidgetHistogramName, true); | ||
} | ||
|
||
} // namespace brave_vpn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* Copyright (c) 2024 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_BRAVE_VPN_BROWSER_BRAVE_VPN_METRICS_H_ | ||
#define BRAVE_COMPONENTS_BRAVE_VPN_BROWSER_BRAVE_VPN_METRICS_H_ | ||
|
||
#include "base/timer/wall_clock_timer.h" | ||
#include "brave/components/time_period_storage/weekly_storage.h" | ||
#include "components/prefs/pref_change_registrar.h" | ||
|
||
class PrefService; | ||
|
||
namespace brave_vpn { | ||
|
||
inline constexpr char kNewUserReturningHistogramName[] = | ||
"Brave.VPN.NewUserReturning"; | ||
inline constexpr char kDaysInMonthUsedHistogramName[] = | ||
"Brave.VPN.DaysInMonthUsed"; | ||
inline constexpr char kLastUsageTimeHistogramName[] = "Brave.VPN.LastUsageTime"; | ||
inline constexpr char kWidgetUsageHistogramName[] = "Brave.VPN.WidgetUsage"; | ||
inline constexpr char kHideWidgetHistogramName[] = "Brave.VPN.HideWidget"; | ||
|
||
class BraveVpnMetrics { | ||
public: | ||
BraveVpnMetrics(PrefService* local_prefs, PrefService* profile_prefs); | ||
~BraveVpnMetrics(); | ||
|
||
BraveVpnMetrics(const BraveVpnMetrics&) = delete; | ||
BraveVpnMetrics& operator=(const BraveVpnMetrics&) = delete; | ||
|
||
// new_usage should be set to true if a new VPN connection was just | ||
// established. | ||
void RecordAllMetrics(bool new_usage); | ||
|
||
#if BUILDFLAG(IS_ANDROID) | ||
void RecordAndroidBackgroundP3A(int64_t session_start_time_ms, | ||
int64_t session_end_time_ms); | ||
#endif | ||
|
||
void RecordWidgetUsage(bool new_usage); | ||
|
||
private: | ||
void HandleShowWidgetChange(); | ||
|
||
raw_ptr<PrefService> local_state_; | ||
raw_ptr<PrefService> profile_prefs_; | ||
PrefChangeRegistrar pref_change_registrar_; | ||
|
||
WeeklyStorage widget_usage_storage_; | ||
base::WallClockTimer report_timer_; | ||
}; | ||
|
||
} // namespace brave_vpn | ||
|
||
#endif // BRAVE_COMPONENTS_BRAVE_VPN_BROWSER_BRAVE_VPN_METRICS_H_ |
115 changes: 115 additions & 0 deletions
115
components/brave_vpn/browser/brave_vpn_metrics_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* Copyright (c) 2024 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/brave_vpn/browser/brave_vpn_metrics.h" | ||
|
||
#include <memory> | ||
|
||
#include "base/test/metrics/histogram_tester.h" | ||
#include "brave/components/brave_vpn/common/brave_vpn_utils.h" | ||
#include "brave/components/constants/pref_names.h" | ||
#include "components/prefs/testing_pref_service.h" | ||
#include "components/sync_preferences/testing_pref_service_syncable.h" | ||
#include "content/public/test/browser_task_environment.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace brave_vpn { | ||
|
||
class BraveVpnMetricsTest : public testing::Test { | ||
public: | ||
BraveVpnMetricsTest() | ||
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} | ||
|
||
void SetUp() override { | ||
base::Time future_mock_time; | ||
if (base::Time::FromString("2023-01-04", &future_mock_time)) { | ||
task_environment_.AdvanceClock(future_mock_time - base::Time::Now()); | ||
} | ||
profile_prefs_.registry()->RegisterBooleanPref(kNewTabPageShowBraveVPN, | ||
true); | ||
brave_vpn::RegisterLocalStatePrefs(local_state_.registry()); | ||
metrics_ = | ||
std::make_unique<BraveVpnMetrics>(&local_state_, &profile_prefs_); | ||
} | ||
|
||
protected: | ||
content::BrowserTaskEnvironment task_environment_; | ||
TestingPrefServiceSimple local_state_; | ||
sync_preferences::TestingPrefServiceSyncable profile_prefs_; | ||
std::unique_ptr<BraveVpnMetrics> metrics_; | ||
base::HistogramTester histogram_tester_; | ||
}; | ||
|
||
TEST_F(BraveVpnMetricsTest, NewUserReturningMetric) { | ||
metrics_->RecordAllMetrics(false); | ||
histogram_tester_.ExpectBucketCount(kNewUserReturningHistogramName, 0, 2); | ||
|
||
task_environment_.FastForwardBy(base::Days(1)); | ||
metrics_->RecordAllMetrics(true); | ||
histogram_tester_.ExpectBucketCount(kNewUserReturningHistogramName, 2, 1); | ||
|
||
task_environment_.FastForwardBy(base::Days(1)); | ||
metrics_->RecordAllMetrics(true); | ||
histogram_tester_.ExpectBucketCount(kNewUserReturningHistogramName, 3, 1); | ||
|
||
task_environment_.FastForwardBy(base::Days(6)); | ||
histogram_tester_.ExpectBucketCount(kNewUserReturningHistogramName, 1, 1); | ||
} | ||
|
||
TEST_F(BraveVpnMetricsTest, DaysInMonthUsedMetric) { | ||
metrics_->RecordAllMetrics(false); | ||
histogram_tester_.ExpectTotalCount(kDaysInMonthUsedHistogramName, 0); | ||
|
||
metrics_->RecordAllMetrics(true); | ||
histogram_tester_.ExpectBucketCount(kDaysInMonthUsedHistogramName, 1, 1); | ||
|
||
task_environment_.FastForwardBy(base::Days(1)); | ||
metrics_->RecordAllMetrics(true); | ||
histogram_tester_.ExpectBucketCount(kDaysInMonthUsedHistogramName, 2, 1); | ||
task_environment_.FastForwardBy(base::Days(1)); | ||
histogram_tester_.ExpectBucketCount(kDaysInMonthUsedHistogramName, 2, 2); | ||
|
||
metrics_->RecordAllMetrics(true); | ||
task_environment_.FastForwardBy(base::Days(30)); | ||
histogram_tester_.ExpectBucketCount(kDaysInMonthUsedHistogramName, 0, 1); | ||
} | ||
|
||
TEST_F(BraveVpnMetricsTest, LastUsageTimeMetric) { | ||
histogram_tester_.ExpectTotalCount(kLastUsageTimeHistogramName, 0); | ||
|
||
metrics_->RecordAllMetrics(true); | ||
histogram_tester_.ExpectBucketCount(kLastUsageTimeHistogramName, 1, 1); | ||
|
||
task_environment_.AdvanceClock(base::Days(10)); | ||
metrics_->RecordAllMetrics(true); | ||
histogram_tester_.ExpectBucketCount(kLastUsageTimeHistogramName, 1, 2); | ||
task_environment_.AdvanceClock(base::Days(10)); | ||
metrics_->RecordAllMetrics(false); | ||
histogram_tester_.ExpectBucketCount(kLastUsageTimeHistogramName, 2, 1); | ||
} | ||
|
||
TEST_F(BraveVpnMetricsTest, WidgetUsageAndHideMetrics) { | ||
histogram_tester_.ExpectTotalCount(kWidgetUsageHistogramName, 0); | ||
histogram_tester_.ExpectTotalCount(kHideWidgetHistogramName, 0); | ||
|
||
// Test widget usage recording | ||
metrics_->RecordWidgetUsage(true); | ||
histogram_tester_.ExpectUniqueSample(kWidgetUsageHistogramName, 0, 1); | ||
|
||
// Record multiple usages | ||
metrics_->RecordWidgetUsage(true); | ||
metrics_->RecordWidgetUsage(true); | ||
histogram_tester_.ExpectBucketCount(kWidgetUsageHistogramName, 1, 2); | ||
|
||
profile_prefs_.SetBoolean(kNewTabPageShowBraveVPN, true); | ||
histogram_tester_.ExpectTotalCount(kHideWidgetHistogramName, 0); | ||
// Test hide widget metric | ||
profile_prefs_.SetBoolean(kNewTabPageShowBraveVPN, false); | ||
histogram_tester_.ExpectUniqueSample(kHideWidgetHistogramName, true, 1); | ||
|
||
histogram_tester_.ExpectTotalCount(kWidgetUsageHistogramName, 3); | ||
} | ||
|
||
} // namespace brave_vpn |
Oops, something went wrong.