Windows should animate when they are about to get docked at screen edges.
[chromium-blink-merge.git] / net / base / net_log.cc
blobd1e9c98de311f26a4242b594f0472d419a8888ea
1 // Copyright (c) 2012 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.
5 #include "net/base/net_log.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/time.h"
12 #include "base/values.h"
13 #include "net/base/net_errors.h"
15 namespace net {
17 namespace {
19 // Returns parameters for logging data transferred events. Includes number of
20 // bytes transferred and, if the log level indicates bytes should be logged and
21 // |byte_count| > 0, the bytes themselves. The bytes are hex-encoded, since
22 // base::StringValue only supports UTF-8.
23 base::Value* BytesTransferredCallback(int byte_count,
24 const char* bytes,
25 NetLog::LogLevel log_level) {
26 base::DictionaryValue* dict = new base::DictionaryValue();
27 dict->SetInteger("byte_count", byte_count);
28 if (NetLog::IsLoggingBytes(log_level) && byte_count > 0)
29 dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, byte_count));
30 return dict;
33 base::Value* SourceEventParametersCallback(const NetLog::Source source,
34 NetLog::LogLevel /* log_level */) {
35 if (!source.IsValid())
36 return NULL;
37 base::DictionaryValue* event_params = new base::DictionaryValue();
38 source.AddToEventParameters(event_params);
39 return event_params;
42 base::Value* NetLogIntegerCallback(const char* name,
43 int value,
44 NetLog::LogLevel /* log_level */) {
45 base::DictionaryValue* event_params = new base::DictionaryValue();
46 event_params->SetInteger(name, value);
47 return event_params;
50 base::Value* NetLogInt64Callback(const char* name,
51 int64 value,
52 NetLog::LogLevel /* log_level */) {
53 base::DictionaryValue* event_params = new base::DictionaryValue();
54 event_params->SetString(name, base::Int64ToString(value));
55 return event_params;
58 base::Value* NetLogStringCallback(const char* name,
59 const std::string* value,
60 NetLog::LogLevel /* log_level */) {
61 base::DictionaryValue* event_params = new base::DictionaryValue();
62 event_params->SetString(name, *value);
63 return event_params;
66 base::Value* NetLogString16Callback(const char* name,
67 const base::string16* value,
68 NetLog::LogLevel /* log_level */) {
69 base::DictionaryValue* event_params = new base::DictionaryValue();
70 event_params->SetString(name, *value);
71 return event_params;
74 } // namespace
76 // LoadTimingInfo requires this be 0.
77 const uint32 NetLog::Source::kInvalidId = 0;
79 NetLog::Source::Source() : type(SOURCE_NONE), id(kInvalidId) {
82 NetLog::Source::Source(SourceType type, uint32 id) : type(type), id(id) {
85 bool NetLog::Source::IsValid() const {
86 return id != kInvalidId;
89 void NetLog::Source::AddToEventParameters(
90 base::DictionaryValue* event_params) const {
91 base::DictionaryValue* dict = new base::DictionaryValue();
92 dict->SetInteger("type", static_cast<int>(type));
93 dict->SetInteger("id", static_cast<int>(id));
94 event_params->Set("source_dependency", dict);
97 NetLog::ParametersCallback NetLog::Source::ToEventParametersCallback() const {
98 return base::Bind(&SourceEventParametersCallback, *this);
101 // static
102 bool NetLog::Source::FromEventParameters(base::Value* event_params,
103 Source* source) {
104 base::DictionaryValue* dict;
105 base::DictionaryValue* source_dict;
106 int source_id;
107 int source_type;
108 if (!event_params ||
109 !event_params->GetAsDictionary(&dict) ||
110 !dict->GetDictionary("source_dependency", &source_dict) ||
111 !source_dict->GetInteger("id", &source_id) ||
112 !source_dict->GetInteger("type", &source_type)) {
113 *source = Source();
114 return false;
117 DCHECK_LE(0, source_id);
118 DCHECK_LT(source_type, NetLog::SOURCE_COUNT);
119 *source = Source(static_cast<SourceType>(source_type), source_id);
120 return true;
123 base::Value* NetLog::Entry::ToValue() const {
124 base::DictionaryValue* entry_dict(new base::DictionaryValue());
126 entry_dict->SetString("time", TickCountToString(time_));
128 // Set the entry source.
129 base::DictionaryValue* source_dict = new base::DictionaryValue();
130 source_dict->SetInteger("id", source_.id);
131 source_dict->SetInteger("type", static_cast<int>(source_.type));
132 entry_dict->Set("source", source_dict);
134 // Set the event info.
135 entry_dict->SetInteger("type", static_cast<int>(type_));
136 entry_dict->SetInteger("phase", static_cast<int>(phase_));
138 // Set the event-specific parameters.
139 if (parameters_callback_) {
140 base::Value* value = parameters_callback_->Run(log_level_);
141 if (value)
142 entry_dict->Set("params", value);
145 return entry_dict;
148 base::Value* NetLog::Entry::ParametersToValue() const {
149 if (parameters_callback_)
150 return parameters_callback_->Run(log_level_);
151 return NULL;
154 NetLog::Entry::Entry(
155 EventType type,
156 Source source,
157 EventPhase phase,
158 base::TimeTicks time,
159 const ParametersCallback* parameters_callback,
160 LogLevel log_level)
161 : type_(type),
162 source_(source),
163 phase_(phase),
164 time_(time),
165 parameters_callback_(parameters_callback),
166 log_level_(log_level) {
169 NetLog::Entry::~Entry() {
172 NetLog::ThreadSafeObserver::ThreadSafeObserver() : log_level_(LOG_BASIC),
173 net_log_(NULL) {
176 NetLog::ThreadSafeObserver::~ThreadSafeObserver() {
177 // Make sure we aren't watching a NetLog on destruction. Because the NetLog
178 // may pass events to each observer on multiple threads, we cannot safely
179 // stop watching a NetLog automatically from a parent class.
180 DCHECK(!net_log_);
183 NetLog::LogLevel NetLog::ThreadSafeObserver::log_level() const {
184 DCHECK(net_log_);
185 return log_level_;
188 NetLog* NetLog::ThreadSafeObserver::net_log() const {
189 return net_log_;
192 NetLog::NetLog()
193 : last_id_(0),
194 base_log_level_(LOG_NONE),
195 effective_log_level_(LOG_NONE) {
198 NetLog::~NetLog() {
201 void NetLog::AddGlobalEntry(EventType type) {
202 AddEntry(type,
203 Source(net::NetLog::SOURCE_NONE, NextID()),
204 net::NetLog::PHASE_NONE,
205 NULL);
208 void NetLog::AddGlobalEntry(
209 EventType type,
210 const NetLog::ParametersCallback& parameters_callback) {
211 AddEntry(type,
212 Source(net::NetLog::SOURCE_NONE, NextID()),
213 net::NetLog::PHASE_NONE,
214 &parameters_callback);
217 uint32 NetLog::NextID() {
218 return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1);
221 void NetLog::SetBaseLogLevel(LogLevel log_level) {
222 base::AutoLock lock(lock_);
223 base_log_level_ = log_level;
225 UpdateLogLevel();
228 NetLog::LogLevel NetLog::GetLogLevel() const {
229 base::subtle::Atomic32 log_level =
230 base::subtle::NoBarrier_Load(&effective_log_level_);
231 return static_cast<net::NetLog::LogLevel>(log_level);
234 void NetLog::AddThreadSafeObserver(
235 net::NetLog::ThreadSafeObserver* observer,
236 LogLevel log_level) {
237 base::AutoLock lock(lock_);
239 DCHECK(!observer->net_log_);
240 observers_.AddObserver(observer);
241 observer->net_log_ = this;
242 observer->log_level_ = log_level;
243 UpdateLogLevel();
246 void NetLog::SetObserverLogLevel(
247 net::NetLog::ThreadSafeObserver* observer,
248 LogLevel log_level) {
249 base::AutoLock lock(lock_);
251 DCHECK(observers_.HasObserver(observer));
252 DCHECK_EQ(this, observer->net_log_);
253 observer->log_level_ = log_level;
254 UpdateLogLevel();
257 void NetLog::RemoveThreadSafeObserver(
258 net::NetLog::ThreadSafeObserver* observer) {
259 base::AutoLock lock(lock_);
261 DCHECK(observers_.HasObserver(observer));
262 DCHECK_EQ(this, observer->net_log_);
263 observers_.RemoveObserver(observer);
264 observer->net_log_ = NULL;
265 UpdateLogLevel();
268 void NetLog::UpdateLogLevel() {
269 lock_.AssertAcquired();
271 // Look through all the observers and find the finest granularity
272 // log level (higher values of the enum imply *lower* log levels).
273 LogLevel new_effective_log_level = base_log_level_;
274 ObserverListBase<ThreadSafeObserver>::Iterator it(observers_);
275 ThreadSafeObserver* observer;
276 while ((observer = it.GetNext()) != NULL) {
277 new_effective_log_level =
278 std::min(new_effective_log_level, observer->log_level());
280 base::subtle::NoBarrier_Store(&effective_log_level_,
281 new_effective_log_level);
284 // static
285 std::string NetLog::TickCountToString(const base::TimeTicks& time) {
286 int64 delta_time = (time - base::TimeTicks()).InMilliseconds();
287 return base::Int64ToString(delta_time);
290 // static
291 const char* NetLog::EventTypeToString(EventType event) {
292 switch (event) {
293 #define EVENT_TYPE(label) case TYPE_ ## label: return #label;
294 #include "net/base/net_log_event_type_list.h"
295 #undef EVENT_TYPE
296 default:
297 NOTREACHED();
298 return NULL;
302 // static
303 base::Value* NetLog::GetEventTypesAsValue() {
304 base::DictionaryValue* dict = new base::DictionaryValue();
305 for (int i = 0; i < EVENT_COUNT; ++i) {
306 dict->SetInteger(EventTypeToString(static_cast<EventType>(i)), i);
308 return dict;
311 // static
312 const char* NetLog::SourceTypeToString(SourceType source) {
313 switch (source) {
314 #define SOURCE_TYPE(label) case SOURCE_ ## label: return #label;
315 #include "net/base/net_log_source_type_list.h"
316 #undef SOURCE_TYPE
317 default:
318 NOTREACHED();
319 return NULL;
323 // static
324 base::Value* NetLog::GetSourceTypesAsValue() {
325 base::DictionaryValue* dict = new base::DictionaryValue();
326 for (int i = 0; i < SOURCE_COUNT; ++i) {
327 dict->SetInteger(SourceTypeToString(static_cast<SourceType>(i)), i);
329 return dict;
332 // static
333 const char* NetLog::EventPhaseToString(EventPhase phase) {
334 switch (phase) {
335 case PHASE_BEGIN:
336 return "PHASE_BEGIN";
337 case PHASE_END:
338 return "PHASE_END";
339 case PHASE_NONE:
340 return "PHASE_NONE";
342 NOTREACHED();
343 return NULL;
346 // static
347 bool NetLog::IsLoggingBytes(LogLevel log_level) {
348 return log_level == NetLog::LOG_ALL;
351 // static
352 bool NetLog::IsLoggingAllEvents(LogLevel log_level) {
353 return log_level <= NetLog::LOG_ALL_BUT_BYTES;
356 // static
357 NetLog::ParametersCallback NetLog::IntegerCallback(const char* name,
358 int value) {
359 return base::Bind(&NetLogIntegerCallback, name, value);
362 // static
363 NetLog::ParametersCallback NetLog::Int64Callback(const char* name,
364 int64 value) {
365 return base::Bind(&NetLogInt64Callback, name, value);
368 // static
369 NetLog::ParametersCallback NetLog::StringCallback(const char* name,
370 const std::string* value) {
371 DCHECK(value);
372 return base::Bind(&NetLogStringCallback, name, value);
375 // static
376 NetLog::ParametersCallback NetLog::StringCallback(const char* name,
377 const base::string16* value) {
378 DCHECK(value);
379 return base::Bind(&NetLogString16Callback, name, value);
382 void NetLog::AddEntry(EventType type,
383 const Source& source,
384 EventPhase phase,
385 const NetLog::ParametersCallback* parameters_callback) {
386 LogLevel log_level = GetLogLevel();
387 if (log_level == LOG_NONE)
388 return;
389 Entry entry(type, source, phase, base::TimeTicks::Now(),
390 parameters_callback, log_level);
392 // Notify all of the log observers.
393 base::AutoLock lock(lock_);
394 FOR_EACH_OBSERVER(ThreadSafeObserver, observers_, OnAddEntry(entry));
397 void BoundNetLog::AddEntry(NetLog::EventType type,
398 NetLog::EventPhase phase) const {
399 if (!net_log_)
400 return;
401 net_log_->AddEntry(type, source_, phase, NULL);
404 void BoundNetLog::AddEntry(
405 NetLog::EventType type,
406 NetLog::EventPhase phase,
407 const NetLog::ParametersCallback& get_parameters) const {
408 if (!net_log_)
409 return;
410 net_log_->AddEntry(type, source_, phase, &get_parameters);
413 void BoundNetLog::AddEvent(NetLog::EventType type) const {
414 AddEntry(type, NetLog::PHASE_NONE);
417 void BoundNetLog::AddEvent(
418 NetLog::EventType type,
419 const NetLog::ParametersCallback& get_parameters) const {
420 AddEntry(type, NetLog::PHASE_NONE, get_parameters);
423 void BoundNetLog::BeginEvent(NetLog::EventType type) const {
424 AddEntry(type, NetLog::PHASE_BEGIN);
427 void BoundNetLog::BeginEvent(
428 NetLog::EventType type,
429 const NetLog::ParametersCallback& get_parameters) const {
430 AddEntry(type, NetLog::PHASE_BEGIN, get_parameters);
433 void BoundNetLog::EndEvent(NetLog::EventType type) const {
434 AddEntry(type, NetLog::PHASE_END);
437 void BoundNetLog::EndEvent(
438 NetLog::EventType type,
439 const NetLog::ParametersCallback& get_parameters) const {
440 AddEntry(type, NetLog::PHASE_END, get_parameters);
443 void BoundNetLog::AddEventWithNetErrorCode(NetLog::EventType event_type,
444 int net_error) const {
445 DCHECK_NE(ERR_IO_PENDING, net_error);
446 if (net_error >= 0) {
447 AddEvent(event_type);
448 } else {
449 AddEvent(event_type, NetLog::IntegerCallback("net_error", net_error));
453 void BoundNetLog::EndEventWithNetErrorCode(NetLog::EventType event_type,
454 int net_error) const {
455 DCHECK_NE(ERR_IO_PENDING, net_error);
456 if (net_error >= 0) {
457 EndEvent(event_type);
458 } else {
459 EndEvent(event_type, NetLog::IntegerCallback("net_error", net_error));
463 void BoundNetLog::AddByteTransferEvent(NetLog::EventType event_type,
464 int byte_count,
465 const char* bytes) const {
466 AddEvent(event_type, base::Bind(BytesTransferredCallback, byte_count, bytes));
469 NetLog::LogLevel BoundNetLog::GetLogLevel() const {
470 if (net_log_)
471 return net_log_->GetLogLevel();
472 return NetLog::LOG_BASIC;
475 bool BoundNetLog::IsLoggingBytes() const {
476 return NetLog::IsLoggingBytes(GetLogLevel());
479 bool BoundNetLog::IsLoggingAllEvents() const {
480 return NetLog::IsLoggingAllEvents(GetLogLevel());
483 // static
484 BoundNetLog BoundNetLog::Make(NetLog* net_log,
485 NetLog::SourceType source_type) {
486 if (!net_log)
487 return BoundNetLog();
489 NetLog::Source source(source_type, net_log->NextID());
490 return BoundNetLog(source, net_log);
493 } // namespace net