30 Commits
Author SHA1 Message Date
Aleksei Seren d5f5a2ecc4 Switch Serp Metrics daily boundary calculations to UTC (#35829)
Replace local-midnight timestamps with UTC midnight throughout
`SerpMetrics` and `SerpMetricsTimePeriodStorage` so daily report
windows are always exactly 24 hours and unaffected by DST
transitions. Add a `kLastReportedAt` preference to store the
timestamp of each successful daily ping, giving
`GetStartOfStalePeriod` a UTC-aligned starting point. Existing
profiles that have no `kLastReportedAt` value continue migrating
from the legacy local-date string in `kLastCheckYMD` until they
send their first report under the new scheme. Remove the
DST-specific test files since UTC boundaries need no DST correction.
2026-04-28 21:59:20 +02:00
Aleksei Seren 826ec7684b [CodeHealth] Clean up SerpMetrics time period storage API (#35755)
Applies a set of code health fixes to the serp metrics time period
storage layer: normalises the pref store constructor interface,
uses C++ references for non-nullable service dependencies, adds
final to concrete classes, relocates test-only headers to test/
subdirectories, and gives test helpers fully qualified names.
2026-04-22 21:34:30 +01:00
Aleksei Seren a716f8d0ea [CodeHealth] Remove unused API from SerpMetricsTimePeriodStorage (#35727)
The deprecated PrefService-based constructors and five methods with no
production callsites were carried over from TimePeriodStorage. The UTC
and DST-offset modes were always disabled in every caller, and the
internal clock was always the system clock, leaving them dead code. All
are removed; tests are migrated to the store-based constructor and a
plain fixture.
2026-04-21 23:23:09 +00:00
Aleksei Seren 39d9920a98 [CodeHealth] Enable clang-tidy and fix violations (#35721)
Add .clang-tidy to browser/serp_metrics and components/serp_metrics
to enforce bugprone, readability, modernize, and performance checks.
Also fix violations surfaced by the new configuration including uppercase literal suffixes,
unused includes, dangling string_view in test fixture, non-static
accessors in tests, and Windows-conditional tests guarded via #if instead
of MAYBE_ macros.
2026-04-21 21:16:09 +01:00
Aleksei Seren f778f3623b Make SerpMetrics specific copy of TimePeriodStorage (#35697)
serp_metrics makes its own copy of the time_period_storage types
with SerpMetrics prefixed names to allow adding new functionality
that is not compatible with existing interfaces and to reduce the
risk of breaking existing P3A functionality.
2026-04-21 10:10:09 -05:00
Terry Mancey 008ab50672 [time_period_storage][serp_metrics] Fix daily bucket rollover after DST start (#35463)
When a user records activity across a DST transition, the shorter
calendar day (23 hours for a standard 1-hour shift, or as few as 22
hours for Antarctica/Troll's 2-hour shift) caused activity from two
consecutive days to be merged into one bucket, inflating the earlier
day's count and silently discarding the later day's data.
FilterToPeriod advanced to the next bucket by adding exactly 24
hours, which on a DST start day overshoots the next local midnight
and skips that bucket entirely. NextMidnight fixes this for SERP
metrics (local time, no DST offset tolerance) by adding 26 hours to
land safely inside the next calendar day and snapping back to
LocalMidnight. P3A continues to use +24h with the one-hour
GetDstOffset tolerance; UTC also uses +24h because its days are
always exactly 24 hours. Regression tests covering DST start, DST
end, and day boundary cusps are added. The one-hour tolerance in
GetPeriodSumInTimeRange is not adjusted because that function already
overcounts by up to one hour for P3A; tightening it would silently
change existing behavior.
2026-04-14 19:18:41 +01:00
Aleksei Seren dd73f81237 Add UTC support to TimePeriodStorage (#35319)
TimePeriodStorage currently buckets data by local time,
which aligns with Desktop and Android where daily pings
are based on local time. iOS, however, uses UTC for its
daily pings. To support SERP metrics on iOS,
TimePeriodStorage needs an option to operate in UTC.

The PR just adds UTC support and doesn't change
current functionality. We are still using local time for
SERP metrics and for other TimePeriodStorage usages.
Local time is used by default unless `should_use_utc`
constructor parameter is explicitly set to true.
2026-04-07 21:12:38 -05:00
Terry Mancey 49f4e03f3d [serp_metrics][CodeHealth] Run SerpMetricsTest across representative timezones (#35346)
Decouples FakeTimePeriodStore and FakeTimePeriodStoreFactory from serp_metrics_unittest.cc into fake_time_period_store.h and a test_support target. Also decouples kTimezones and TimezoneTestParamName into timezone_test_util.h. Converts SerpMetricsTest from TestWithParam<const char*> to TestWithParam<std::string_view> to match the timezone test util param type. Parameterizes all tests across representative IANA timezones covering UTC-11 to UTC+13, DST and no-DST, whole-hour and fractional-hour offsets.
2026-04-08 02:33:21 +02:00
Terry Mancey f6803618d7 [serp_metrics] Only record Google metrics for web searches (#35193)
Google vertical searches are identified by the presence of a `tbm`
parameter (images, news, video, shopping, books) or a `udm` parameter
set to a vertical value (images, video, shopping, forums, short
videos). Previously these were counted toward Google SERP metrics
alongside regular web searches, inflating the count. This adds
`IsGoogleWebSearch` to filter them out so only plain web searches are
recorded. `udm=0` (implicit default), `udm=14` (web without AI
Overviews), and `udm=web` are all treated as web searches.
2026-04-02 13:55:29 -05:00
Aleksei Seren 0deca93a6c Make SerpMetricsService reusable on iOS (#35185)
The PR makes `SerpMetricsService` reusable on iOS
by injecting time period store factory and removing
its dependency on browser layer types.
2026-04-02 14:41:19 +01:00
Terry Mancey 5c81465346 Fix SERP metrics search count being incorrect at day rollover (#35082)
In a rare edge case where search counts are queried at the exact moment
the clock crosses midnight, the start and end of the time range could be
computed from different points in time, causing both the stale period
and yesterday counts to be incorrect. The fix captures a single time
snapshot up front so both boundaries are always consistent.
2026-03-30 23:56:12 +02:00
Claudio DeSouza 5ca35fdb69 [cr147] GetAllPrepopulatedEngines has moved
This change corrects the call to `GetAllPrepopulatedEngines`, which is
now a free fucntion under `regional_capabilities::`.

Chromium changes:
https://chromium.googlesource.com/chromium/src/+/a507104ab4c62c1c4d6bcbc97afb4bf58393de05

commit a507104ab4c62c1c4d6bcbc97afb4bf58393de05
Author: Nicolas Dossou-Gbete <dgn@chromium.org>
Date:   Mon Feb 16 01:35:09 2026 -0800

    ose-split: Declare the PrepopulatedEngineMigration feature flag

    This flag will guard the logic allowing us to change the prepopulated ID
    associated with given prepopulated engines, and update the local data
    associated with the previous version of the these engines. Adding this
    flag requires also flagging when a keywords DB update has been made
    while the feature is enabled, to add the flag state as another keywords
    DB update triggering criteria.

    As part of the CL we also wrap usage of kAllEngines with a getter that
    allows swapping it out in tests, to exercise the logic related to using
    that second list of non-regional known engines as fallback.

    Bug: 446637115
    Change-Id: I618503a7b32df12be559511ec97651122cf3a5b7
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7544515
    Reviewed-by: Jérôme Lebel <jlebel@chromium.org>
    Commit-Queue: Nicolas Dossou-Gbété <dgn@chromium.org>
    Reviewed-by: James Lee <ljjlee@google.com>
    Auto-Submit: Nicolas Dossou-Gbété <dgn@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#1585320}
2026-03-26 19:25:05 -04:00
Aleksei Seren cf4edb452a Refactor SerpMetrics to use TimePeriodStoreFactory (#34882)
This is a code health change which allows us to simplify
codebase and remove unnecessary `serp_metrics_factory.h`
utility file.
2026-03-23 12:59:32 -05:00
Aleksei Seren 32fe44e5da Migrate SERP metrics to profile attributes (#34724)
The PR migrates existing SERP metrics from profile preferences
to profile attributes.
Migration happens in BraveStatsUpdater::OnProfileAdded
where Profile is added to the ProfileManager, the profile is
fully created and registered with the ProfileManager.
2026-03-18 12:48:44 -05:00
Aleksei Seren d700d81f46 Add SERP metrics prefs target (#34712)
The PR adds SERP metrics prefs target and includes
kDeprecatedSerpMetricsTimePeriodStorage preference to it.
This will allow us to use kDeprecatedSerpMetricsTimePeriodStorage
preference without duplication. The change is pre-requisite for
SERP metrics profile attribute migration.
2026-03-16 22:29:50 -05:00
Terry Mancey b262d21ea5 [CodeHealth] SERP metrics (#34602) 2026-03-10 18:43:48 +00:00
Terry Mancey a86c7f70bd [CodeHealth] SERP metrics (#34518)
As part of general code health improvements, apply IWYU fixes, replace
SerpClassifier with free functions, improve TestHttpsServerBuilder,
update tests whose behavior did not match our expectations, and
deduplicate the search engine allowlist.
2026-03-09 16:21:51 +00:00
Terry Mancey 6f5e7733df Fixes Startpage searches are not recorded in serp_metrics (#34492) 2026-03-05 21:46:18 +00:00
Aleksei Seren e4adbdc310 Store SERP metrics in profile attributes (#34399)
The PR moves SERP metrics from profile prefs
to profile attributes to add multi-profile support.
2026-03-04 19:43:01 +00:00
Terry Mancey e137cca00c SERP metrics should support extensions (#34394)
SERP metrics should be supported for browser extensions to ensure
analytics are consistent. Currently, extension traffic isn’t being
reported.
2026-03-04 11:41:19 +00:00
Terry Mancey 6220eb7035 Deterministically classify “other” search engines (#34271)
Use an allow list to deterministically classify ‘other’ search engines.
2026-03-03 12:10:02 +00:00
Terry Mancey ec982fc475 Fixes searches from "Mojeek" originating from Brave Search aren't cou… (#34228)
Fixes searches from "Mojeek" originating from Brave Search aren't counted in SERP metric

The issue was that TemplateURLService initially only contains the
default search engines. Other prepopulated engines are added lazily when
their homepages are visited.
2026-02-27 07:22:14 -05:00
Aleksei Seren 68b9474d5b Refactor SerpMetrics to use SerpMetricType (#34069)
Reduces code duplication in SerpMetrics by adding parameterized
methods that accept a SerpMetricType.
2026-02-20 11:55:41 -05:00
Terry Mancey 273ae5441a Follow up to #52104: Deleted SERP metrics can be recovered (#33770)
This occurred because TimePeriodStorage keeps internal state in memory
that can be rewritten to disk; as a result, SERP metrics reappear if the
user visits SERP again, but they do not reappear if the browser is
restarted, since the in-memory state is cleared.
2026-02-08 23:02:47 -05:00
Terry Mancey 92cc95752e [CodeHealth] Test cleanup and coverage improvements for SERP metrics (#33737) 2026-02-06 19:39:37 +00:00
Terry Mancey 6b39333b77 Fix SerpMetricsTabHelperTest failures (#33687)
This PR makes sure our tests check the actual data the browser is using,
so results are always accurate and consistent with what’s really
happening during a session.
2026-02-05 16:55:47 -05:00
Terry Mancey d369620dc1 Follow up to #52104: Sometimes SERP count is not properly counted in the usage ping (#33712)
kLastCheckYMD stores the day the usage ping was sent, but the ping only
reports metrics for the previous completed day and any accumulated stale
period. When kLastCheckYMD was interpreted as "metrics up to this day
have already been reported", searches recorded later that same day were
excluded from both the stale and yesterday buckets and never reported.
2026-02-05 21:34:08 +00:00
Terry ManceyandAleksei Seren d84b898e39 Include SERP metrics in the daily usage ping (Desktop/Android) (#33474)
This change extends the existing usage ping to include aggregated SERP
metrics for the previous day, along with a stale total to account for
missed reporting. Metrics are reported only as aggregates and are sent
using the existing anonymous usage reporting flow, enabling server-side
analysis of overall search usage without increasing data granularity or
privacy risk.

This is part of https://github.com/brave/brave-browser/issues/52104.

Co-authored-by: Aleksei Seren <aseren@brave.com>
2026-02-04 16:28:08 +00:00
Terry ManceyandAleksei Seren 490ec0ffb1 Implement SERP URL classifier (#33472)
This change adds logic to classify navigated URLs as search engine
results pages and determine the corresponding search engine bucket
(Brave, Google, or Other). The classifier operates solely on URL
structure and does not extract or persist query terms, providing a
reliable and privacy-safe foundation for SERP detection and metrics
collection.

This is part of https://github.com/brave/brave-browser/issues/52104.

Co-authored-by: Aleksei Seren <aseren@brave.com>
2026-02-02 15:02:34 -05:00
Terry ManceyandAleksei Seren 6f300fe059 Implement daily aggregation and storage of SERP metrics (#33471)
This change introduces a privacy-preserving mechanism to aggregate daily
counts of search engine results page (SERP) navigations within the
browser. Metrics are stored as rolling, pref-backed aggregates and
bucketed by search engine (Brave, Google, Other), with no URLs, queries,
or per-event data recorded. Aggregation is aligned to local calendar
days and supports recovery of missed reporting via a bounded stale
period, enabling accurate long-term measurement of overall search usage
while maintaining Brave’s privacy guarantees.

This is part of https://github.com/brave/brave-browser/issues/52104.

Co-authored-by: Aleksei Seren <aseren@brave.com>
2026-02-01 11:52:38 -05:00