| Index: content/browser/tracing/tracing_controller_impl.cc
|
| diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
|
| index 4c08eacfd90281c0e4af8466a62776462c3a0e8e..7523e833cf26cdee9d3843b04668b4ca92474867 100644
|
| --- a/content/browser/tracing/tracing_controller_impl.cc
|
| +++ b/content/browser/tracing/tracing_controller_impl.cc
|
| @@ -15,6 +15,11 @@
|
| #include "content/public/browser/browser_message_filter.h"
|
| #include "content/public/common/content_switches.h"
|
|
|
| +#if defined(OS_CHROMEOS)
|
| +#include "chromeos/dbus/dbus_thread_manager.h"
|
| +#include "chromeos/dbus/debug_daemon_client.h"
|
| +#endif
|
| +
|
| using base::debug::TraceLog;
|
|
|
| namespace content {
|
| @@ -43,16 +48,28 @@ class TracingControllerImpl::ResultFile {
|
| base::Bind(&TracingControllerImpl::ResultFile::CloseTask,
|
| base::Unretained(this), callback));
|
| }
|
| + void WriteSystemTrace(
|
| + const scoped_refptr<base::RefCountedString>& events_str_ptr) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE,
|
| + FROM_HERE,
|
| + base::Bind(&TracingControllerImpl::ResultFile::WriteSystemTraceTask,
|
| + base::Unretained(this), events_str_ptr));
|
| + }
|
| +
|
| const base::FilePath& path() const { return path_; }
|
|
|
| private:
|
| void OpenTask();
|
| void WriteTask(const scoped_refptr<base::RefCountedString>& events_str_ptr);
|
| + void WriteSystemTraceTask(
|
| + const scoped_refptr<base::RefCountedString>& events_str_ptr);
|
| void CloseTask(const base::Closure& callback);
|
|
|
| FILE* file_;
|
| base::FilePath path_;
|
| bool has_at_least_one_result_;
|
| + scoped_refptr<base::RefCountedString> system_trace_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ResultFile);
|
| };
|
| @@ -97,13 +114,35 @@ void TracingControllerImpl::ResultFile::WriteTask(
|
| DCHECK(written == 1);
|
| }
|
|
|
| +void TracingControllerImpl::ResultFile::WriteSystemTraceTask(
|
| + const scoped_refptr<base::RefCountedString>& events_str_ptr) {
|
| + system_trace_ = events_str_ptr;
|
| +}
|
| +
|
| void TracingControllerImpl::ResultFile::CloseTask(
|
| const base::Closure& callback) {
|
| if (!file_)
|
| return;
|
|
|
| - const char* trailout = "]}";
|
| - size_t written = fwrite(trailout, strlen(trailout), 1, file_);
|
| + const char* trailevents = "]";
|
| + size_t written = fwrite(trailevents, strlen(trailevents), 1, file_);
|
| + DCHECK(written == 1);
|
| +
|
| + if (system_trace_) {
|
| + std::string json_string = base::GetQuotedJSONString(system_trace_->data());
|
| +
|
| + const char* systemTraceHead = ", \"systemTraceEvents\": ";
|
| + written = fwrite(systemTraceHead, strlen(systemTraceHead), 1, file_);
|
| + DCHECK(written == 1);
|
| +
|
| + written = fwrite(json_string.data(), json_string.size(), 1, file_);
|
| + DCHECK(written == 1);
|
| +
|
| + system_trace_ = NULL;
|
| + }
|
| +
|
| + const char* trailout = "}";
|
| + written = fwrite(trailout, strlen(trailout), 1, file_);
|
| DCHECK(written == 1);
|
| base::CloseFile(file_);
|
| file_ = NULL;
|
| @@ -119,6 +158,9 @@ TracingControllerImpl::TracingControllerImpl() :
|
| maximum_trace_buffer_percent_full_(0),
|
| // Tracing may have been enabled by ContentMainRunner if kTraceStartup
|
| // is specified in command line.
|
| +#if defined(OS_CHROMEOS)
|
| + is_system_tracing_(false),
|
| +#endif
|
| is_recording_(TraceLog::GetInstance()->IsEnabled()),
|
| is_monitoring_(false) {
|
| }
|
| @@ -194,7 +236,14 @@ bool TracingControllerImpl::EnableRecording(
|
| if (options & ENABLE_SAMPLING) {
|
| trace_options |= TraceLog::ENABLE_SAMPLING;
|
| }
|
| - // TODO(haraken): How to handle ENABLE_SYSTRACE?
|
| +#if defined(OS_CHROMEOS)
|
| + if (options & ENABLE_SYSTRACE) {
|
| + DCHECK(!is_system_tracing_);
|
| + chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
|
| + StartSystemTracing();
|
| + is_system_tracing_ = true;
|
| + }
|
| +#endif
|
|
|
| base::Closure on_enable_recording_done_callback =
|
| base::Bind(&TracingControllerImpl::OnEnableRecordingDone,
|
| @@ -609,10 +658,31 @@ void TracingControllerImpl::OnDisableRecordingAcked(
|
| if (pending_disable_recording_ack_count_ != 0)
|
| return;
|
|
|
| + OnDisableRecordingComplete();
|
| +}
|
| +
|
| +void TracingControllerImpl::OnDisableRecordingComplete() {
|
| // All acks (including from the subprocesses and the local trace) have been
|
| // received.
|
| is_recording_ = false;
|
|
|
| +#if defined(OS_CHROMEOS)
|
| + if (is_system_tracing_) {
|
| + // Disable system tracing now that the local trace has shutdown.
|
| + // This must be done last because we potentially need to push event
|
| + // records into the system event log for synchronizing system event
|
| + // timestamps with chrome event timestamps--and since the system event
|
| + // log is a ring-buffer (on linux) adding them at the end is the only
|
| + // way we're confident we'll have them in the final result.
|
| + is_system_tracing_ = false;
|
| + chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
|
| + RequestStopSystemTracing(
|
| + base::Bind(&TracingControllerImpl::OnEndSystemTracingAcked,
|
| + base::Unretained(this)));
|
| + return;
|
| + }
|
| +#endif
|
| +
|
| // Trigger callback if one is set.
|
| if (!pending_get_categories_done_callback_.is_null()) {
|
| pending_get_categories_done_callback_.Run(known_category_groups_);
|
| @@ -637,6 +707,19 @@ void TracingControllerImpl::OnResultFileClosed() {
|
| result_file_.reset();
|
| }
|
|
|
| +#if defined(OS_CHROMEOS)
|
| +void TracingControllerImpl::OnEndSystemTracingAcked(
|
| + const scoped_refptr<base::RefCountedString>& events_str_ptr) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| +
|
| + if (result_file_)
|
| + result_file_->WriteSystemTrace(events_str_ptr);
|
| +
|
| + DCHECK(!is_system_tracing_);
|
| + OnDisableRecordingComplete();
|
| +}
|
| +#endif
|
| +
|
| void TracingControllerImpl::OnCaptureMonitoringSnapshotAcked(
|
| TraceMessageFilter* trace_message_filter) {
|
| if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
|
|