123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- // Copyright 2022 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/browsing_topics/browsing_topics_page_load_data_tracker.h"
- #include "components/browsing_topics/util.h"
- #include "components/history/content/browser/history_context_helper.h"
- #include "components/history/core/browser/history_service.h"
- #include "content/public/browser/browsing_topics_site_data_manager.h"
- #include "content/public/browser/navigation_entry.h"
- #include "content/public/browser/render_frame_host.h"
- #include "content/public/browser/render_process_host.h"
- #include "content/public/browser/storage_partition.h"
- #include "content/public/browser/web_contents.h"
- #include "services/metrics/public/cpp/metrics_utils.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"
- #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
- namespace browsing_topics {
- // Max number of context domains to keep track of per page load to limit in-use
- // memory. This should also be greater than
- // `kBrowsingTopicsMaxNumberOfApiUsageContextDomainsToStorePerPageLoad`.
- constexpr int kMaxNumberOfContextDomainsToMonitor = 1000;
- BrowsingTopicsPageLoadDataTracker::~BrowsingTopicsPageLoadDataTracker() {
- if (observed_hashed_context_domains_.empty())
- return;
- // TODO(yaoxia): consider also recording metrics when the Chrome app goes into
- // background, in which case the destructor may never be called.
- ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
- ukm::builders::BrowsingTopics_PageLoad builder(source_id_);
- builder.SetTopicsRequestingContextDomainsCount(
- ukm::GetExponentialBucketMinForCounts1000(
- observed_hashed_context_domains_.size()));
- builder.Record(ukm_recorder->Get());
- }
- BrowsingTopicsPageLoadDataTracker::BrowsingTopicsPageLoadDataTracker(
- content::Page& page)
- : content::PageUserData<BrowsingTopicsPageLoadDataTracker>(page),
- hashed_main_frame_host_(HashMainFrameHostForStorage(
- page.GetMainDocument().GetLastCommittedOrigin().host())),
- source_id_(page.GetMainDocument().GetPageUkmSourceId()) {
- DCHECK(page.IsPrimary());
- // TODO(yaoxia): consider dropping the permissions policy checks. We require
- // that the API is used in the page, and that already implies that the
- // permissions policy is allowed.
- if ((page.GetMainDocument().IsLastCommitIPAddressPubliclyRoutable() ||
- base::FeatureList::IsEnabled(
- blink::features::kBrowsingTopicsBypassIPIsPubliclyRoutableCheck)) &&
- page.GetMainDocument().IsFeatureEnabled(
- blink::mojom::PermissionsPolicyFeature::kBrowsingTopics) &&
- page.GetMainDocument().IsFeatureEnabled(
- blink::mojom::PermissionsPolicyFeature::
- kBrowsingTopicsBackwardCompatible)) {
- eligible_to_commit_ = true;
- }
- }
- void BrowsingTopicsPageLoadDataTracker::OnBrowsingTopicsApiUsed(
- const HashedDomain& hashed_context_domain,
- history::HistoryService* history_service) {
- if (!eligible_to_commit_)
- return;
- // On the first API usage in the page, set the allowed bit in history.
- if (observed_hashed_context_domains_.empty()) {
- content::WebContents* web_contents =
- content::WebContents::FromRenderFrameHost(&page().GetMainDocument());
- history_service->SetBrowsingTopicsAllowed(
- history::ContextIDForWebContents(web_contents),
- web_contents->GetController().GetLastCommittedEntry()->GetUniqueID(),
- web_contents->GetLastCommittedURL());
- }
- DCHECK_LE(
- blink::features::
- kBrowsingTopicsMaxNumberOfApiUsageContextDomainsToStorePerPageLoad
- .Get(),
- kMaxNumberOfContextDomainsToMonitor);
- // Cap the number of context domains to keep track of per page load to limit
- // in-use memory.
- if (observed_hashed_context_domains_.size() >=
- kMaxNumberOfContextDomainsToMonitor) {
- return;
- }
- bool is_new_domain =
- observed_hashed_context_domains_.insert(hashed_context_domain).second;
- // Ignore this context if we've already added it.
- if (!is_new_domain)
- return;
- // Cap the number of context domains to store to disk per page load to limit
- // disk memory usage.
- if (observed_hashed_context_domains_.size() >
- static_cast<size_t>(
- blink::features::
- kBrowsingTopicsMaxNumberOfApiUsageContextDomainsToStorePerPageLoad
- .Get())) {
- return;
- }
- // Persist the usage now rather than at the end of the page load, as when the
- // app enters background, it may be killed without further notification.
- page()
- .GetMainDocument()
- .GetProcess()
- ->GetStoragePartition()
- ->GetBrowsingTopicsSiteDataManager()
- ->OnBrowsingTopicsApiUsed(hashed_main_frame_host_,
- {hashed_context_domain}, base::Time::Now());
- }
- PAGE_USER_DATA_KEY_IMPL(BrowsingTopicsPageLoadDataTracker);
- } // namespace browsing_topics
|