blob: bae47e353ca9fb0f26c83ad00388b40d4b4cb33a [file] [log] [blame]
sside08673f12022-03-10 07:40:591// Copyright 2022 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "components/segmentation_platform/internal/signals/ukm_observer.h"
6
7#include <cstdint>
8
9#include "base/rand_util.h"
10#include "base/time/time.h"
11#include "components/segmentation_platform/internal/database/ukm_database.h"
12#include "components/segmentation_platform/internal/signals/ukm_config.h"
13#include "components/segmentation_platform/internal/signals/url_signal_handler.h"
14#include "components/ukm/ukm_recorder_impl.h"
15#include "services/metrics/public/mojom/ukm_interface.mojom.h"
16
17namespace segmentation_platform {
18
19UkmObserver::UkmObserver(ukm::UkmRecorderImpl* ukm_recorder,
20 UkmDatabase* ukm_database,
21 UrlSignalHandler* url_signal_handler)
22 : ukm_database_(ukm_database),
23 url_signal_handler_(url_signal_handler),
24 ukm_recorder_(ukm_recorder) {}
25
26UkmObserver::~UkmObserver() {
27 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_check_);
28 if (config_)
29 ukm_recorder_->RemoveUkmRecorderObserver(this);
30}
31
32void UkmObserver::StartObserving(const UkmConfig& config) {
33 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_check_);
34
35 bool was_observing = true;
36 if (!config_) {
37 config_ = std::make_unique<UkmConfig>();
38 was_observing = false;
39 }
40
41 UkmConfig::MergeResult result = config_->Merge(config);
42 if (result == UkmConfig::NO_NEW_EVENT)
43 return;
44
45 if (was_observing)
46 ukm_recorder_->RemoveUkmRecorderObserver(this);
47 ukm_recorder_->AddUkmRecorderObserver(config_->GetRawObservedEvents(), this);
48}
49
50void UkmObserver::OnEntryAdded(ukm::mojom::UkmEntryPtr entry) {
51 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_check_);
52 if (paused_)
53 return;
54
55 // Remove any metric from the entry that is not observed.
56 const base::flat_set<UkmMetricHash>* metrics_for_event =
57 config_->GetObservedMetrics(
58 UkmEventHash::FromUnsafeValue(entry->event_hash));
59 if (!metrics_for_event)
60 return;
61 for (const auto& metric_and_value : entry->metrics) {
62 if (!metrics_for_event->count(
63 UkmMetricHash::FromUnsafeValue(metric_and_value.first))) {
64 entry->metrics.erase(metric_and_value);
65 }
66 }
67 ukm_database_->UkmEntryAdded(std::move(entry));
68}
69
70void UkmObserver::OnUpdateSourceURL(ukm::SourceId source_id,
71 const std::vector<GURL>& urls) {
72 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_check_);
73 if (paused_)
74 return;
75
76 url_signal_handler_->OnUkmSourceUpdated(source_id, urls);
77}
78
79void UkmObserver::PauseOrResumeObservation(bool pause) {
80 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_check_);
81 paused_ = pause;
82}
83
84} // namespace segmentation_platform