OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "content/browser/tracing/tracing_controller_impl.h" | 4 #include "content/browser/tracing/tracing_controller_impl.h" |
5 | 5 |
6 #include "base/bind.h" | 6 #include "base/bind.h" |
7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
8 #include "base/json/string_escape.h" | 8 #include "base/json/string_escape.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 using base::trace_event::TraceOptions; | 28 using base::trace_event::TraceOptions; |
29 using base::trace_event::CategoryFilter; | 29 using base::trace_event::CategoryFilter; |
30 | 30 |
31 namespace content { | 31 namespace content { |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = | 35 base::LazyInstance<TracingControllerImpl>::Leaky g_controller = |
36 LAZY_INSTANCE_INITIALIZER; | 36 LAZY_INSTANCE_INITIALIZER; |
37 | 37 |
38 class FileTraceDataSink : public TracingController::TraceDataSink { | |
39 public: | |
40 explicit FileTraceDataSink(const base::FilePath& trace_file_path, | |
41 const base::Closure& callback) | |
42 : file_path_(trace_file_path), | |
43 completion_callback_(callback), | |
44 file_(NULL) {} | |
45 | |
46 void AddTraceChunk(const std::string& chunk) override { | |
47 std::string tmp = chunk; | |
48 scoped_refptr<base::RefCountedString> chunk_ptr = | |
49 base::RefCountedString::TakeString(&tmp); | |
50 BrowserThread::PostTask( | |
51 BrowserThread::FILE, | |
52 FROM_HERE, | |
53 base::Bind( | |
54 &FileTraceDataSink::AddTraceChunkOnFileThread, this, chunk_ptr)); | |
55 } | |
56 void SetSystemTrace(const std::string& data) override { | |
57 system_trace_ = data; | |
58 } | |
59 void Close() override { | |
60 BrowserThread::PostTask( | |
61 BrowserThread::FILE, | |
62 FROM_HERE, | |
63 base::Bind(&FileTraceDataSink::CloseOnFileThread, this)); | |
64 } | |
65 | |
66 private: | |
67 ~FileTraceDataSink() override { DCHECK(file_ == NULL); } | |
68 | |
69 void AddTraceChunkOnFileThread( | |
70 const scoped_refptr<base::RefCountedString> chunk) { | |
71 if (file_ != NULL) | |
72 fputc(',', file_); | |
73 else if (!OpenFileIfNeededOnFileThread()) | |
74 return; | |
75 ignore_result(fwrite(chunk->data().c_str(), strlen(chunk->data().c_str()), | |
76 1, file_)); | |
77 } | |
78 | |
79 bool OpenFileIfNeededOnFileThread() { | |
80 if (file_ != NULL) | |
81 return true; | |
82 file_ = base::OpenFile(file_path_, "w"); | |
83 if (file_ == NULL) { | |
84 LOG(ERROR) << "Failed to open " << file_path_.value(); | |
85 return false; | |
86 } | |
87 const char preamble[] = "{\"traceEvents\": ["; | |
88 ignore_result(fwrite(preamble, strlen(preamble), 1, file_)); | |
89 return true; | |
90 } | |
91 | |
92 void CloseOnFileThread() { | |
93 if (OpenFileIfNeededOnFileThread()) { | |
94 fputc(']', file_); | |
95 if (!system_trace_.empty()) { | |
96 const char systemTraceEvents[] = ",\"systemTraceEvents\": "; | |
97 ignore_result(fwrite(systemTraceEvents, strlen(systemTraceEvents), | |
98 1, file_)); | |
99 ignore_result(fwrite(system_trace_.c_str(), | |
100 strlen(system_trace_.c_str()), 1, file_)); | |
101 } | |
102 fputc('}', file_); | |
103 base::CloseFile(file_); | |
104 file_ = NULL; | |
105 } | |
106 BrowserThread::PostTask( | |
107 BrowserThread::UI, | |
108 FROM_HERE, | |
109 base::Bind(&FileTraceDataSink::FinalizeOnUIThread, this)); | |
110 } | |
111 | |
112 void FinalizeOnUIThread() { completion_callback_.Run(); } | |
113 | |
114 base::FilePath file_path_; | |
115 base::Closure completion_callback_; | |
116 FILE* file_; | |
117 std::string system_trace_; | |
118 | |
119 DISALLOW_COPY_AND_ASSIGN(FileTraceDataSink); | |
120 }; | |
121 | |
122 class StringTraceDataSink : public TracingController::TraceDataSink { | |
123 public: | |
124 typedef base::Callback<void(base::RefCountedString*)> CompletionCallback; | |
125 | |
126 explicit StringTraceDataSink(CompletionCallback callback) | |
127 : completion_callback_(callback) {} | |
128 | |
129 // TracingController::TraceDataSink implementation | |
130 void AddTraceChunk(const std::string& chunk) override { | |
131 if (!trace_.empty()) | |
132 trace_ += ","; | |
133 trace_ += chunk; | |
134 } | |
135 void SetSystemTrace(const std::string& data) override { | |
136 system_trace_ = data; | |
137 } | |
138 void Close() override { | |
139 std::string result = "{\"traceEvents\":[" + trace_ + "]"; | |
140 if (!system_trace_.empty()) | |
141 result += ",\"systemTraceEvents\": " + system_trace_; | |
142 result += "}"; | |
143 | |
144 scoped_refptr<base::RefCountedString> str = | |
145 base::RefCountedString::TakeString(&result); | |
146 completion_callback_.Run(str.get()); | |
147 } | |
148 | |
149 private: | |
150 ~StringTraceDataSink() override {} | |
151 | |
152 std::string trace_; | |
153 std::string system_trace_; | |
154 CompletionCallback completion_callback_; | |
155 | |
156 DISALLOW_COPY_AND_ASSIGN(StringTraceDataSink); | |
157 }; | |
158 | |
159 } // namespace | 38 } // namespace |
160 | 39 |
161 TracingController* TracingController::GetInstance() { | 40 TracingController* TracingController::GetInstance() { |
162 return TracingControllerImpl::GetInstance(); | 41 return TracingControllerImpl::GetInstance(); |
163 } | 42 } |
164 | 43 |
165 TracingControllerImpl::TracingControllerImpl() | 44 TracingControllerImpl::TracingControllerImpl() |
166 : pending_disable_recording_ack_count_(0), | 45 : pending_disable_recording_ack_count_(0), |
167 pending_capture_monitoring_snapshot_ack_count_(0), | 46 pending_capture_monitoring_snapshot_ack_count_(0), |
168 pending_trace_log_status_ack_count_(0), | 47 pending_trace_log_status_ack_count_(0), |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 base::Closure on_disable_monitoring_done_callback = | 299 base::Closure on_disable_monitoring_done_callback = |
421 base::Bind(&TracingControllerImpl::OnDisableMonitoringDone, | 300 base::Bind(&TracingControllerImpl::OnDisableMonitoringDone, |
422 base::Unretained(this), callback); | 301 base::Unretained(this), callback); |
423 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 302 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
424 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, | 303 base::Bind(&TracingControllerImpl::SetDisabledOnFileThread, |
425 base::Unretained(this), | 304 base::Unretained(this), |
426 on_disable_monitoring_done_callback)); | 305 on_disable_monitoring_done_callback)); |
427 return true; | 306 return true; |
428 } | 307 } |
429 | 308 |
430 scoped_refptr<TracingController::TraceDataSink> | |
431 TracingController::CreateStringSink( | |
432 const base::Callback<void(base::RefCountedString*)>& callback) { | |
433 return new StringTraceDataSink(callback); | |
434 } | |
435 | |
436 scoped_refptr<TracingController::TraceDataSink> | |
437 TracingController::CreateFileSink(const base::FilePath& file_path, | |
438 const base::Closure& callback) { | |
439 return new FileTraceDataSink(file_path, callback); | |
440 } | |
441 | |
442 void TracingControllerImpl::OnDisableMonitoringDone( | 309 void TracingControllerImpl::OnDisableMonitoringDone( |
443 const DisableMonitoringDoneCallback& callback) { | 310 const DisableMonitoringDoneCallback& callback) { |
444 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 311 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
445 | 312 |
446 OnMonitoringStateChanged(false); | 313 OnMonitoringStateChanged(false); |
447 | 314 |
448 // Notify all child processes. | 315 // Notify all child processes. |
449 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); | 316 for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
450 it != trace_message_filters_.end(); ++it) { | 317 it != trace_message_filters_.end(); ++it) { |
451 it->get()->SendDisableMonitoring(); | 318 it->get()->SendDisableMonitoring(); |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 is_monitoring_ = is_monitoring; | 866 is_monitoring_ = is_monitoring; |
1000 #if !defined(OS_ANDROID) | 867 #if !defined(OS_ANDROID) |
1001 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); | 868 for (std::set<TracingUI*>::iterator it = tracing_uis_.begin(); |
1002 it != tracing_uis_.end(); it++) { | 869 it != tracing_uis_.end(); it++) { |
1003 (*it)->OnMonitoringStateChanged(is_monitoring); | 870 (*it)->OnMonitoringStateChanged(is_monitoring); |
1004 } | 871 } |
1005 #endif | 872 #endif |
1006 } | 873 } |
1007 | 874 |
1008 } // namespace content | 875 } // namespace content |
OLD | NEW |