Skip to content

Commit

Permalink
[Merge to M102][Topics] Add UKM metrics
Browse files Browse the repository at this point in the history
Add UKM metrics for:
- Epoch topics calculation result (not URL keyed)
- document.browsingTopics() API result
- Number of unique context domains using the API per page load.

UKM collection privacy review (approved):
https://docs.google.com/document/d/1ddfLDWtnddW7bMjXXFvY58WncGjMYgq-98udJ7AE02M

(cherry picked from commit 716e481)

Bug: 1316647
Change-Id: Id8bfb9ff235e282f836b15b6c642ba50cb74dcda
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3588679
Reviewed-by: Josh Karlin <jkarlin@chromium.org>
Reviewed-by: Robert Kaplow <rkaplow@chromium.org>
Commit-Queue: Yao Xiao <yaoxia@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#994406}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3605949
Cr-Commit-Position: refs/branch-heads/5005@{#157}
Cr-Branched-From: 5b4d945-refs/heads/main@{#992738}
  • Loading branch information
yaoxiachromium authored and Chromium LUCI CQ committed Apr 26, 2022
1 parent 2dacf40 commit 7ba8c02
Show file tree
Hide file tree
Showing 15 changed files with 1,142 additions and 52 deletions.
163 changes: 163 additions & 0 deletions chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
Expand Up @@ -28,14 +28,17 @@
#include "components/optimization_guide/core/test_model_info_builder.h"
#include "components/optimization_guide/core/test_optimization_guide_model_provider.h"
#include "components/privacy_sandbox/privacy_sandbox_settings.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/browsing_topics_site_data_manager.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_features.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browsing_topics_test_util.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/features.h"

Expand Down Expand Up @@ -417,6 +420,9 @@ class BrowsingTopicsBrowserTest : public BrowsingTopicsBrowserTestBase {
calculation_finish_waiters_.emplace(profile,
std::make_unique<base::RunLoop>());

if (!ukm_recorder_)
ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();

return std::make_unique<TesterBrowsingTopicsService>(
profile->GetPath(), privacy_sandbox_settings, history_service,
site_data_manager, annotations_service,
Expand All @@ -437,6 +443,8 @@ class BrowsingTopicsBrowserTest : public BrowsingTopicsBrowserTestBase {

optimization_guide::TestPageContentAnnotator test_page_content_annotator_;

std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;

base::CallbackListSubscription subscription_;
};

Expand Down Expand Up @@ -503,6 +511,161 @@ IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, BrowsingTopicsStateOnStart) {
now + base::Days(7));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, CalculationResultUkm) {
auto entries = ukm_recorder_->GetEntriesByName(
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::kEntryName);

// The number of entries should equal the number of profiles, which could be
// greater than 1 on some platform.
EXPECT_EQ(optimization_guide_model_providers_.size(), entries.size());

for (auto* entry : entries) {
ukm_recorder_->ExpectEntryMetric(
entry,
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic0Name,
6);
ukm_recorder_->ExpectEntryMetric(
entry,
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic1Name,
5);
ukm_recorder_->ExpectEntryMetric(
entry,
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic2Name,
4);
ukm_recorder_->ExpectEntryMetric(
entry,
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic3Name,
3);
ukm_recorder_->ExpectEntryMetric(
entry,
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic4Name,
2);
ukm_recorder_->ExpectEntryMetric(
entry,
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTaxonomyVersionName,
1);
ukm_recorder_->ExpectEntryMetric(
entry,
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kModelVersionName,
1);
ukm_recorder_->ExpectEntryMetric(
entry,
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kPaddedTopicsStartIndexName,
5);
}
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, ApiResultUkm) {
GURL main_frame_url =
https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

InvokeTopicsAPI(web_contents());

auto entries = ukm_recorder_->GetEntriesByName(
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kEntryName);
EXPECT_EQ(1u, entries.size());

ukm_recorder_->ExpectEntrySourceHasUrl(entries.back(), main_frame_url);

const int64_t* topic0_metric = ukm_recorder_->GetEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic0Name);
const int64_t* topic1_metric = ukm_recorder_->GetEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic1Name);

EXPECT_TRUE(topic0_metric);
EXPECT_TRUE(topic1_metric);

EXPECT_TRUE((*topic0_metric == kExpectedTopic1.value() &&
*topic1_metric == kExpectedTopic2.value()) ||
(*topic0_metric == kExpectedTopic2.value() &&
*topic1_metric == kExpectedTopic1.value()));

ukm_recorder_->ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic0IsTrueTopTopicName,
true);
ukm_recorder_->ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic0ModelVersionName,
2);
ukm_recorder_->ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic0TaxonomyVersionName,
1);

ukm_recorder_->ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic1IsTrueTopTopicName,
true);
ukm_recorder_->ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic1ModelVersionName,
2);
ukm_recorder_->ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic1TaxonomyVersionName,
1);

EXPECT_FALSE(ukm_recorder_->GetEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kReturnedTopic2Name));
EXPECT_FALSE(ukm_recorder_->GetEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_DocumentBrowsingTopicsApiResult::
kEmptyReasonName));
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, PageLoadUkm) {
// The test assumes pages gets deleted after navigation, triggering metrics
// recording. Disable back/forward cache to ensure that pages don't get
// preserved in the cache.
content::DisableBackForwardCacheForTesting(
web_contents(), content::BackForwardCache::TEST_REQUIRES_NO_CACHING);

GURL main_frame_url =
https_server_.GetURL("a.test", "/browsing_topics/one_iframe_page.html");

ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url));

InvokeTopicsAPI(web_contents());

ASSERT_TRUE(
ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));

auto entries = ukm_recorder_->GetEntriesByName(
ukm::builders::BrowsingTopics_PageLoad::kEntryName);
EXPECT_EQ(1u, entries.size());

ukm_recorder_->ExpectEntrySourceHasUrl(entries.back(), main_frame_url);

ukm_recorder_->ExpectEntryMetric(entries.back(),
ukm::builders::BrowsingTopics_PageLoad::
kTopicsRequestingContextDomainsCountName,
1);
}

IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, GetTopicsForSiteForDisplay) {
GURL main_frame_url =
https_server_.GetURL("a.test", "/browsing_topics/empty_page.html");
Expand Down
3 changes: 3 additions & 0 deletions components/browsing_topics/BUILD.gn
Expand Up @@ -33,6 +33,8 @@ source_set("browsing_topics") {
"//content/public/common:common",
"//crypto",
"//net/base/registry_controlled_domains",
"//services/metrics/public/cpp:metrics_cpp",
"//services/metrics/public/cpp:ukm_builders",
"//third_party/blink/public/common",
]
}
Expand Down Expand Up @@ -83,6 +85,7 @@ source_set("unit_tests") {
"//components/privacy_sandbox:privacy_sandbox_prefs",
"//components/privacy_sandbox:test_support",
"//components/sync_preferences:test_support",
"//components/ukm:test_support",
"//content/test:test_support",
"//testing/gtest",
"//third_party/blink/public/common",
Expand Down
2 changes: 2 additions & 0 deletions components/browsing_topics/DEPS
Expand Up @@ -8,12 +8,14 @@ include_rules = [
"+content/test",
"+crypto",
"+net/base/registry_controlled_domains",
"+services/metrics/public/cpp",
"+third_party/blink/public",
]

specific_include_rules = {
".*_unittest.cc": [
"+components/content_settings/core",
"+components/sync_preferences",
"+components/ukm",
],
}
43 changes: 41 additions & 2 deletions components/browsing_topics/browsing_topics_calculator.cc
Expand Up @@ -14,12 +14,52 @@
#include "components/privacy_sandbox/canonical_topic.h"
#include "components/privacy_sandbox/privacy_sandbox_settings.h"
#include "content/public/browser/browsing_topics_site_data_manager.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/public/common/features.h"

namespace browsing_topics {

namespace {

void RecordCalculatorResultMetrics(
const BrowsingTopicsCalculator::CalculatorResultStatus& status,
const EpochTopics& epoch_topics) {
base::UmaHistogramEnumeration(
"BrowsingTopics.EpochTopicsCalculation.CalculatorResultStatus", status);

ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult builder(
ukm::NoURLSourceId());

if (status == BrowsingTopicsCalculator::CalculatorResultStatus::kSuccess) {
const std::vector<TopicAndDomains>& topics =
epoch_topics.top_topics_and_observing_domains();

if (topics.size() > 0 && topics[0].IsValid())
builder.SetTopTopic0(topics[0].topic().value());

if (topics.size() > 1 && topics[1].IsValid())
builder.SetTopTopic1(topics[1].topic().value());

if (topics.size() > 2 && topics[2].IsValid())
builder.SetTopTopic2(topics[2].topic().value());

if (topics.size() > 3 && topics[3].IsValid())
builder.SetTopTopic3(topics[3].topic().value());

if (topics.size() > 4 && topics[4].IsValid())
builder.SetTopTopic4(topics[4].topic().value());

builder.SetTaxonomyVersion(epoch_topics.taxonomy_version())
.SetModelVersion(epoch_topics.model_version())
.SetPaddedTopicsStartIndex(
epoch_topics.padded_top_topics_start_index());
}

builder.Record(ukm_recorder->Get());
}

// Derive the mapping from hosts to topics and the mapping from topics to hosts.
// Precondition: the annotation didn't fail in general (e.g. `ModelInfo` is
// valid).
Expand Down Expand Up @@ -379,8 +419,7 @@ void BrowsingTopicsCalculator::OnCalculateCompleted(
EpochTopics epoch_topics) {
DCHECK(status != CalculatorResultStatus::kSuccess || !epoch_topics.empty());

base::UmaHistogramEnumeration(
"BrowsingTopics.EpochTopicsCalculation.CalculatorResultStatus", status);
RecordCalculatorResultMetrics(status, epoch_topics);

std::move(calculate_completed_callback_).Run(std::move(epoch_topics));

Expand Down
85 changes: 85 additions & 0 deletions components/browsing_topics/browsing_topics_calculator_unittest.cc
Expand Up @@ -25,8 +25,10 @@
#include "components/privacy_sandbox/privacy_sandbox_settings.h"
#include "components/privacy_sandbox/privacy_sandbox_test_util.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/browsing_topics_test_util.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/features.h"

namespace browsing_topics {
Expand Down Expand Up @@ -452,6 +454,89 @@ TEST_F(BrowsingTopicsCalculatorTest, TopTopicsPartiallyPadded) {
EXPECT_EQ(result.padded_top_topics_start_index(), 3u);
}

TEST_F(BrowsingTopicsCalculatorTest, CalculationResultUkm_FailedCalculation) {
ukm::TestAutoSetUkmRecorder ukm_recorder;
privacy_sandbox_settings_->SetPrivacySandboxEnabled(false);

CalculateTopics();

auto entries = ukm_recorder.GetEntriesByName(
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::kEntryName);
EXPECT_EQ(1u, entries.size());

EXPECT_FALSE(ukm_recorder.GetEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic0Name));
}

TEST_F(BrowsingTopicsCalculatorTest, CalculationResultUkm) {
ukm::TestAutoSetUkmRecorder ukm_recorder;
base::HistogramTester histograms;

base::Time begin_time = base::Time::Now();

AddHistoryEntries({kHost4, kHost5, kHost6}, begin_time);

test_page_content_annotator_.UsePageTopics(
*optimization_guide::TestModelInfoBuilder().SetVersion(1).Build(),
{{kTokenizedHost1, TopicsAndWeight({1, 2, 3, 4, 5, 6}, 0.1)},
{kTokenizedHost2, TopicsAndWeight({2, 3, 4, 5, 6}, 0.1)},
{kTokenizedHost3, TopicsAndWeight({3, 4, 5, 6}, 0.1)},
{kTokenizedHost4, TopicsAndWeight({4, 5, 6}, 0.1)},
{kTokenizedHost5, TopicsAndWeight({5, 6}, 0.1)},
{kTokenizedHost6, TopicsAndWeight({6}, 0.1)}});

task_environment_.AdvanceClock(base::Seconds(1));

CalculateTopics();

auto entries = ukm_recorder.GetEntriesByName(
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::kEntryName);
EXPECT_EQ(1u, entries.size());

ukm_recorder.ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic0Name,
6);
ukm_recorder.ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic1Name,
5);
ukm_recorder.ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic2Name,
4);
ukm_recorder.ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic3Name,
101);
ukm_recorder.ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTopTopic4Name,
102);
ukm_recorder.ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kTaxonomyVersionName,
1);
ukm_recorder.ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kModelVersionName,
1);
ukm_recorder.ExpectEntryMetric(
entries.back(),
ukm::builders::BrowsingTopics_EpochTopicsCalculationResult::
kPaddedTopicsStartIndexName,
3);
}

TEST_F(BrowsingTopicsCalculatorTest, TopTopicsAndObservingDomains) {
base::Time begin_time = base::Time::Now();

Expand Down

0 comments on commit 7ba8c02

Please sign in to comment.