| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chromeos/reporting/websites/website_events_observer.h" |
| |
| #include <memory> |
| |
| #include "base/sequence_checker.h" |
| #include "chrome/browser/apps/app_service/metrics/website_metrics.h" |
| #include "chrome/browser/chromeos/reporting/metric_reporting_prefs.h" |
| #include "chrome/browser/chromeos/reporting/websites/website_metrics_retriever_interface.h" |
| #include "components/reporting/metrics/metric_event_observer.h" |
| #include "components/reporting/metrics/reporting_settings.h" |
| #include "components/reporting/proto/synced/metric_data.pb.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/web_contents.h" |
| #include "url/gurl.h" |
| |
| namespace reporting { |
| |
| WebsiteEventsObserver::WebsiteEventsObserver( |
| std::unique_ptr<WebsiteMetricsRetrieverInterface> website_metrics_retriever, |
| const ReportingSettings* reporting_settings) |
| : website_metrics_retriever_(std::move(website_metrics_retriever)), |
| reporting_settings_(reporting_settings) { |
| CHECK(website_metrics_retriever_); |
| website_metrics_retriever_->GetWebsiteMetrics( |
| base::BindOnce(&WebsiteEventsObserver::InitEventObserver, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| WebsiteEventsObserver::~WebsiteEventsObserver() = default; |
| |
| void WebsiteEventsObserver::SetOnEventObservedCallback( |
| MetricRepeatingCallback callback) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| CHECK(!on_metric_observed_) << "Observer callback already set"; |
| on_metric_observed_ = std::move(callback); |
| } |
| |
| void WebsiteEventsObserver::SetReportingEnabled(bool is_enabled) { |
| // Do nothing. We retrieve the reporting setting and validate the website URL |
| // is allowlisted before we report an observed event. |
| } |
| |
| void WebsiteEventsObserver::OnUrlOpened(const GURL& url_opened, |
| ::content::WebContents* web_contents) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| if (!IsWebsiteUrlAllowlisted(url_opened, reporting_settings_, |
| kReportWebsiteActivityAllowlist)) { |
| return; |
| } |
| |
| MetricData metric_data; |
| metric_data.mutable_event_data()->set_type(MetricEventType::URL_OPENED); |
| |
| auto* const website_opened_data = metric_data.mutable_telemetry_data() |
| ->mutable_website_telemetry() |
| ->mutable_website_opened_data(); |
| website_opened_data->set_url(url_opened.spec()); |
| website_opened_data->set_render_process_host_id( |
| web_contents->GetRenderViewHost()->GetProcess()->GetDeprecatedID()); |
| website_opened_data->set_render_frame_routing_id( |
| web_contents->GetRenderViewHost()->GetRoutingID()); |
| |
| on_metric_observed_.Run(std::move(metric_data)); |
| } |
| |
| void WebsiteEventsObserver::OnUrlClosed(const GURL& url_closed, |
| ::content::WebContents* web_contents) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| if (!IsWebsiteUrlAllowlisted(url_closed, reporting_settings_, |
| kReportWebsiteActivityAllowlist)) { |
| return; |
| } |
| |
| MetricData metric_data; |
| metric_data.mutable_event_data()->set_type(MetricEventType::URL_CLOSED); |
| |
| auto* const website_closed_data = metric_data.mutable_telemetry_data() |
| ->mutable_website_telemetry() |
| ->mutable_website_closed_data(); |
| website_closed_data->set_url(url_closed.spec()); |
| website_closed_data->set_render_process_host_id( |
| web_contents->GetRenderViewHost()->GetProcess()->GetDeprecatedID()); |
| website_closed_data->set_render_frame_routing_id( |
| web_contents->GetRenderViewHost()->GetRoutingID()); |
| |
| on_metric_observed_.Run(std::move(metric_data)); |
| } |
| |
| void WebsiteEventsObserver::InitEventObserver( |
| ::apps::WebsiteMetrics* website_metrics) { |
| // Runs on the same sequence as the website metrics retriever because they |
| // both use the UI thread. |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| if (!website_metrics) { |
| // This can happen if the `WebsiteMetrics` component initialization |
| // failed (for example, component was destructed). We just abort |
| // initialization of the event observer when this happens. |
| return; |
| } |
| observer_.Observe(website_metrics); |
| } |
| |
| void WebsiteEventsObserver::OnWebsiteMetricsDestroyed() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| observer_.Reset(); |
| } |
| |
| } // namespace reporting |