Upload upstream chromium 71.0.3578.0
[platform/framework/web/chromium-efl.git] / components / ukm / ukm_recorder_impl.h
1 // Copyright 2017 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 #ifndef COMPONENTS_UKM_UKM_RECORDER_IMPL_H_
6 #define COMPONENTS_UKM_UKM_RECORDER_IMPL_H_
7
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <unordered_set>
13 #include <vector>
14
15 #include "base/callback_forward.h"
16 #include "base/containers/flat_map.h"
17 #include "base/sequence_checker.h"
18 #include "base/strings/string_piece.h"
19 #include "services/metrics/public/cpp/ukm_decode.h"
20 #include "services/metrics/public/cpp/ukm_recorder.h"
21 #include "services/metrics/public/mojom/ukm_interface.mojom.h"
22
23 namespace metrics {
24 class UkmBrowserTestBase;
25 class UkmEGTestHelper;
26 }
27
28 namespace ukm {
29 class Report;
30 class UkmSource;
31 class UkmUtilsForTest;
32
33 namespace debug {
34 class UkmDebugDataExtractor;
35 }
36
37 class UkmRecorderImpl : public UkmRecorder {
38   using IsWebstoreExtensionCallback =
39       base::RepeatingCallback<bool(base::StringPiece id)>;
40
41  public:
42   UkmRecorderImpl();
43   ~UkmRecorderImpl() override;
44
45   // Unconditionally attempts to create a field trial to control client side
46   // metrics/crash sampling to use as a fallback when one hasn't been
47   // provided. This is expected to occur on first-run on platforms that don't
48   // have first-run variations support. This should only be called when there is
49   // no existing field trial controlling the sampling feature.
50   static void CreateFallbackSamplingTrial(bool is_stable_channel,
51                                           base::FeatureList* feature_list);
52
53   // Enables/disables recording control if data is allowed to be collected. The
54   // |extensions| flag separately controls recording of chrome-extension://
55   // URLs; this flag should reflect the "sync extensions" user setting.
56   void EnableRecording(bool extensions);
57   void DisableRecording();
58
59   // Disables sampling for testing purposes.
60   void DisableSamplingForTesting() override;
61
62   // Deletes stored recordings.
63   void Purge();
64
65   // Sets a callback for determining if an extension URL can be recorded.
66   void SetIsWebstoreExtensionCallback(
67       const IsWebstoreExtensionCallback& callback);
68
69  protected:
70   // Cache the list of whitelisted entries from the field trial parameter.
71   void StoreWhitelistedEntries();
72
73   // Writes recordings into a report proto, and clears recordings.
74   void StoreRecordingsInReport(Report* report);
75
76   const std::map<SourceId, std::unique_ptr<UkmSource>>& sources() const {
77     return recordings_.sources;
78   }
79
80   const std::vector<mojom::UkmEntryPtr>& entries() const {
81     return recordings_.entries;
82   }
83
84   // UkmRecorder:
85   void AddEntry(mojom::UkmEntryPtr entry) override;
86   void UpdateSourceURL(SourceId source_id, const GURL& url) override;
87   void UpdateAppURL(SourceId source_id, const GURL& url) override;
88   void RecordNavigation(
89       SourceId source_id,
90       const UkmSource::NavigationData& navigation_data) override;
91   using UkmRecorder::RecordOtherURL;
92
93   virtual bool ShouldRestrictToWhitelistedSourceIds() const;
94
95   virtual bool ShouldRestrictToWhitelistedEntries() const;
96
97  private:
98   friend ::metrics::UkmBrowserTestBase;
99   friend ::metrics::UkmEGTestHelper;
100   friend ::ukm::debug::UkmDebugDataExtractor;
101   friend ::ukm::UkmUtilsForTest;
102
103   struct MetricAggregate {
104     uint64_t total_count = 0;
105     double value_sum = 0;
106     double value_square_sum = 0.0;
107     uint64_t dropped_due_to_limits = 0;
108     uint64_t dropped_due_to_sampling = 0;
109     uint64_t dropped_due_to_whitelist = 0;
110   };
111
112   struct EventAggregate {
113     EventAggregate();
114     ~EventAggregate();
115
116     base::flat_map<uint64_t, MetricAggregate> metrics;
117     uint64_t total_count = 0;
118     uint64_t dropped_due_to_limits = 0;
119     uint64_t dropped_due_to_sampling = 0;
120     uint64_t dropped_due_to_whitelist = 0;
121   };
122
123   using MetricAggregateMap = std::map<uint64_t, MetricAggregate>;
124
125   // Returns true if |sanitized_url| should be recorded.
126   bool ShouldRecordUrl(SourceId source_id, const GURL& sanitized_url) const;
127
128   void RecordSource(std::unique_ptr<UkmSource> source);
129
130   // Load sampling configurations from field-trial information.
131   void LoadExperimentSamplingInfo();
132
133   // Whether recording new data is currently allowed.
134   bool recording_enabled_ = false;
135
136   // Indicates whether recording is enabled for extensions.
137   bool extensions_enabled_ = false;
138
139   // Indicates whether recording continuity has been broken since last report.
140   bool recording_is_continuous_ = true;
141
142   // Indicates if sampling has been enabled.
143   bool sampling_enabled_ = true;
144
145   // Callback for checking extension IDs.
146   IsWebstoreExtensionCallback is_webstore_extension_callback_;
147
148   // Map from hashes to entry and metric names.
149   ukm::builders::DecodeMap decode_map_;
150
151   // Whitelisted Entry hashes, only the ones in this set will be recorded.
152   std::set<uint64_t> whitelisted_entry_hashes_;
153
154   // Sampling configurations, loaded from a field-trial.
155   int default_sampling_rate_ = 0;
156   base::flat_map<uint64_t, int> event_sampling_rates_;
157
158   // Contains data from various recordings which periodically get serialized
159   // and cleared by StoreRecordingsInReport() and may be Purged().
160   struct Recordings {
161     Recordings();
162     Recordings& operator=(Recordings&&);
163     ~Recordings();
164
165     // Data captured by UpdateSourceUrl().
166     std::map<SourceId, std::unique_ptr<UkmSource>> sources;
167
168     // Data captured by AddEntry().
169     std::vector<mojom::UkmEntryPtr> entries;
170
171     // URLs of sources that matched a whitelist url, but were not included in
172     // the report generated by the last log rotation because we haven't seen any
173     // events for that source yet.
174     std::unordered_set<std::string> carryover_urls_whitelist;
175
176     // Aggregate information for collected event metrics.
177     std::map<uint64_t, EventAggregate> event_aggregations;
178
179     // Aggregated counters about Sources recorded in the current log.
180     struct SourceCounts {
181       // Count of URLs recorded for all sources.
182       size_t observed = 0;
183       // Count of URLs recorded for all SourceIdType::NAVIGATION_ID Sources.
184       size_t navigation_sources = 0;
185       // Sources carried over (not recorded) from a previous logging rotation.
186       size_t carryover_sources = 0;
187
188       // Resets all of the data.
189       void Reset();
190     };
191     SourceCounts source_counts;
192
193     // Resets all of the data.
194     void Reset();
195   };
196   Recordings recordings_;
197
198   SEQUENCE_CHECKER(sequence_checker_);
199 };
200
201 }  // namespace ukm
202
203 #endif  // COMPONENTS_UKM_UKM_RECORDER_IMPL_H_