[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / tracing / background_tracing_rule.cc
blobb32e0b13740af00432db09121f95ee690b092e52
1 // Copyright 2015 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 #include "content/browser/tracing/background_tracing_rule.h"
6 #include <string>
8 #include "base/bind.h"
9 #include "base/metrics/histogram_macros.h"
10 #include "base/metrics/statistics_recorder.h"
11 #include "base/rand_util.h"
12 #include "base/strings/safe_sprintf.h"
13 #include "base/values.h"
14 #include "components/tracing/tracing_messages.h"
15 #include "content/browser/tracing/background_tracing_manager_impl.h"
16 #include "content/browser/tracing/trace_message_filter.h"
17 #include "content/public/browser/browser_thread.h"
19 namespace {
21 const char kConfigRuleKey[] = "rule";
22 const char kConfigCategoryKey[] = "category";
23 const char kConfigRuleTriggerNameKey[] = "trigger_name";
25 const char kConfigRuleHistogramNameKey[] = "histogram_name";
26 const char kConfigRuleHistogramValueKey[] = "histogram_value";
28 const char kConfigRuleRandomIntervalTimeoutMin[] = "timeout_min";
29 const char kConfigRuleRandomIntervalTimeoutMax[] = "timeout_max";
31 const char kPreemptiveConfigRuleMonitorNamed[] =
32 "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED";
34 const char kPreemptiveConfigRuleMonitorHistogram[] =
35 "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE";
37 const char kReactiveConfigRuleTraceOnNavigationUntilTriggerOrFull[] =
38 "TRACE_ON_NAVIGATION_UNTIL_TRIGGER_OR_FULL";
40 const char kReactiveConfigRuleTraceAtRandomIntervals[] =
41 "TRACE_AT_RANDOM_INTERVALS";
43 const char kTraceAtRandomIntervalsEventName[] =
44 "ReactiveTraceAtRandomIntervals";
46 const int kReactiveConfigNavigationTimeout = 30;
47 const int kReactiveTraceRandomStartTimeMin = 60;
48 const int kReactiveTraceRandomStartTimeMax = 120;
50 } // namespace
52 namespace content {
54 BackgroundTracingRule::BackgroundTracingRule() {}
56 BackgroundTracingRule::~BackgroundTracingRule() {}
58 bool BackgroundTracingRule::ShouldTriggerNamedEvent(
59 const std::string& named_event) const {
60 return false;
63 BackgroundTracingConfigImpl::CategoryPreset
64 BackgroundTracingRule::GetCategoryPreset() const {
65 return BackgroundTracingConfigImpl::BENCHMARK;
68 namespace {
70 class NamedTriggerRule : public BackgroundTracingRule {
71 public:
72 NamedTriggerRule(const std::string& named_event)
73 : named_event_(named_event) {}
75 void IntoDict(base::DictionaryValue* dict) const override {
76 DCHECK(dict);
77 dict->SetString(kConfigRuleKey, kPreemptiveConfigRuleMonitorNamed);
78 dict->SetString(kConfigRuleTriggerNameKey, named_event_.c_str());
81 bool ShouldTriggerNamedEvent(const std::string& named_event) const override {
82 return named_event == named_event_;
85 private:
86 std::string named_event_;
89 class HistogramRule : public BackgroundTracingRule,
90 public TracingControllerImpl::TraceMessageFilterObserver {
91 public:
92 HistogramRule(const std::string& histogram_name, int histogram_value)
93 : histogram_name_(histogram_name), histogram_value_(histogram_value) {}
95 ~HistogramRule() override {
96 base::StatisticsRecorder::ClearCallback(histogram_name_);
97 TracingControllerImpl::GetInstance()->RemoveTraceMessageFilterObserver(
98 this);
101 // BackgroundTracingRule implementation
102 void Install() override {
103 base::StatisticsRecorder::SetCallback(
104 histogram_name_,
105 base::Bind(&HistogramRule::OnHistogramChangedCallback,
106 base::Unretained(this), histogram_name_, histogram_value_));
108 TracingControllerImpl::GetInstance()->AddTraceMessageFilterObserver(this);
111 void IntoDict(base::DictionaryValue* dict) const override {
112 DCHECK(dict);
113 dict->SetString(kConfigRuleKey, kPreemptiveConfigRuleMonitorHistogram);
114 dict->SetString(kConfigRuleHistogramNameKey, histogram_name_.c_str());
115 dict->SetInteger(kConfigRuleHistogramValueKey, histogram_value_);
118 void OnHistogramTrigger(const std::string& histogram_name) const override {
119 if (histogram_name != histogram_name_)
120 return;
122 content::BrowserThread::PostTask(
123 content::BrowserThread::UI, FROM_HERE,
124 base::Bind(
125 &BackgroundTracingManagerImpl::TriggerPreemptiveFinalization,
126 base::Unretained(BackgroundTracingManagerImpl::GetInstance())));
129 // TracingControllerImpl::TraceMessageFilterObserver implementation
130 void OnTraceMessageFilterAdded(TraceMessageFilter* filter) override {
131 filter->Send(
132 new TracingMsg_SetUMACallback(histogram_name_, histogram_value_));
135 void OnTraceMessageFilterRemoved(TraceMessageFilter* filter) override {
136 filter->Send(new TracingMsg_ClearUMACallback(histogram_name_));
139 void OnHistogramChangedCallback(const std::string& histogram_name,
140 base::Histogram::Sample reference_value,
141 base::Histogram::Sample actual_value) {
142 if (reference_value > actual_value)
143 return;
145 OnHistogramTrigger(histogram_name);
148 private:
149 std::string histogram_name_;
150 int histogram_value_;
153 class ReactiveTraceForNSOrTriggerOrFullRule : public BackgroundTracingRule {
154 public:
155 ReactiveTraceForNSOrTriggerOrFullRule(
156 const std::string& named_event,
157 BackgroundTracingConfigImpl::CategoryPreset category_preset)
158 : named_event_(named_event), category_preset_(category_preset) {}
160 // BackgroundTracingRule implementation
161 void IntoDict(base::DictionaryValue* dict) const override {
162 DCHECK(dict);
163 dict->SetString(
164 kConfigCategoryKey,
165 BackgroundTracingConfigImpl::CategoryPresetToString(category_preset_));
166 dict->SetString(kConfigRuleKey,
167 kReactiveConfigRuleTraceOnNavigationUntilTriggerOrFull);
168 dict->SetString(kConfigRuleTriggerNameKey, named_event_.c_str());
171 bool ShouldTriggerNamedEvent(const std::string& named_event) const override {
172 return named_event == named_event_;
175 int GetReactiveTimeout() const override {
176 return kReactiveConfigNavigationTimeout;
179 BackgroundTracingConfigImpl::CategoryPreset GetCategoryPreset()
180 const override {
181 return category_preset_;
184 private:
185 std::string named_event_;
186 BackgroundTracingConfigImpl::CategoryPreset category_preset_;
189 class ReactiveTraceAtRandomIntervalsRule : public BackgroundTracingRule {
190 public:
191 ReactiveTraceAtRandomIntervalsRule(
192 BackgroundTracingConfigImpl::CategoryPreset category_preset,
193 int timeout_min,
194 int timeout_max)
195 : category_preset_(category_preset),
196 timeout_min_(timeout_min),
197 timeout_max_(timeout_max) {
198 named_event_ = GenerateUniqueName();
201 ~ReactiveTraceAtRandomIntervalsRule() override {}
203 void IntoDict(base::DictionaryValue* dict) const override {
204 DCHECK(dict);
205 dict->SetString(
206 kConfigCategoryKey,
207 BackgroundTracingConfigImpl::CategoryPresetToString(category_preset_));
208 dict->SetString(kConfigRuleKey, kReactiveConfigRuleTraceAtRandomIntervals);
209 dict->SetInteger(kConfigRuleRandomIntervalTimeoutMin, timeout_min_);
210 dict->SetInteger(kConfigRuleRandomIntervalTimeoutMax, timeout_max_);
213 void Install() override {
214 handle_ = BackgroundTracingManagerImpl::GetInstance()->RegisterTriggerType(
215 named_event_.c_str());
217 StartTimer();
220 void OnStartedFinalizing(bool success) {
221 if (!success)
222 return;
224 StartTimer();
227 void OnTriggerTimer() {
228 BackgroundTracingManagerImpl::GetInstance()->TriggerNamedEvent(
229 handle_,
230 base::Bind(&ReactiveTraceAtRandomIntervalsRule::OnStartedFinalizing,
231 base::Unretained(this)));
234 void StartTimer() {
235 int time_to_wait = base::RandInt(kReactiveTraceRandomStartTimeMin,
236 kReactiveTraceRandomStartTimeMax);
237 trigger_timer_.Start(
238 FROM_HERE, base::TimeDelta::FromSeconds(time_to_wait),
239 base::Bind(&ReactiveTraceAtRandomIntervalsRule::OnTriggerTimer,
240 base::Unretained(this)));
243 int GetReactiveTimeout() const override {
244 return base::RandInt(timeout_min_, timeout_max_);
247 bool ShouldTriggerNamedEvent(const std::string& named_event) const override {
248 return named_event == named_event_;
251 BackgroundTracingConfigImpl::CategoryPreset GetCategoryPreset()
252 const override {
253 return category_preset_;
256 std::string GenerateUniqueName() const {
257 static int ids = 0;
258 char work_buffer[256];
259 base::strings::SafeSNPrintf(work_buffer, sizeof(work_buffer), "%s_%d",
260 kTraceAtRandomIntervalsEventName, ids++);
261 return work_buffer;
264 private:
265 std::string named_event_;
266 base::OneShotTimer<ReactiveTraceAtRandomIntervalsRule> trigger_timer_;
267 BackgroundTracingConfigImpl::CategoryPreset category_preset_;
268 BackgroundTracingManagerImpl::TriggerHandle handle_;
269 int timeout_min_;
270 int timeout_max_;
273 } // namespace
275 int BackgroundTracingRule::GetReactiveTimeout() const {
276 return -1;
279 scoped_ptr<BackgroundTracingRule> BackgroundTracingRule::PreemptiveRuleFromDict(
280 const base::DictionaryValue* dict) {
281 DCHECK(dict);
283 std::string type;
284 if (!dict->GetString(kConfigRuleKey, &type))
285 return nullptr;
287 if (type == kPreemptiveConfigRuleMonitorNamed) {
288 std::string trigger_name;
289 if (!dict->GetString(kConfigRuleTriggerNameKey, &trigger_name))
290 return nullptr;
292 return scoped_ptr<BackgroundTracingRule>(
293 new NamedTriggerRule(trigger_name));
296 if (type == kPreemptiveConfigRuleMonitorHistogram) {
297 std::string histogram_name;
298 if (!dict->GetString(kConfigRuleHistogramNameKey, &histogram_name))
299 return nullptr;
301 int histogram_value;
302 if (!dict->GetInteger(kConfigRuleHistogramValueKey, &histogram_value))
303 return nullptr;
305 return scoped_ptr<BackgroundTracingRule>(
306 new HistogramRule(histogram_name, histogram_value));
309 return nullptr;
312 scoped_ptr<BackgroundTracingRule> BackgroundTracingRule::ReactiveRuleFromDict(
313 const base::DictionaryValue* dict,
314 BackgroundTracingConfigImpl::CategoryPreset category_preset) {
315 DCHECK(dict);
317 std::string type;
318 if (!dict->GetString(kConfigRuleKey, &type))
319 return nullptr;
321 if (type == kReactiveConfigRuleTraceOnNavigationUntilTriggerOrFull) {
322 std::string trigger_name;
323 if (!dict->GetString(kConfigRuleTriggerNameKey, &trigger_name))
324 return nullptr;
326 return scoped_ptr<BackgroundTracingRule>(
327 new ReactiveTraceForNSOrTriggerOrFullRule(trigger_name,
328 category_preset));
331 if (type == kReactiveConfigRuleTraceAtRandomIntervals) {
332 int timeout_min;
333 if (!dict->GetInteger(kConfigRuleRandomIntervalTimeoutMin, &timeout_min))
334 return nullptr;
336 int timeout_max;
337 if (!dict->GetInteger(kConfigRuleRandomIntervalTimeoutMax, &timeout_max))
338 return nullptr;
340 if (timeout_min > timeout_max)
341 return nullptr;
343 return scoped_ptr<BackgroundTracingRule>(
344 new ReactiveTraceAtRandomIntervalsRule(category_preset, timeout_min,
345 timeout_max));
348 return nullptr;
351 } // namespace content