1// Copyright (c) 2011 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 "net/base/net_log.h"
6
7#include "base/logging.h"
8#include "base/string_number_conversions.h"
9#include "base/time.h"
10#include "base/utf_string_conversions.h"
11#include "base/values.h"
12#include "net/base/net_errors.h"
13
14namespace net {
15
16Value* NetLog::Source::ToValue() const {
17  DictionaryValue* dict = new DictionaryValue();
18  dict->SetInteger("type", static_cast<int>(type));
19  dict->SetInteger("id", static_cast<int>(id));
20  return dict;
21}
22
23// static
24std::string NetLog::TickCountToString(const base::TimeTicks& time) {
25  int64 delta_time = (time - base::TimeTicks()).InMilliseconds();
26  return base::Int64ToString(delta_time);
27}
28
29// static
30const char* NetLog::EventTypeToString(EventType event) {
31  switch (event) {
32#define EVENT_TYPE(label) case TYPE_ ## label: return #label;
33#include "net/base/net_log_event_type_list.h"
34#undef EVENT_TYPE
35  }
36  return NULL;
37}
38
39// static
40std::vector<NetLog::EventType> NetLog::GetAllEventTypes() {
41  std::vector<NetLog::EventType> types;
42#define EVENT_TYPE(label) types.push_back(TYPE_ ## label);
43#include "net/base/net_log_event_type_list.h"
44#undef EVENT_TYPE
45  return types;
46}
47
48// static
49const char* NetLog::SourceTypeToString(SourceType source) {
50  switch (source) {
51#define SOURCE_TYPE(label, id) case id: return #label;
52#include "net/base/net_log_source_type_list.h"
53#undef SOURCE_TYPE
54  }
55  NOTREACHED();
56  return NULL;
57}
58
59// static
60const char* NetLog::EventPhaseToString(EventPhase phase) {
61  switch (phase) {
62    case PHASE_BEGIN:
63      return "PHASE_BEGIN";
64    case PHASE_END:
65      return "PHASE_END";
66    case PHASE_NONE:
67      return "PHASE_NONE";
68  }
69  NOTREACHED();
70  return NULL;
71}
72
73// static
74Value* NetLog::EntryToDictionaryValue(NetLog::EventType type,
75                                      const base::TimeTicks& time,
76                                      const NetLog::Source& source,
77                                      NetLog::EventPhase phase,
78                                      NetLog::EventParameters* params,
79                                      bool use_strings) {
80  DictionaryValue* entry_dict = new DictionaryValue();
81
82  entry_dict->SetString("time", TickCountToString(time));
83
84  // Set the entry source.
85  DictionaryValue* source_dict = new DictionaryValue();
86  source_dict->SetInteger("id", source.id);
87  if (!use_strings) {
88    source_dict->SetInteger("type", static_cast<int>(source.type));
89  } else {
90    source_dict->SetString("type",
91                           NetLog::SourceTypeToString(source.type));
92  }
93  entry_dict->Set("source", source_dict);
94
95  // Set the event info.
96  if (!use_strings) {
97    entry_dict->SetInteger("type", static_cast<int>(type));
98    entry_dict->SetInteger("phase", static_cast<int>(phase));
99  } else {
100    entry_dict->SetString("type", NetLog::EventTypeToString(type));
101    entry_dict->SetString("phase", NetLog::EventPhaseToString(phase));
102  }
103
104  // Set the event-specific parameters.
105  if (params)
106    entry_dict->Set("params", params->ToValue());
107
108  return entry_dict;
109}
110
111void BoundNetLog::AddEntry(
112    NetLog::EventType type,
113    NetLog::EventPhase phase,
114    const scoped_refptr<NetLog::EventParameters>& params) const {
115  if (net_log_) {
116    net_log_->AddEntry(type, base::TimeTicks::Now(), source_, phase, params);
117  }
118}
119
120void BoundNetLog::AddEntryWithTime(
121    NetLog::EventType type,
122    const base::TimeTicks& time,
123    NetLog::EventPhase phase,
124    const scoped_refptr<NetLog::EventParameters>& params) const {
125  if (net_log_) {
126    net_log_->AddEntry(type, time, source_, phase, params);
127  }
128}
129
130void BoundNetLog::AddEvent(
131    NetLog::EventType event_type,
132    const scoped_refptr<NetLog::EventParameters>& params) const {
133  AddEntry(event_type, NetLog::PHASE_NONE, params);
134}
135
136void BoundNetLog::BeginEvent(
137    NetLog::EventType event_type,
138    const scoped_refptr<NetLog::EventParameters>& params) const {
139  AddEntry(event_type, NetLog::PHASE_BEGIN, params);
140}
141
142void BoundNetLog::EndEvent(
143    NetLog::EventType event_type,
144    const scoped_refptr<NetLog::EventParameters>& params) const {
145  AddEntry(event_type, NetLog::PHASE_END, params);
146}
147
148void BoundNetLog::EndEventWithNetErrorCode(NetLog::EventType event_type,
149                                           int net_error) const {
150  DCHECK_NE(net_error, ERR_IO_PENDING);
151  if (net_error >= 0) {
152    EndEvent(event_type, NULL);
153  } else {
154    EndEvent(
155        event_type,
156        make_scoped_refptr(new NetLogIntegerParameter("net_error", net_error)));
157  }
158}
159
160NetLog::LogLevel BoundNetLog::GetLogLevel() const {
161  if (net_log_)
162    return net_log_->GetLogLevel();
163  return NetLog::LOG_BASIC;
164}
165
166bool BoundNetLog::IsLoggingBytes() const {
167  return GetLogLevel() == NetLog::LOG_ALL;
168}
169
170bool BoundNetLog::IsLoggingAllEvents() const {
171  return GetLogLevel() <= NetLog::LOG_ALL_BUT_BYTES;
172}
173
174// static
175BoundNetLog BoundNetLog::Make(NetLog* net_log,
176                              NetLog::SourceType source_type) {
177  if (!net_log)
178    return BoundNetLog();
179
180  NetLog::Source source(source_type, net_log->NextID());
181  return BoundNetLog(source, net_log);
182}
183
184NetLogStringParameter::NetLogStringParameter(const char* name,
185                                             const std::string& value)
186    : name_(name), value_(value) {
187}
188
189NetLogStringParameter::~NetLogStringParameter() {
190}
191
192Value* NetLogIntegerParameter::ToValue() const {
193  DictionaryValue* dict = new DictionaryValue();
194  dict->SetInteger(name_, value_);
195  return dict;
196}
197
198Value* NetLogStringParameter::ToValue() const {
199  DictionaryValue* dict = new DictionaryValue();
200  dict->SetString(name_, value_);
201  return dict;
202}
203
204Value* NetLogSourceParameter::ToValue() const {
205  DictionaryValue* dict = new DictionaryValue();
206
207  dict->Set(name_, value_.ToValue());
208  return dict;
209}
210
211ScopedNetLogEvent::ScopedNetLogEvent(
212    const BoundNetLog& net_log,
213    NetLog::EventType event_type,
214    const scoped_refptr<NetLog::EventParameters>& params)
215    : net_log_(net_log),
216      event_type_(event_type) {
217  net_log_.BeginEvent(event_type, params);
218}
219
220ScopedNetLogEvent::~ScopedNetLogEvent() {
221  net_log_.EndEvent(event_type_, end_event_params_);
222}
223
224void ScopedNetLogEvent::SetEndEventParameters(
225    const scoped_refptr<NetLog::EventParameters>& end_event_params) {
226  DCHECK(!end_event_params_.get());
227  end_event_params_ = end_event_params;
228}
229
230const BoundNetLog& ScopedNetLogEvent::net_log() const {
231  return net_log_;
232}
233
234}  // namespace net
235