Skip to content

Commit

Permalink
Merge pull request #5302 from brave/ie_p3a_search_volume
Browse files Browse the repository at this point in the history
Issue 8854: Implement search counter p3a metric.
  • Loading branch information
iefremov authored May 6, 2020
2 parents 3989f82 + 9ff073c commit 5676d95
Show file tree
Hide file tree
Showing 18 changed files with 400 additions and 434 deletions.
1 change: 1 addition & 0 deletions browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ source_set("browser_process") {
"//brave/components/resources",
"//brave/components/services:brave_content_manifest_overlays",
"//brave/components/speedreader:buildflags",
"//brave/components/weekly_storage",
"//brave/services/network/public/cpp",
"//chrome/common",
"//components/autofill/core/common",
Expand Down
5 changes: 5 additions & 0 deletions browser/brave_profile_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "brave/browser/brave_profile_prefs.h"

#include "brave/browser/themes/brave_dark_mode_utils.h"
#include "brave/browser/ui/omnibox/brave_omnibox_client_impl.h"
#include "brave/common/brave_wallet_constants.h"
#include "brave/common/pref_names.h"
#include "brave/components/binance/browser/buildflags/buildflags.h"
Expand Down Expand Up @@ -229,6 +230,10 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
speedreader::SpeedreaderService::RegisterPrefs(registry);
#endif

#if !defined(OS_ANDROID)
BraveOmniboxClientImpl::RegisterPrefs(registry);
#endif

RegisterProfilePrefsForMigration(registry);
}

Expand Down
120 changes: 16 additions & 104 deletions browser/p3a/p3a_core_metrics.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

#include "brave/browser/p3a/p3a_core_metrics.h"

#include <numeric>
#include <utility>

#include "base/metrics/histogram_macros.h"
Expand All @@ -16,7 +15,6 @@
#include "chrome/browser/ui/browser_list.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"

namespace brave {

Expand Down Expand Up @@ -54,103 +52,33 @@ const char* GetPrefNameForProfile(Profile* profile) {
BraveUptimeTracker* g_brave_uptime_tracker_instance = nullptr;

constexpr size_t kUsageTimeQueryIntervalMinutes = 1;
constexpr size_t kNumOfSavedDailyUptimes = 7;
constexpr char kDailyUptimesListPrefName[] = "daily_uptimes";

} // namespace

UsagePermanentState::UsagePermanentState(PrefService* local_state)
: local_state_(local_state) {
if (local_state) {
LoadUptimes();
}
}

UsagePermanentState::~UsagePermanentState() = default;

void UsagePermanentState::AddInterval(base::TimeDelta delta) {
base::Time now_midnight = base::Time::Now().LocalMidnight();
base::Time last_saved_midnight;

if (!daily_uptimes_.empty()) {
last_saved_midnight = daily_uptimes_.front().day;
}

if (now_midnight - last_saved_midnight > base::TimeDelta()) {
// Day changed. Since we consider only small incoming intervals, lets just
// save it with a new timestamp.
daily_uptimes_.push_front({now_midnight, delta});
if (daily_uptimes_.size() > kNumOfSavedDailyUptimes) {
daily_uptimes_.pop_back();
}
} else {
daily_uptimes_.front().uptime += delta;
}

RecordP3A();
SaveUptimes();
}

base::TimeDelta UsagePermanentState::GetTotalUsage() const {
// We record only uptime for last N days.
const base::Time n_days_ago =
base::Time::Now() - base::TimeDelta::FromDays(kNumOfSavedDailyUptimes);
return std::accumulate(daily_uptimes_.begin(), daily_uptimes_.end(),
DailyUptime(),
[n_days_ago](const auto& u1, const auto& u2) {
base::TimeDelta add;
// Check only last continious days.
if (u2.day > n_days_ago) {
add = u2.uptime;
}
return DailyUptime{{}, u1.uptime + add};
})
.uptime;
}

void UsagePermanentState::LoadUptimes() {
DCHECK(daily_uptimes_.empty());
const base::ListValue* list =
local_state_->GetList(kDailyUptimesListPrefName);
if (!list) {
return;
}
for (auto it = list->begin(); it != list->end(); ++it) {
const base::Value* day = it->FindKey("day");
const base::Value* uptime = it->FindKey("uptime");
if (!day || !uptime || !day->is_double() || !uptime->is_double()) {
continue;
}
if (daily_uptimes_.size() == kNumOfSavedDailyUptimes) {
break;
}
daily_uptimes_.push_back(
{base::Time::FromDoubleT(day->GetDouble()),
base::TimeDelta::FromSecondsD(uptime->GetDouble())});
}
BraveUptimeTracker::BraveUptimeTracker(PrefService* local_state)
: state_(local_state, kDailyUptimesListPrefName) {
timer_.Start(
FROM_HERE, base::TimeDelta::FromMinutes(kUsageTimeQueryIntervalMinutes),
base::Bind(&BraveUptimeTracker::RecordUsage, base::Unretained(this)));
}

void UsagePermanentState::SaveUptimes() {
DCHECK(!daily_uptimes_.empty());
DCHECK_LE(daily_uptimes_.size(), kNumOfSavedDailyUptimes);
void BraveUptimeTracker::RecordUsage() {
const base::TimeDelta new_total = usage_clock_.GetTotalUsageTime();
const base::TimeDelta interval = new_total - current_total_usage_;
if (interval > base::TimeDelta()) {
state_.AddDelta(interval.InSeconds());
current_total_usage_ = new_total;

ListPrefUpdate update(local_state_, kDailyUptimesListPrefName);
base::ListValue* list = update.Get();
// TODO(iefremov): Optimize if needed.
list->Clear();
for (const auto& u : daily_uptimes_) {
base::DictionaryValue value;
value.SetKey("day", base::Value(u.day.ToDoubleT()));
value.SetKey("uptime", base::Value(u.uptime.InSecondsF()));
list->Append(std::move(value));
RecordP3A();
}
}

void UsagePermanentState::RecordP3A() {
void BraveUptimeTracker::RecordP3A() {
int answer = 0;
if (daily_uptimes_.size() == kNumOfSavedDailyUptimes) {
base::TimeDelta total = GetTotalUsage();
const int minutes = total.InMinutes();
if (state_.IsOneWeekPassed()) {
uint64_t total = state_.GetWeeklySum();
const int minutes = base::TimeDelta::FromSeconds(total).InMinutes();
DCHECK_GE(minutes, 0);
if (0 <= minutes && minutes < 30) {
answer = 1;
Expand All @@ -163,22 +91,6 @@ void UsagePermanentState::RecordP3A() {
UMA_HISTOGRAM_EXACT_LINEAR("Brave.Uptime.BrowserOpenMinutes", answer, 3);
}

BraveUptimeTracker::BraveUptimeTracker(PrefService* local_state)
: state_(local_state) {
timer_.Start(
FROM_HERE, base::TimeDelta::FromMinutes(kUsageTimeQueryIntervalMinutes),
base::Bind(&BraveUptimeTracker::RecordUsage, base::Unretained(this)));
}

void BraveUptimeTracker::RecordUsage() {
const base::TimeDelta new_total = usage_clock_.GetTotalUsageTime();
const base::TimeDelta interval = new_total - current_total_usage_;
if (interval > base::TimeDelta()) {
state_.AddInterval(interval);
current_total_usage_ = new_total;
}
}

BraveUptimeTracker::~BraveUptimeTracker() = default;

void BraveUptimeTracker::CreateInstance(PrefService* local_state) {
Expand Down
25 changes: 3 additions & 22 deletions browser/p3a/p3a_core_metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <list>

#include "base/timer/timer.h"
#include "brave/components/weekly_storage/weekly_storage.h"
#include "chrome/browser/resource_coordinator/usage_clock.h"
#include "chrome/browser/ui/browser_list_observer.h"

Expand All @@ -17,27 +18,6 @@ class PrefRegistrySimple;

namespace brave {

class UsagePermanentState {
public:
explicit UsagePermanentState(PrefService* local_state);
~UsagePermanentState();

void AddInterval(base::TimeDelta delta);
base::TimeDelta GetTotalUsage() const;

private:
struct DailyUptime {
base::Time day;
base::TimeDelta uptime;
};
void LoadUptimes();
void SaveUptimes();
void RecordP3A();

std::list<DailyUptime> daily_uptimes_;
PrefService* local_state_ = nullptr;
};

class BraveUptimeTracker {
public:
explicit BraveUptimeTracker(PrefService* local_state);
Expand All @@ -49,11 +29,12 @@ class BraveUptimeTracker {

private:
void RecordUsage();
void RecordP3A();

resource_coordinator::UsageClock usage_clock_;
base::RepeatingTimer timer_;
base::TimeDelta current_total_usage_;
UsagePermanentState state_;
WeeklyStorage state_;

DISALLOW_COPY_AND_ASSIGN(BraveUptimeTracker);
};
Expand Down
1 change: 1 addition & 0 deletions browser/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ source_set("ui") {
"//brave/components/brave_wallet/browser/buildflags:buildflags",
"//brave/components/brave_welcome_ui:generated_resources",
"//brave/components/p3a:buildflags",
"//brave/components/weekly_storage",
"//chrome/app:command_ids",
"//chrome/app/vector_icons:vector_icons",
"//chrome/common",
Expand Down
70 changes: 65 additions & 5 deletions browser/ui/omnibox/brave_omnibox_client_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,73 @@

#include "brave/browser/ui/omnibox/brave_omnibox_client_impl.h"

#include <algorithm>

#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "brave/browser/autocomplete/brave_autocomplete_scheme_classifier.h"
#include "brave/common/pref_names.h"
#include "brave/components/weekly_storage/weekly_storage.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/omnibox/chrome_omnibox_client.h"
#include "chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"

namespace {

constexpr char kSearchCountPrefName[] = "brave.weekly_storage.search_count";

bool IsSearchEvent(const AutocompleteMatch& match) {
switch (match.type) {
case AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED:
case AutocompleteMatchType::SEARCH_HISTORY:
case AutocompleteMatchType::SEARCH_SUGGEST:
case AutocompleteMatchType::SEARCH_SUGGEST_ENTITY:
case AutocompleteMatchType::SEARCH_SUGGEST_TAIL:
case AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED:
case AutocompleteMatchType::SEARCH_SUGGEST_PROFILE:
case AutocompleteMatchType::SEARCH_OTHER_ENGINE:
return true;
default:
return false;
}
return false;
}

void RecordSearchEventP3A(uint64_t number_of_searches) {
constexpr int kIntervals[] = {0, 5, 10, 20, 50, 100, 500};
const int* it =
std::lower_bound(kIntervals, std::end(kIntervals), number_of_searches);
const int answer = it - kIntervals;
UMA_HISTOGRAM_EXACT_LINEAR("Brave.Omnibox.SearchCount", answer,
base::size(kIntervals));
}

} // namespace

BraveOmniboxClientImpl::BraveOmniboxClientImpl(
OmniboxEditController* controller,
Profile* profile)
: ChromeOmniboxClient(controller, profile),
profile_(profile),
scheme_classifier_(profile) {}
OmniboxEditController* controller,
Profile* profile)
: ChromeOmniboxClient(controller, profile),
profile_(profile),
scheme_classifier_(profile) {
// Record initial search count p3a value.
const base::Value* search_p3a =
profile_->GetPrefs()->GetList(kSearchCountPrefName);
if (search_p3a->GetList().size() == 0) {
RecordSearchEventP3A(0);
}
}

BraveOmniboxClientImpl::~BraveOmniboxClientImpl() {}

void BraveOmniboxClientImpl::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterListPref(kSearchCountPrefName);
}

const AutocompleteSchemeClassifier&
BraveOmniboxClientImpl::GetSchemeClassifier() const {
return scheme_classifier_;
Expand All @@ -29,3 +80,12 @@ BraveOmniboxClientImpl::GetSchemeClassifier() const {
bool BraveOmniboxClientImpl::IsAutocompleteEnabled() const {
return profile_->GetPrefs()->GetBoolean(kAutocompleteEnabled);
}

void BraveOmniboxClientImpl::OnInputAccepted(const AutocompleteMatch& match) {
if (IsSearchEvent(match)) {
// TODO(iefremov): Optimize this.
WeeklyStorage storage(profile_->GetPrefs(), kSearchCountPrefName);
storage.AddDelta(1);
RecordSearchEventP3A(storage.GetWeeklySum());
}
}
11 changes: 8 additions & 3 deletions browser/ui/omnibox/brave_omnibox_client_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@
#ifndef BRAVE_BROWSER_UI_OMNIBOX_BRAVE_OMNIBOX_CLIENT_IMPL_H_
#define BRAVE_BROWSER_UI_OMNIBOX_BRAVE_OMNIBOX_CLIENT_IMPL_H_

#include "chrome/browser/ui/omnibox/chrome_omnibox_client.h"
#include "brave/browser/autocomplete/brave_autocomplete_scheme_classifier.h"
#include "chrome/browser/ui/omnibox/chrome_omnibox_client.h"

class OmniboxEditController;
class PrefRegistrySimple;
class Profile;

class BraveOmniboxClientImpl : public ChromeOmniboxClient {
public:
BraveOmniboxClientImpl(OmniboxEditController* controller,
Profile* profile);
BraveOmniboxClientImpl(OmniboxEditController* controller, Profile* profile);
~BraveOmniboxClientImpl() override;

static void RegisterPrefs(PrefRegistrySimple* prefs);

const AutocompleteSchemeClassifier& GetSchemeClassifier() const override;
bool IsAutocompleteEnabled() const override;

void OnInputAccepted(const AutocompleteMatch& match) override;

private:
Profile* profile_;
BraveAutocompleteSchemeClassifier scheme_classifier_;
Expand Down
3 changes: 1 addition & 2 deletions components/brave_perf_predictor/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ source_set("browser") {
"bandwidth_savings_predictor.h",
"named_third_party_registry.cc",
"named_third_party_registry.h",
"p3a_bandwidth_savings_permanent_state.cc",
"p3a_bandwidth_savings_permanent_state.h",
"p3a_bandwidth_savings_tracker.cc",
"p3a_bandwidth_savings_tracker.h",
"perf_predictor_page_metrics_observer.cc",
Expand All @@ -36,6 +34,7 @@ source_set("browser") {
"//base",
"//brave/components/brave_perf_predictor/common",
"//brave/components/resources",
"//brave/components/weekly_storage",
"//components/page_load_metrics/browser",
"//components/page_load_metrics/common",
"//components/prefs",
Expand Down
Loading

0 comments on commit 5676d95

Please sign in to comment.