[M73 Dev][EFL] Disable VizDisplayCompositor for EFL port
[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 UkmRecorderImplTest;
31 class UkmSource;
32 class UkmUtilsForTest;
33
34 namespace debug {
35 class UkmDebugDataExtractor;
36 }
37
38 class UkmRecorderImpl : public UkmRecorder {
39   using IsWebstoreExtensionCallback =
40       base::RepeatingCallback<bool(base::StringPiece id)>;
41
42  public:
43   UkmRecorderImpl();
44   ~UkmRecorderImpl() override;
45
46   // Unconditionally attempts to create a field trial to control client side
47   // metrics/crash sampling to use as a fallback when one hasn't been
48   // provided. This is expected to occur on first-run on platforms that don't
49   // have first-run variations support. This should only be called when there is
50   // no existing field trial controlling the sampling feature.
51   static void CreateFallbackSamplingTrial(bool is_stable_channel,
52                                           base::FeatureList* feature_list);
53
54   // Enables/disables recording control if data is allowed to be collected. The
55   // |extensions| flag separately controls recording of chrome-extension://
56   // URLs; this flag should reflect the "sync extensions" user setting.
57   void EnableRecording(bool extensions);
58   void DisableRecording();
59
60   // Disables sampling for testing purposes.
61   void DisableSamplingForTesting() override;
62
63   // Deletes stored recordings.
64   void Purge();
65
66   // Sets a callback for determining if an extension URL can be recorded.
67   void SetIsWebstoreExtensionCallback(
68       const IsWebstoreExtensionCallback& callback);
69
70  protected:
71   // Calculates sampled in/out based on a given |rate|. This is virtual so
72   // it can be overriden by tests.
73   virtual bool IsSampledIn(int sampling_rate);
74
75   // Cache the list of whitelisted entries from the field trial parameter.
76   void StoreWhitelistedEntries();
77
78   // Writes recordings into a report proto, and clears recordings.
79   void StoreRecordingsInReport(Report* report);
80
81   const std::map<SourceId, std::unique_ptr<UkmSource>>& sources() const {
82     return recordings_.sources;
83   }
84
85   const std::vector<mojom::UkmEntryPtr>& entries() const {
86     return recordings_.entries;
87   }
88
89   // UkmRecorder:
90   void AddEntry(mojom::UkmEntryPtr entry) override;
91   void UpdateSourceURL(SourceId source_id, const GURL& url) override;
92   void UpdateAppURL(SourceId source_id, const GURL& url) override;
93   void RecordNavigation(
94       SourceId source_id,
95       const UkmSource::NavigationData& navigation_data) override;
96   using UkmRecorder::RecordOtherURL;
97
98   virtual bool ShouldRestrictToWhitelistedSourceIds() const;
99
100   virtual bool ShouldRestrictToWhitelistedEntries() const;
101
102  private:
103   friend ::metrics::UkmBrowserTestBase;
104   friend ::metrics::UkmEGTestHelper;
105   friend ::ukm::debug::UkmDebugDataExtractor;
106   friend ::ukm::UkmRecorderImplTest;
107   friend ::ukm::UkmUtilsForTest;
108
109   struct MetricAggregate {
110     uint64_t total_count = 0;
111     double value_sum = 0;
112     double value_square_sum = 0.0;
113     uint64_t dropped_due_to_limits = 0;
114     uint64_t dropped_due_to_sampling = 0;
115     uint64_t dropped_due_to_whitelist = 0;
116   };
117
118   struct EventAggregate {
119     EventAggregate();
120     ~EventAggregate();
121
122     base::flat_map<uint64_t, MetricAggregate> metrics;
123     uint64_t total_count = 0;
124     uint64_t dropped_due_to_limits = 0;
125     uint64_t dropped_due_to_sampling = 0;
126     uint64_t dropped_due_to_whitelist = 0;
127   };
128
129   // Container for sampling in/out choices for events within a single page
130   // load. This is important because some events are emitted multiple times
131   // with different metric values that are expected to be grouped together.
132   // For example, Blink.UseCounter is emitted for *all* used blink features
133   // on a page so its important that this metric either be on or off for
134   // the entire page. The sampling of different events is calculated
135   // independently (i.e. it can't be assumed that because one type of event
136   // is sampled-in that another will be sample-in or sampled-out) but always
137   // remembered for the entire page.
138   class PageSampling {
139    public:
140     PageSampling();
141     ~PageSampling();
142
143     // Sets the sampled-in flag for a given |event_id|.
144     void Set(uint64_t event_id, bool sampled_in);
145
146     // Returns if there is already a flag for a given |event_id|. The value
147     // of that flag is stored in |out_sampled_in|;
148     bool Find(uint64_t event_id, bool* out_sampled_in) const;
149
150     // Returns if this record has been modified.
151     bool modified() const { return modified_; }
152
153     // Clears the |modified_| flag.
154     void clear_modified() { modified_ = false; }
155
156    private:
157     // Per-event boolean indicating sampled-in for this page, keyed by event_id.
158     std::map<uint64_t, bool> event_sampling_;
159
160     // Boolean indicating if this has been modified, used to clear out old
161     // entries so they don't continue to use memory. "Modified" means Set()
162     // has been called since the last time clear_modified() was called
163     // (currently at every upload of UKM data).
164     bool modified_ = false;
165
166     DISALLOW_COPY_AND_ASSIGN(PageSampling);
167   };
168
169   using MetricAggregateMap = std::map<uint64_t, MetricAggregate>;
170
171   // Returns true if |sanitized_url| should be recorded.
172   bool ShouldRecordUrl(SourceId source_id, const GURL& sanitized_url) const;
173
174   void RecordSource(std::unique_ptr<UkmSource> source);
175
176   // Load sampling configurations from field-trial information.
177   void LoadExperimentSamplingInfo();
178
179   // Whether recording new data is currently allowed.
180   bool recording_enabled_ = false;
181
182   // Indicates whether recording is enabled for extensions.
183   bool extensions_enabled_ = false;
184
185   // Indicates whether recording continuity has been broken since last report.
186   bool recording_is_continuous_ = true;
187
188   // Indicates if sampling has been enabled.
189   bool sampling_enabled_ = true;
190
191   // Callback for checking extension IDs.
192   IsWebstoreExtensionCallback is_webstore_extension_callback_;
193
194   // Map from hashes to entry and metric names.
195   ukm::builders::DecodeMap decode_map_;
196
197   // Whitelisted Entry hashes, only the ones in this set will be recorded.
198   std::set<uint64_t> whitelisted_entry_hashes_;
199
200   // Sampling configurations, loaded from a field-trial.
201   int default_sampling_rate_ = 0;
202   base::flat_map<uint64_t, int> event_sampling_rates_;
203
204   // Result of sampling calculation per event for a source/page. This is
205   // cleared at the start of each page load and ensure that that all events
206   // within a page will be included or excluded together.
207   std::map<int64_t, PageSampling> source_event_sampling_;
208
209   // Contains data from various recordings which periodically get serialized
210   // and cleared by StoreRecordingsInReport() and may be Purged().
211   struct Recordings {
212     Recordings();
213     Recordings& operator=(Recordings&&);
214     ~Recordings();
215
216     // Data captured by UpdateSourceUrl().
217     std::map<SourceId, std::unique_ptr<UkmSource>> sources;
218
219     // Data captured by AddEntry().
220     std::vector<mojom::UkmEntryPtr> entries;
221
222     // URLs of sources that matched a whitelist url, but were not included in
223     // the report generated by the last log rotation because we haven't seen any
224     // events for that source yet.
225     std::unordered_set<std::string> carryover_urls_whitelist;
226
227     // Aggregate information for collected event metrics.
228     std::map<uint64_t, EventAggregate> event_aggregations;
229
230     // Aggregated counters about Sources recorded in the current log.
231     struct SourceCounts {
232       // Count of URLs recorded for all sources.
233       size_t observed = 0;
234       // Count of URLs recorded for all SourceIdType::NAVIGATION_ID Sources.
235       size_t navigation_sources = 0;
236       // Sources carried over (not recorded) from a previous logging rotation.
237       size_t carryover_sources = 0;
238
239       // Resets all of the data.
240       void Reset();
241     };
242     SourceCounts source_counts;
243
244     // Resets all of the data.
245     void Reset();
246   };
247   Recordings recordings_;
248
249   SEQUENCE_CHECKER(sequence_checker_);
250 };
251
252 }  // namespace ukm
253
254 #endif  // COMPONENTS_UKM_UKM_RECORDER_IMPL_H_