| 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 |