summaryrefslogtreecommitdiff
path: root/chromium/components/ukm
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-29 16:35:13 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-01 15:33:35 +0000
commitc8c2d1901aec01e934adf561a9fdf0cc776cdef8 (patch)
tree9157c3d9815e5870799e070b113813bec53e0535 /chromium/components/ukm
parentabefd5095b41dac94ca451d784ab6e27372e981a (diff)
downloadqtwebengine-chromium-c8c2d1901aec01e934adf561a9fdf0cc776cdef8.tar.gz
BASELINE: Update Chromium to 64.0.3282.139
Change-Id: I1cae68fe9c94ff7608b26b8382fc19862cdb293a Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components/ukm')
-rw-r--r--chromium/components/ukm/BUILD.gn23
-rw-r--r--chromium/components/ukm/DEPS1
-rw-r--r--chromium/components/ukm/OWNERS6
-rw-r--r--chromium/components/ukm/content/source_url_recorder.cc10
-rw-r--r--chromium/components/ukm/content/source_url_recorder_browsertest.cc33
-rw-r--r--chromium/components/ukm/content/source_url_recorder_test.cc54
-rw-r--r--chromium/components/ukm/debug_page/debug_page.cc2
-rw-r--r--chromium/components/ukm/test_ukm_recorder.cc100
-rw-r--r--chromium/components/ukm/test_ukm_recorder.h51
-rw-r--r--chromium/components/ukm/ukm_interface.cc42
-rw-r--r--chromium/components/ukm/ukm_interface.h35
-rw-r--r--chromium/components/ukm/ukm_recorder_impl.cc55
-rw-r--r--chromium/components/ukm/ukm_recorder_impl.h11
-rw-r--r--chromium/components/ukm/ukm_reporting_service.cc8
-rw-r--r--chromium/components/ukm/ukm_reporting_service.h6
-rw-r--r--chromium/components/ukm/ukm_service.cc34
-rw-r--r--chromium/components/ukm/ukm_service.h8
-rw-r--r--chromium/components/ukm/ukm_service_unittest.cc126
-rw-r--r--chromium/components/ukm/ukm_source.cc2
19 files changed, 388 insertions, 219 deletions
diff --git a/chromium/components/ukm/BUILD.gn b/chromium/components/ukm/BUILD.gn
index eb7723f2462..3705109962a 100644
--- a/chromium/components/ukm/BUILD.gn
+++ b/chromium/components/ukm/BUILD.gn
@@ -26,9 +26,9 @@ static_library("ukm") {
]
public_deps = [
- "//components/metrics/proto",
"//services/metrics/public/cpp:metrics_cpp",
"//services/metrics/public/interfaces",
+ "//third_party/metrics_proto",
]
deps = [
@@ -41,25 +41,6 @@ static_library("ukm") {
]
}
-static_library("ukm_interface") {
- sources = [
- "ukm_interface.cc",
- "ukm_interface.h",
- ]
-
- public_deps = [
- "//base",
- "//services/metrics/public/cpp:metrics_cpp",
- "//services/metrics/public/interfaces",
- ]
-
- deps = [
- ":ukm",
- "//mojo/public/cpp/bindings",
- "//services/metrics/public/cpp:metrics_cpp",
- ]
-}
-
# Helper library for observing signals that we need to clear any local data.
static_library("observers") {
sources = [
@@ -85,7 +66,7 @@ static_library("test_support") {
public_deps = [
":ukm",
- "//components/metrics/proto",
+ "//third_party/metrics_proto",
]
deps = [
"//base",
diff --git a/chromium/components/ukm/DEPS b/chromium/components/ukm/DEPS
index 099b24d0d0c..74b50a011d2 100644
--- a/chromium/components/ukm/DEPS
+++ b/chromium/components/ukm/DEPS
@@ -4,5 +4,6 @@ include_rules = [
"+components/variations",
"+mojo/public",
"+services/metrics/public",
+ "+third_party/metrics_proto",
"+third_party/zlib/google",
]
diff --git a/chromium/components/ukm/OWNERS b/chromium/components/ukm/OWNERS
index 189104122ea..684cb163c06 100644
--- a/chromium/components/ukm/OWNERS
+++ b/chromium/components/ukm/OWNERS
@@ -1,5 +1,3 @@
-asvitkine@chromium.org
-holte@chromium.org
-rkaplow@chromium.org
+file://base/metrics/OWNERS
-# COMPONENT: Internals>Metrics
+# COMPONENT: Internals>Metrics>UKM
diff --git a/chromium/components/ukm/content/source_url_recorder.cc b/chromium/components/ukm/content/source_url_recorder.cc
index 573ead41136..43d0f8d1efb 100644
--- a/chromium/components/ukm/content/source_url_recorder.cc
+++ b/chromium/components/ukm/content/source_url_recorder.cc
@@ -18,10 +18,6 @@
namespace {
-bool IsValidUkmUrl(const GURL& url) {
- return url.SchemeIsHTTPOrHTTPS();
-}
-
// SourceUrlRecorderWebContentsObserver is responsible for recording UKM source
// URLs, for all main frame navigations in a given WebContents.
// SourceUrlRecorderWebContentsObserver records both the final URL for a
@@ -105,12 +101,10 @@ void SourceUrlRecorderWebContentsObserver::MaybeRecordUrl(
const ukm::SourceId source_id = ukm::ConvertToSourceId(
navigation_handle->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID);
-
- if (IsValidUkmUrl(initial_url))
- ukm_recorder->UpdateSourceURL(source_id, initial_url);
+ ukm_recorder->UpdateSourceURL(source_id, initial_url);
const GURL& final_url = navigation_handle->GetURL();
- if (final_url != initial_url && IsValidUkmUrl(final_url))
+ if (final_url != initial_url)
ukm_recorder->UpdateSourceURL(source_id, final_url);
}
diff --git a/chromium/components/ukm/content/source_url_recorder_browsertest.cc b/chromium/components/ukm/content/source_url_recorder_browsertest.cc
index 93575f3e56f..d2501867c12 100644
--- a/chromium/components/ukm/content/source_url_recorder_browsertest.cc
+++ b/chromium/components/ukm/content/source_url_recorder_browsertest.cc
@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/command_line.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/test/scoped_feature_list.h"
#include "components/ukm/content/source_url_recorder.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/ukm/ukm_source.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/common/content_switches.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/navigation_handle_observer.h"
@@ -19,26 +18,21 @@
class SourceUrlRecorderWebContentsObserverBrowserTest
: public content::ContentBrowserTest {
protected:
+ SourceUrlRecorderWebContentsObserverBrowserTest() {
+ scoped_feature_list_.InitAndEnableFeature(ukm::kUkmFeature);
+ }
+
+ ~SourceUrlRecorderWebContentsObserverBrowserTest() override {}
+
void SetUpOnMainThread() override {
content::ContentBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(embedded_test_server()->Start());
- // UKM DCHECKs if the active UkmRecorder is changed from one instance
- // to another, rather than being changed from a nullptr; browser_tests
- // need to circumvent that to be able to intercept UKM calls with its
- // own TestUkmRecorder instance rather than the default UkmRecorder.
- ukm::UkmRecorder::Set(nullptr);
test_ukm_recorder_ = base::MakeUnique<ukm::TestAutoSetUkmRecorder>();
ukm::InitializeSourceUrlRecorderForWebContents(shell()->web_contents());
}
- void SetUpCommandLine(base::CommandLine* command_line) override {
- content::ContentBrowserTest::SetUpCommandLine(command_line);
- command_line->AppendSwitchASCII(switches::kEnableFeatures,
- ukm::kUkmFeature.name);
- }
-
const ukm::UkmSource* GetSourceForNavigationId(int64_t navigation_id) {
CHECK_GT(navigation_id, 0);
const ukm::SourceId source_id =
@@ -46,7 +40,11 @@ class SourceUrlRecorderWebContentsObserverBrowserTest
return test_ukm_recorder_->GetSourceForSourceId(source_id);
}
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
+
+ DISALLOW_COPY_AND_ASSIGN(SourceUrlRecorderWebContentsObserverBrowserTest);
};
class SourceUrlRecorderWebContentsObserverDownloadBrowserTest
@@ -84,15 +82,6 @@ IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverBrowserTest, Basic) {
}
IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverBrowserTest,
- IgnoreUnsupportedScheme) {
- GURL url("about:blank");
- content::NavigationHandleObserver observer(shell()->web_contents(), url);
- content::NavigateToURL(shell(), url);
- EXPECT_TRUE(observer.has_committed());
- EXPECT_EQ(nullptr, GetSourceForNavigationId(observer.navigation_id()));
-}
-
-IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverBrowserTest,
IgnoreUrlInSubframe) {
GURL main_url = embedded_test_server()->GetURL("/page_with_iframe.html");
GURL subframe_url = embedded_test_server()->GetURL("/title1.html");
diff --git a/chromium/components/ukm/content/source_url_recorder_test.cc b/chromium/components/ukm/content/source_url_recorder_test.cc
index 6fd8386226b..6ac04ae7f1b 100644
--- a/chromium/components/ukm/content/source_url_recorder_test.cc
+++ b/chromium/components/ukm/content/source_url_recorder_test.cc
@@ -29,11 +29,13 @@ class SourceUrlRecorderWebContentsObserverTest
TEST_F(SourceUrlRecorderWebContentsObserverTest, Basic) {
GURL url("https://www.example.com/");
NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), url);
- EXPECT_EQ(1ul, test_ukm_recorder_.sources_count());
- const ukm::UkmSource* ukm_source = test_ukm_recorder_.GetSourceForUrl(url);
- ASSERT_NE(nullptr, ukm_source);
- EXPECT_EQ(url, ukm_source->url());
- EXPECT_TRUE(ukm_source->initial_url().is_empty());
+
+ const auto& sources = test_ukm_recorder_.GetSources();
+ EXPECT_EQ(1ul, sources.size());
+ for (const auto& kv : sources) {
+ EXPECT_EQ(url, kv.second->url());
+ EXPECT_TRUE(kv.second->initial_url().is_empty());
+ }
}
TEST_F(SourceUrlRecorderWebContentsObserverTest, InitialUrl) {
@@ -44,18 +46,12 @@ TEST_F(SourceUrlRecorderWebContentsObserverTest, InitialUrl) {
simulator->Start();
simulator->Redirect(final_url);
simulator->Commit();
- EXPECT_EQ(1ul, test_ukm_recorder_.sources_count());
- const ukm::UkmSource* ukm_source =
- test_ukm_recorder_.GetSourceForUrl(final_url);
- ASSERT_NE(nullptr, ukm_source);
- EXPECT_EQ(final_url, ukm_source->url());
- EXPECT_EQ(initial_url, ukm_source->initial_url());
-}
-
-TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreUnsupportedScheme) {
- NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(),
- GURL("about:blank"));
- EXPECT_EQ(0ul, test_ukm_recorder_.sources_count());
+ const auto& sources = test_ukm_recorder_.GetSources();
+ EXPECT_EQ(1ul, sources.size());
+ for (const auto& kv : sources) {
+ EXPECT_EQ(final_url, kv.second->url());
+ EXPECT_EQ(initial_url, kv.second->initial_url());
+ }
}
TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreUrlInSubframe) {
@@ -66,9 +62,13 @@ TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreUrlInSubframe) {
NavigationSimulator::NavigateAndCommitFromDocument(
sub_frame_url,
content::RenderFrameHostTester::For(main_rfh())->AppendChild("subframe"));
- EXPECT_EQ(1ul, test_ukm_recorder_.sources_count());
- EXPECT_NE(nullptr, test_ukm_recorder_.GetSourceForUrl(main_frame_url));
- EXPECT_EQ(nullptr, test_ukm_recorder_.GetSourceForUrl(sub_frame_url));
+
+ const auto& sources = test_ukm_recorder_.GetSources();
+ EXPECT_EQ(1ul, sources.size());
+ for (const auto& kv : sources) {
+ EXPECT_EQ(main_frame_url, kv.second->url());
+ EXPECT_TRUE(kv.second->initial_url().is_empty());
+ }
}
TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreSameDocumentNavigation) {
@@ -77,11 +77,13 @@ TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreSameDocumentNavigation) {
NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(), url);
NavigationSimulator::CreateRendererInitiated(same_document_url, main_rfh())
->CommitSameDocument();
+
EXPECT_EQ(same_document_url, web_contents()->GetLastCommittedURL());
- EXPECT_EQ(1ul, test_ukm_recorder_.sources_count());
- EXPECT_EQ(nullptr, test_ukm_recorder_.GetSourceForUrl(same_document_url));
- const ukm::UkmSource* ukm_source = test_ukm_recorder_.GetSourceForUrl(url);
- ASSERT_NE(nullptr, ukm_source);
- EXPECT_EQ(url, ukm_source->url());
- EXPECT_TRUE(ukm_source->initial_url().is_empty());
+
+ const auto& sources = test_ukm_recorder_.GetSources();
+ EXPECT_EQ(1ul, sources.size());
+ for (const auto& kv : sources) {
+ EXPECT_EQ(url, kv.second->url());
+ EXPECT_TRUE(kv.second->initial_url().is_empty());
+ }
}
diff --git a/chromium/components/ukm/debug_page/debug_page.cc b/chromium/components/ukm/debug_page/debug_page.cc
index fb6e60dffcf..1bc33a5f3c3 100644
--- a/chromium/components/ukm/debug_page/debug_page.cc
+++ b/chromium/components/ukm/debug_page/debug_page.cc
@@ -10,7 +10,7 @@
#include "base/strings/stringprintf.h"
#include "components/ukm/ukm_service.h"
#include "components/ukm/ukm_source.h"
-#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_decode.h"
#include "url/gurl.h"
namespace ukm {
diff --git a/chromium/components/ukm/test_ukm_recorder.cc b/chromium/components/ukm/test_ukm_recorder.cc
index 5f9e9e60bb6..c3c876cb05a 100644
--- a/chromium/components/ukm/test_ukm_recorder.cc
+++ b/chromium/components/ukm/test_ukm_recorder.cc
@@ -9,13 +9,30 @@
#include "base/logging.h"
#include "base/metrics/metrics_hashes.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "components/ukm/ukm_source.h"
+#include "services/metrics/public/cpp/delegating_ukm_recorder.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ukm {
namespace {
+// Merge the data from |in| to |out|.
+void MergeEntry(const mojom::UkmEntry* in, mojom::UkmEntry* out) {
+ if (out->event_hash) {
+ EXPECT_EQ(out->source_id, in->source_id);
+ EXPECT_EQ(out->event_hash, in->event_hash);
+ } else {
+ out->event_hash = in->event_hash;
+ out->source_id = in->source_id;
+ }
+ for (const auto& metric : in->metrics) {
+ out->metrics.emplace_back(metric->Clone());
+ }
+}
+
// Provides a single merged ukm::mojom::UkmEntry proto that contains all metrics
// from the given |entries|. |entries| must be non-empty, and all |entries| must
// have the same |source_id| and |event_hash|.
@@ -24,16 +41,7 @@ mojom::UkmEntryPtr GetMergedEntry(
EXPECT_FALSE(entries.empty());
mojom::UkmEntryPtr merged_entry = mojom::UkmEntry::New();
for (const auto* entry : entries) {
- if (merged_entry->event_hash) {
- EXPECT_EQ(merged_entry->source_id, entry->source_id);
- EXPECT_EQ(merged_entry->event_hash, entry->event_hash);
- } else {
- merged_entry->event_hash = entry->event_hash;
- merged_entry->source_id = entry->source_id;
- }
- for (const auto& metric : entry->metrics) {
- merged_entry->metrics.emplace_back(metric->Clone());
- }
+ MergeEntry(entry, merged_entry.get());
}
return merged_entry;
}
@@ -122,12 +130,74 @@ const mojom::UkmEntry* TestUkmRecorder::GetEntryForEntryName(
return nullptr;
}
+std::vector<const mojom::UkmEntry*> TestUkmRecorder::GetEntriesByName(
+ base::StringPiece entry_name) const {
+ uint64_t hash = base::HashMetricName(entry_name);
+ std::vector<const mojom::UkmEntry*> result;
+ for (const auto& it : entries()) {
+ if (it->event_hash == hash)
+ result.push_back(it.get());
+ }
+ return result;
+}
+
+std::map<ukm::SourceId, mojom::UkmEntryPtr>
+TestUkmRecorder::GetMergedEntriesByName(base::StringPiece entry_name) const {
+ uint64_t hash = base::HashMetricName(entry_name);
+ std::map<ukm::SourceId, mojom::UkmEntryPtr> result;
+ for (const auto& it : entries()) {
+ if (it->event_hash != hash)
+ continue;
+ mojom::UkmEntryPtr& entry_ptr = result[it->source_id];
+ if (!entry_ptr)
+ entry_ptr = mojom::UkmEntry::New();
+ MergeEntry(it.get(), entry_ptr.get());
+ }
+ return result;
+}
+
+// static
+bool TestUkmRecorder::EntryHasMetric(const mojom::UkmEntry* entry,
+ base::StringPiece metric_name) {
+ return FindMetric(entry, metric_name) != nullptr;
+}
+
+void TestUkmRecorder::ExpectEntrySourceHasUrl(const mojom::UkmEntry* entry,
+ const GURL& url) const {
+ const UkmSource* src = GetSourceForSourceId(entry->source_id);
+ if (src == nullptr) {
+ FAIL() << "Entry source id has no associated Source.";
+ return;
+ }
+ EXPECT_EQ(src->url(), url);
+}
+
+// static
+const int64_t* TestUkmRecorder::GetEntryMetric(const mojom::UkmEntry* entry,
+ base::StringPiece metric_name) {
+ const mojom::UkmMetric* metric = FindMetric(entry, metric_name);
+ return metric ? &metric->value : nullptr;
+}
+
+// static
+void TestUkmRecorder::ExpectEntryMetric(const mojom::UkmEntry* entry,
+ base::StringPiece metric_name,
+ int64_t expected_value) {
+ const mojom::UkmMetric* metric = FindMetric(entry, metric_name);
+ if (metric == nullptr) {
+ FAIL() << "Failed to find metric for event: " << metric_name;
+ return;
+ }
+ EXPECT_EQ(metric->value, expected_value) << " for metric:" << metric_name;
+}
+
// static
const mojom::UkmMetric* TestUkmRecorder::FindMetric(
const mojom::UkmEntry* entry,
- const char* metric_name) {
+ base::StringPiece metric_name) {
+ uint64_t hash = base::HashMetricName(metric_name);
for (const auto& metric : entry->metrics) {
- if (metric->metric_hash == base::HashMetricName(metric_name))
+ if (metric->metric_hash == hash)
return metric.get();
}
return nullptr;
@@ -270,12 +340,12 @@ std::vector<int64_t> TestUkmRecorder::GetMetrics(
return GetMetricValues(source.id(), event_name, metric_name);
}
-TestAutoSetUkmRecorder::TestAutoSetUkmRecorder() {
- UkmRecorder::Set(this);
+TestAutoSetUkmRecorder::TestAutoSetUkmRecorder() : self_ptr_factory_(this) {
+ DelegatingUkmRecorder::Get()->AddDelegate(self_ptr_factory_.GetWeakPtr());
}
TestAutoSetUkmRecorder::~TestAutoSetUkmRecorder() {
- UkmRecorder::Set(nullptr);
+ DelegatingUkmRecorder::Get()->RemoveDelegate(this);
};
} // namespace ukm
diff --git a/chromium/components/ukm/test_ukm_recorder.h b/chromium/components/ukm/test_ukm_recorder.h
index 5bce2e87c39..0ad19b71244 100644
--- a/chromium/components/ukm/test_ukm_recorder.h
+++ b/chromium/components/ukm/test_ukm_recorder.h
@@ -14,6 +14,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "components/ukm/ukm_recorder_impl.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/interfaces/ukm_interface.mojom.h"
@@ -31,22 +32,57 @@ class TestUkmRecorder : public UkmRecorderImpl {
size_t sources_count() const { return sources().size(); }
- // Get all SourceIds with any data associated with them.
- std::set<ukm::SourceId> GetSourceIds() const;
+ size_t entries_count() const { return entries().size(); }
+ using UkmRecorderImpl::UpdateSourceURL;
+
+ // Get all recorded UkmSource data.
const std::map<ukm::SourceId, std::unique_ptr<UkmSource>>& GetSources()
const {
return sources();
}
+ // Get UkmSource data for a single SourceId.
+ const UkmSource* GetSourceForSourceId(ukm::SourceId source_id) const;
+
+ // Get all of the entries recorded for entry name.
+ std::vector<const mojom::UkmEntry*> GetEntriesByName(
+ base::StringPiece entry_name) const;
+
+ // Get the data for all entries with given entry name, merged to one entry
+ // for each source id. Intended for singular="true" metrics.
+ std::map<ukm::SourceId, mojom::UkmEntryPtr> GetMergedEntriesByName(
+ base::StringPiece entry_name) const;
+
+ // Check if an entry is associated with a url.
+ void ExpectEntrySourceHasUrl(const mojom::UkmEntry* entry,
+ const GURL& url) const;
+
+ // Expect the value of a metric from an entry.
+ static void ExpectEntryMetric(const mojom::UkmEntry* entry,
+ base::StringPiece metric_name,
+ int64_t expected_value);
+
+ // Check if an entry contains a specific metric.
+ static bool EntryHasMetric(const mojom::UkmEntry* entry,
+ base::StringPiece metric_name);
+
+ // Expect the value of a metric from an entry.
+ static const int64_t* GetEntryMetric(const mojom::UkmEntry* entry,
+ base::StringPiece metric_name);
+
+ // All of the methods below are deprecated.
+ // Use GetEntriesByName based testing instead.
+ // TODO(crbug/761524): Migrate tests and remove these.
+
+ // Get all SourceIds with any data associated with them.
+ std::set<ukm::SourceId> GetSourceIds() const;
+
const UkmSource* GetSourceForUrl(const char* url) const;
const UkmSource* GetSourceForUrl(const GURL& url) const {
return GetSourceForUrl(url.spec().c_str());
}
std::vector<const ukm::UkmSource*> GetSourcesForUrl(const char* url) const;
- const UkmSource* GetSourceForSourceId(ukm::SourceId source_id) const;
-
- size_t entries_count() const { return entries().size(); }
// Returns whether the given UKM |source| has an entry with the given
// |event_name|.
@@ -124,7 +160,7 @@ class TestUkmRecorder : public UkmRecorderImpl {
// Deprecated.
static const mojom::UkmMetric* FindMetric(const mojom::UkmEntry* entry,
- const char* metric_name);
+ base::StringPiece metric_name);
private:
ukm::mojom::UkmEntryPtr GetMergedEntryForSourceID(
@@ -144,6 +180,9 @@ class TestAutoSetUkmRecorder : public TestUkmRecorder {
public:
TestAutoSetUkmRecorder();
~TestAutoSetUkmRecorder() override;
+
+ private:
+ base::WeakPtrFactory<TestAutoSetUkmRecorder> self_ptr_factory_;
};
} // namespace ukm
diff --git a/chromium/components/ukm/ukm_interface.cc b/chromium/components/ukm/ukm_interface.cc
deleted file mode 100644
index 3cc99a25d7a..00000000000
--- a/chromium/components/ukm/ukm_interface.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/ukm/ukm_interface.h"
-
-#include "base/atomic_sequence_num.h"
-#include "base/memory/ptr_util.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "services/metrics/public/cpp/ukm_recorder.h"
-#include "services/metrics/public/cpp/ukm_source_id.h"
-#include "url/gurl.h"
-
-namespace ukm {
-
-UkmInterface::UkmInterface(UkmRecorder* ukm_recorder, int64_t instance_id)
- : ukm_recorder_(ukm_recorder), instance_id_(instance_id) {}
-
-UkmInterface::~UkmInterface() = default;
-
-// static
-void UkmInterface::Create(UkmRecorder* ukm_recorder,
- mojom::UkmRecorderInterfaceRequest request) {
- static base::AtomicSequenceNumber seq;
- mojo::MakeStrongBinding(
- base::MakeUnique<UkmInterface>(ukm_recorder,
- static_cast<int64_t>(seq.GetNext()) + 1),
- std::move(request));
-}
-
-void UkmInterface::AddEntry(mojom::UkmEntryPtr ukm_entry) {
- ukm_entry->source_id =
- ConvertSourceIdFromInstance(instance_id_, ukm_entry->source_id);
- ukm_recorder_->AddEntry(std::move(ukm_entry));
-}
-
-void UkmInterface::UpdateSourceURL(int64_t source_id, const std::string& url) {
- ukm_recorder_->UpdateSourceURL(
- ConvertSourceIdFromInstance(instance_id_, source_id), GURL(url));
-}
-
-} // namespace ukm
diff --git a/chromium/components/ukm/ukm_interface.h b/chromium/components/ukm/ukm_interface.h
deleted file mode 100644
index 9432de1fa7d..00000000000
--- a/chromium/components/ukm/ukm_interface.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_UKM_UKM_INTERFACE_H_
-#define COMPONENTS_UKM_UKM_INTERFACE_H_
-
-#include "services/metrics/public/interfaces/ukm_interface.mojom.h"
-
-namespace ukm {
-
-class UkmRecorder;
-
-class UkmInterface : public mojom::UkmRecorderInterface {
- public:
- UkmInterface(UkmRecorder* ukm_recorder, int64_t instance_id);
- ~UkmInterface() override;
-
- static void Create(UkmRecorder* ukm_recorder,
- mojom::UkmRecorderInterfaceRequest request);
-
- private:
- // ukm::mojom::UkmRecorderInterface:
- void AddEntry(mojom::UkmEntryPtr entry) override;
- void UpdateSourceURL(int64_t source_id, const std::string& url) override;
-
- UkmRecorder* ukm_recorder_;
- int64_t instance_id_;
-
- DISALLOW_COPY_AND_ASSIGN(UkmInterface);
-};
-
-} // namespace ukm
-
-#endif // COMPONENTS_UKM_UKM_INTERFACE_H_
diff --git a/chromium/components/ukm/ukm_recorder_impl.cc b/chromium/components/ukm/ukm_recorder_impl.cc
index 43adec45b40..28a5bbdf095 100644
--- a/chromium/components/ukm/ukm_recorder_impl.cc
+++ b/chromium/components/ukm/ukm_recorder_impl.cc
@@ -4,16 +4,21 @@
#include "components/ukm/ukm_recorder_impl.h"
+#include <memory>
+#include <string>
+#include <utility>
+
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/metrics_hashes.h"
#include "base/strings/string_split.h"
-#include "components/metrics/proto/ukm/entry.pb.h"
-#include "components/metrics/proto/ukm/report.pb.h"
-#include "components/metrics/proto/ukm/source.pb.h"
#include "components/ukm/ukm_source.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "third_party/metrics_proto/ukm/entry.pb.h"
+#include "third_party/metrics_proto/ukm/report.pb.h"
+#include "third_party/metrics_proto/ukm/source.pb.h"
+#include "url/gurl.h"
namespace ukm {
@@ -55,6 +60,18 @@ size_t GetMaxEntries() {
kUkmFeature, "MaxEntries", kDefaultMaxEntries));
}
+// Returns whether |url| has one of the schemes supported for logging to UKM.
+// URLs with other schemes will not be logged.
+// Note: This currently excludes chrome-extension:// URLs as in order to log
+// them, UKM needs to take into account extension-sync consent, which is not
+// yet done.
+bool HasSupportedScheme(const GURL& url) {
+ // Note: kChromeUIScheme is defined in content, which this code can't
+ // depend on - since it's used by iOS too. So "chrome" is hardcoded here.
+ return url.SchemeIsHTTPOrHTTPS() || url.SchemeIs(url::kFtpScheme) ||
+ url.SchemeIs(url::kAboutScheme) || url.SchemeIs("chrome");
+}
+
// True if we should record the initial_url field of the UKM Source proto.
bool ShouldRecordInitialUrl() {
return base::GetFieldTrialParamByFeatureAsBool(kUkmFeature,
@@ -66,6 +83,7 @@ enum class DroppedDataReason {
RECORDING_DISABLED = 1,
MAX_HIT = 2,
NOT_WHITELISTED = 3,
+ UNSUPPORTED_URL_SCHEME = 4,
NUM_DROPPED_DATA_REASONS
};
@@ -94,6 +112,18 @@ void StoreEntryProto(const mojom::UkmEntry& in, Entry* out) {
}
}
+GURL SanitizeURL(const GURL& url) {
+ GURL::Replacements remove_params;
+ remove_params.ClearUsername();
+ remove_params.ClearPassword();
+ // chrome:// and about: URLs params are never used for navigation, only to
+ // prepopulate data on the page, so don't include their params.
+ if (url.SchemeIs(url::kAboutScheme) || url.SchemeIs("chrome")) {
+ remove_params.ClearQuery();
+ }
+ return url.ReplaceComponents(remove_params);
+}
+
} // namespace
UkmRecorderImpl::UkmRecorderImpl() : recording_enabled_(false) {}
@@ -110,11 +140,14 @@ void UkmRecorderImpl::DisableRecording() {
}
void UkmRecorderImpl::Purge() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
sources_.clear();
entries_.clear();
}
void UkmRecorderImpl::StoreRecordingsInReport(Report* report) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
std::set<SourceId> ids_seen;
for (const auto& entry : entries_) {
Entry* proto_entry = report->add_entries();
@@ -172,9 +205,9 @@ bool UkmRecorderImpl::ShouldRestrictToWhitelistedSourceIds() const {
kUkmFeature, "RestrictToWhitelistedSourceIds", true);
}
-void UkmRecorderImpl::UpdateSourceURL(ukm::SourceId source_id,
- const GURL& url) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+void UkmRecorderImpl::UpdateSourceURL(SourceId source_id,
+ const GURL& unsanitized_url) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!recording_enabled_) {
RecordDroppedSource(DroppedDataReason::RECORDING_DISABLED);
@@ -187,6 +220,13 @@ void UkmRecorderImpl::UpdateSourceURL(ukm::SourceId source_id,
return;
}
+ GURL url = SanitizeURL(unsanitized_url);
+
+ if (!HasSupportedScheme(url)) {
+ RecordDroppedSource(DroppedDataReason::UNSUPPORTED_URL_SCHEME);
+ return;
+ }
+
// Update the pre-existing source if there is any. This happens when the
// initial URL is different from the committed URL for the same source, e.g.,
// when there is redirection.
@@ -206,7 +246,7 @@ void UkmRecorderImpl::UpdateSourceURL(ukm::SourceId source_id,
}
void UkmRecorderImpl::AddEntry(mojom::UkmEntryPtr entry) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!recording_enabled_) {
RecordDroppedEntry(DroppedDataReason::RECORDING_DISABLED);
@@ -227,6 +267,7 @@ void UkmRecorderImpl::AddEntry(mojom::UkmEntryPtr entry) {
}
void UkmRecorderImpl::StoreWhitelistedEntries() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const auto entries =
base::SplitString(GetWhitelistEntries(), ",", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
diff --git a/chromium/components/ukm/ukm_recorder_impl.h b/chromium/components/ukm/ukm_recorder_impl.h
index c3cdc8d254b..a24820aabde 100644
--- a/chromium/components/ukm/ukm_recorder_impl.h
+++ b/chromium/components/ukm/ukm_recorder_impl.h
@@ -9,12 +9,13 @@
#include <set>
#include <vector>
-#include "base/threading/thread_checker.h"
+#include "base/sequence_checker.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "services/metrics/public/interfaces/ukm_interface.mojom.h"
namespace metrics {
class UkmBrowserTest;
+class UkmEGTestHelper;
}
namespace ukm {
@@ -51,14 +52,16 @@ class UkmRecorderImpl : public UkmRecorder {
const std::vector<mojom::UkmEntryPtr>& entries() const { return entries_; }
+ // UkmRecorder:
+ void UpdateSourceURL(SourceId source_id, const GURL& url) override;
+
virtual bool ShouldRestrictToWhitelistedSourceIds() const;
private:
friend ::metrics::UkmBrowserTest;
+ friend ::metrics::UkmEGTestHelper;
friend ::ukm::debug::DebugPage;
- // UkmRecorder:
- void UpdateSourceURL(SourceId source_id, const GURL& url) override;
void AddEntry(mojom::UkmEntryPtr entry) override;
// Whether recording new data is currently allowed.
@@ -72,7 +75,7 @@ class UkmRecorderImpl : public UkmRecorder {
// Whitelisted Entry hashes, only the ones in this set will be recorded.
std::set<uint64_t> whitelisted_entry_hashes_;
- THREAD_CHECKER(thread_checker_);
+ SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace ukm
diff --git a/chromium/components/ukm/ukm_reporting_service.cc b/chromium/components/ukm/ukm_reporting_service.cc
index aba99ad1cea..9a7502ff9b5 100644
--- a/chromium/components/ukm/ukm_reporting_service.cc
+++ b/chromium/components/ukm/ukm_reporting_service.cc
@@ -75,6 +75,10 @@ std::string UkmReportingService::GetUploadUrl() const {
return GetServerUrl();
}
+std::string UkmReportingService::GetInsecureUploadUrl() const {
+ return "";
+}
+
base::StringPiece UkmReportingService::upload_mime_type() const {
return kMimeType;
}
@@ -90,7 +94,9 @@ void UkmReportingService::LogCellularConstraint(bool upload_canceled) {
}
void UkmReportingService::LogResponseOrErrorCode(int response_code,
- int error_code) {
+ int error_code,
+ bool was_https) {
+ // |was_https| is ignored since all UKM logs are received over HTTPS.
UMA_HISTOGRAM_SPARSE_SLOWLY("UKM.LogUpload.ResponseOrErrorCode",
response_code >= 0 ? response_code : error_code);
}
diff --git a/chromium/components/ukm/ukm_reporting_service.h b/chromium/components/ukm/ukm_reporting_service.h
index c62a5e3fdcd..a805395148e 100644
--- a/chromium/components/ukm/ukm_reporting_service.h
+++ b/chromium/components/ukm/ukm_reporting_service.h
@@ -48,10 +48,14 @@ class UkmReportingService : public metrics::ReportingService {
// metrics:ReportingService:
metrics::LogStore* log_store() override;
std::string GetUploadUrl() const override;
+ // Returns an empty string since retrying over HTTP is not enabled for UKM
+ std::string GetInsecureUploadUrl() const override;
base::StringPiece upload_mime_type() const override;
metrics::MetricsLogUploader::MetricServiceType service_type() const override;
void LogCellularConstraint(bool upload_canceled) override;
- void LogResponseOrErrorCode(int response_code, int error_code) override;
+ void LogResponseOrErrorCode(int response_code,
+ int error_code,
+ bool was_https) override;
void LogSuccess(size_t log_size) override;
void LogLargeRejection(size_t log_size) override;
diff --git a/chromium/components/ukm/ukm_service.cc b/chromium/components/ukm/ukm_service.cc
index 8a2a2e48987..aa21e48d02f 100644
--- a/chromium/components/ukm/ukm_service.cc
+++ b/chromium/components/ukm/ukm_service.cc
@@ -15,16 +15,17 @@
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "components/metrics/metrics_log.h"
#include "components/metrics/metrics_service_client.h"
-#include "components/metrics/proto/ukm/report.pb.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/ukm/persisted_logs_metrics_impl.h"
#include "components/ukm/ukm_pref_names.h"
#include "components/ukm/ukm_rotation_scheduler.h"
+#include "services/metrics/public/cpp/delegating_ukm_recorder.h"
+#include "third_party/metrics_proto/ukm/report.pb.h"
namespace ukm {
@@ -93,28 +94,28 @@ UkmService::UkmService(PrefService* pref_service,
StoreWhitelistedEntries();
- UkmRecorder::Set(this);
+ DelegatingUkmRecorder::Get()->AddDelegate(self_ptr_factory_.GetWeakPtr());
}
UkmService::~UkmService() {
DisableReporting();
- UkmRecorder::Set(nullptr);
+ DelegatingUkmRecorder::Get()->RemoveDelegate(this);
}
void UkmService::Initialize() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!initialize_started_);
DVLOG(1) << "UkmService::Initialize";
initialize_started_ = true;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::Bind(&UkmService::StartInitTask, self_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(kInitializationDelaySeconds));
}
void UkmService::EnableReporting() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::EnableReporting";
if (reporting_service_.reporting_active())
return;
@@ -128,7 +129,7 @@ void UkmService::EnableReporting() {
}
void UkmService::DisableReporting() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::DisableReporting";
reporting_service_.DisableReporting();
@@ -141,7 +142,7 @@ void UkmService::DisableReporting() {
#if defined(OS_ANDROID) || defined(OS_IOS)
void UkmService::OnAppEnterForeground() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::OnAppEnterForeground";
// If initialize_started_ is false, UKM has not yet been started, so bail. The
@@ -153,7 +154,7 @@ void UkmService::OnAppEnterForeground() {
}
void UkmService::OnAppEnterBackground() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::OnAppEnterBackground";
if (!initialize_started_)
@@ -169,14 +170,14 @@ void UkmService::OnAppEnterBackground() {
#endif
void UkmService::Flush() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (initialize_complete_)
BuildAndStoreLog();
reporting_service_.ukm_log_store()->PersistUnsentLogs();
}
void UkmService::Purge() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::Purge";
reporting_service_.ukm_log_store()->Purge();
UkmRecorderImpl::Purge();
@@ -185,6 +186,7 @@ void UkmService::Purge() {
// TODO(bmcquade): rename this to something more generic, like
// ResetClientState. Consider resetting all prefs here.
void UkmService::ResetClientId() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
client_id_ = GenerateClientId(pref_service_);
session_id_ = LoadSessionId(pref_service_);
report_count_ = 0;
@@ -203,7 +205,7 @@ void UkmService::RegisterPrefs(PrefRegistrySimple* registry) {
}
void UkmService::StartInitTask() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::StartInitTask";
client_id_ = LoadOrGenerateClientId(pref_service_);
session_id_ = LoadSessionId(pref_service_);
@@ -214,14 +216,14 @@ void UkmService::StartInitTask() {
}
void UkmService::FinishedInitTask() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::FinishedInitTask";
initialize_complete_ = true;
scheduler_->InitTaskComplete();
}
void UkmService::RotateLog() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::RotateLog";
if (!reporting_service_.ukm_log_store()->has_unsent_logs())
BuildAndStoreLog();
@@ -229,7 +231,7 @@ void UkmService::RotateLog() {
}
void UkmService::BuildAndStoreLog() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "UkmService::BuildAndStoreLog";
// Suppress generating a log if we have no new data to include.
diff --git a/chromium/components/ukm/ukm_service.h b/chromium/components/ukm/ukm_service.h
index 22b7ef5ee27..5c70a84256b 100644
--- a/chromium/components/ukm/ukm_service.h
+++ b/chromium/components/ukm/ukm_service.h
@@ -11,7 +11,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
+#include "base/sequence_checker.h"
#include "build/build_config.h"
#include "components/metrics/delegating_provider.h"
#include "components/metrics/metrics_provider.h"
@@ -25,6 +25,7 @@ class PrefService;
namespace metrics {
class MetricsServiceClient;
class UkmBrowserTest;
+class UkmEGTestHelper;
}
namespace ukm {
@@ -76,8 +77,9 @@ class UkmService : public UkmRecorderImpl {
static void RegisterPrefs(PrefRegistrySimple* registry);
private:
- friend ::ukm::debug::DebugPage;
friend ::metrics::UkmBrowserTest;
+ friend ::metrics::UkmEGTestHelper;
+ friend ::ukm::debug::DebugPage;
FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, AddEntryWithEmptyMetrics);
FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, EntryBuilderAndSerialization);
@@ -132,7 +134,7 @@ class UkmService : public UkmRecorderImpl {
// The scheduler for determining when uploads should happen.
std::unique_ptr<metrics::MetricsRotationScheduler> scheduler_;
- base::ThreadChecker thread_checker_;
+ SEQUENCE_CHECKER(sequence_checker_);
bool initialize_started_;
bool initialize_complete_;
diff --git a/chromium/components/ukm/ukm_service_unittest.cc b/chromium/components/ukm/ukm_service_unittest.cc
index 4c5b80e401c..d5437dbc719 100644
--- a/chromium/components/ukm/ukm_service_unittest.cc
+++ b/chromium/components/ukm/ukm_service_unittest.cc
@@ -17,8 +17,6 @@
#include "base/threading/platform_thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "components/metrics/proto/ukm/report.pb.h"
-#include "components/metrics/proto/ukm/source.pb.h"
#include "components/metrics/test_metrics_provider.h"
#include "components/metrics/test_metrics_service_client.h"
#include "components/prefs/testing_pref_service.h"
@@ -29,6 +27,8 @@
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_entry_builder.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/metrics_proto/ukm/report.pb.h"
+#include "third_party/metrics_proto/ukm/source.pb.h"
#include "third_party/zlib/google/compression_utils.h"
namespace ukm {
@@ -36,11 +36,11 @@ namespace ukm {
// A small shim exposing UkmRecorder methods to tests.
class TestRecordingHelper {
public:
- TestRecordingHelper(UkmRecorder* recorder) : recorder_(recorder) {}
+ explicit TestRecordingHelper(UkmRecorder* recorder) : recorder_(recorder) {}
void UpdateSourceURL(SourceId source_id, const GURL& url) {
recorder_->UpdateSourceURL(source_id, url);
- };
+ }
std::unique_ptr<UkmEntryBuilder> GetEntryBuilder(SourceId source_id,
const char* event_name) {
@@ -49,6 +49,8 @@ class TestRecordingHelper {
private:
UkmRecorder* recorder_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestRecordingHelper);
};
namespace {
@@ -668,8 +670,8 @@ TEST_F(UkmServiceTest, UnreferencedNonWhitelistedSources) {
}
ids.push_back(GetNonWhitelistedSourceId(i));
- recorder.UpdateSourceURL(
- ids.back(), GURL("https://google.com/foobar" + base::IntToString(i)));
+ recorder.UpdateSourceURL(ids.back(), GURL("https://google.com/foobar" +
+ base::NumberToString(i)));
last_time = base::TimeTicks::Now();
}
@@ -720,4 +722,116 @@ TEST_F(UkmServiceTest, UnreferencedNonWhitelistedSources) {
}
}
+TEST_F(UkmServiceTest, UnsupportedSchemes) {
+ struct {
+ const char* url;
+ bool expected_kept;
+ } test_cases[] = {
+ {"http://google.ca/", true},
+ {"https://google.ca/", true},
+ {"ftp://google.ca/", true},
+ {"about:blank", true},
+ {"chrome://version/", true},
+ {"file:///tmp/", false},
+ {"chrome-extension://bhcnanendmgjjeghamaccjnochlnhcgj", false},
+ {"abc://google.ca/", false},
+ {"www.google.ca/", false},
+ };
+
+ base::FieldTrialList field_trial_list(nullptr /* entropy_provider */);
+ ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {});
+ UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
+
+ EXPECT_EQ(GetPersistedLogCount(), 0);
+ service.Initialize();
+ task_runner_->RunUntilIdle();
+ service.EnableRecording();
+ service.EnableReporting();
+
+ int64_t id_counter = 1;
+ int expected_kept_count = 0;
+ for (const auto& test : test_cases) {
+ auto source_id = GetWhitelistedSourceId(id_counter++);
+ recorder.UpdateSourceURL(source_id, GURL(test.url));
+ recorder.GetEntryBuilder(source_id, "FakeEntry");
+ if (test.expected_kept)
+ ++expected_kept_count;
+ }
+
+ service.Flush();
+ EXPECT_EQ(GetPersistedLogCount(), 1);
+ Report proto_report = GetPersistedReport();
+
+ EXPECT_EQ(expected_kept_count, proto_report.sources_size());
+ for (const auto& test : test_cases) {
+ bool found = false;
+ for (int i = 0; i < proto_report.sources_size(); ++i) {
+ if (proto_report.sources(i).url() == test.url) {
+ found = true;
+ break;
+ }
+ }
+ EXPECT_EQ(test.expected_kept, found) << test.url;
+ }
+}
+
+TEST_F(UkmServiceTest, SanitizeUrlAuthParams) {
+ UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
+ EXPECT_EQ(0, GetPersistedLogCount());
+ service.Initialize();
+ task_runner_->RunUntilIdle();
+ service.EnableRecording();
+ service.EnableReporting();
+
+ auto id = GetWhitelistedSourceId(0);
+ recorder.UpdateSourceURL(id, GURL("https://username:password@example.com/"));
+
+ service.Flush();
+ EXPECT_EQ(1, GetPersistedLogCount());
+
+ auto proto_report = GetPersistedReport();
+ ASSERT_EQ(1, proto_report.sources_size());
+ const Source& proto_source = proto_report.sources(0);
+ EXPECT_EQ("https://example.com/", proto_source.url());
+}
+
+TEST_F(UkmServiceTest, SanitizeChromeUrlParams) {
+ struct {
+ const char* url;
+ const char* expected_url;
+ } test_cases[] = {
+ {"chrome://version/?foo=bar", "chrome://version/"},
+ {"about:blank?foo=bar", "about:blank"},
+ {"chrome://histograms/Variations", "chrome://histograms/Variations"},
+ {"http://google.ca/?foo=bar", "http://google.ca/?foo=bar"},
+ {"https://google.ca/?foo=bar", "https://google.ca/?foo=bar"},
+ {"ftp://google.ca/?foo=bar", "ftp://google.ca/?foo=bar"},
+ };
+
+ for (const auto& test : test_cases) {
+ ClearPrefs();
+
+ UkmService service(&prefs_, &client_);
+ TestRecordingHelper recorder(&service);
+ EXPECT_EQ(0, GetPersistedLogCount());
+ service.Initialize();
+ task_runner_->RunUntilIdle();
+ service.EnableRecording();
+ service.EnableReporting();
+
+ auto id = GetWhitelistedSourceId(0);
+ recorder.UpdateSourceURL(id, GURL(test.url));
+
+ service.Flush();
+ EXPECT_EQ(1, GetPersistedLogCount());
+
+ auto proto_report = GetPersistedReport();
+ ASSERT_EQ(1, proto_report.sources_size());
+ const Source& proto_source = proto_report.sources(0);
+ EXPECT_EQ(test.expected_url, proto_source.url());
+ }
+}
+
} // namespace ukm
diff --git a/chromium/components/ukm/ukm_source.cc b/chromium/components/ukm/ukm_source.cc
index 4a701495ecb..e74e05356a2 100644
--- a/chromium/components/ukm/ukm_source.cc
+++ b/chromium/components/ukm/ukm_source.cc
@@ -6,7 +6,7 @@
#include "base/atomicops.h"
#include "base/hash.h"
-#include "components/metrics/proto/ukm/source.pb.h"
+#include "third_party/metrics_proto/ukm/source.pb.h"
namespace ukm {