Index: content/browser/devtools/devtools_tracing_handler.cc |
diff --git a/content/browser/devtools/devtools_tracing_handler.cc b/content/browser/devtools/devtools_tracing_handler.cc |
index 0657b8e48d2a9c83cc2d171630eddcefc77913b4..0e1869a141d99280a416b84cb224822907057a44 100644 |
--- a/content/browser/devtools/devtools_tracing_handler.cc |
+++ b/content/browser/devtools/devtools_tracing_handler.cc |
@@ -6,14 +6,18 @@ |
#include "base/bind.h" |
#include "base/callback.h" |
+#include "base/file_util.h" |
+#include "base/json/json_reader.h" |
+#include "base/json/json_writer.h" |
#include "base/location.h" |
+#include "base/memory/ref_counted_memory.h" |
#include "base/strings/string_split.h" |
#include "base/strings/stringprintf.h" |
#include "base/values.h" |
#include "content/browser/devtools/devtools_http_handler_impl.h" |
#include "content/browser/devtools/devtools_protocol_constants.h" |
-#include "content/public/browser/trace_controller.h" |
-#include "content/public/browser/trace_subscriber.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/tracing_controller.h" |
namespace content { |
@@ -23,10 +27,23 @@ const char kRecordUntilFull[] = "record-until-full"; |
const char kRecordContinuously[] = "record-continuously"; |
const char kEnableSampling[] = "enable-sampling"; |
+void ReadFile( |
+ const base::FilePath& path, |
+ const base::Callback<void(const scoped_refptr<base::RefCountedString>&)> |
+ callback) { |
+ std::string trace_data; |
+ if (!base::ReadFileToString(path, &trace_data)) |
+ LOG(ERROR) << "Failed to read file: " << path.value(); |
+ base::DeleteFile(path, false); |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
+ base::Bind(callback, make_scoped_refptr( |
+ base::RefCountedString::TakeString(&trace_data)))); |
+} |
+ |
} // namespace |
DevToolsTracingHandler::DevToolsTracingHandler() |
- : is_running_(false) { |
+ : weak_factory_(this) { |
RegisterCommandHandler(devtools::Tracing::start::kName, |
base::Bind(&DevToolsTracingHandler::OnStart, |
base::Unretained(this))); |
@@ -38,28 +55,60 @@ DevToolsTracingHandler::DevToolsTracingHandler() |
DevToolsTracingHandler::~DevToolsTracingHandler() { |
} |
-void DevToolsTracingHandler::OnEndTracingComplete() { |
- is_running_ = false; |
+void DevToolsTracingHandler::BeginReadingRecordingResult( |
+ const base::FilePath& path) { |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&ReadFile, path, |
+ base::Bind(&DevToolsTracingHandler::ReadRecordingResult, |
+ weak_factory_.GetWeakPtr()))); |
+} |
+ |
+void DevToolsTracingHandler::ReadRecordingResult( |
+ const scoped_refptr<base::RefCountedString>& trace_data) { |
+ if (trace_data->data().size()) { |
+ scoped_ptr<base::Value> trace_value(base::JSONReader::Read( |
+ trace_data->data())); |
+ DictionaryValue* dictionary = NULL; |
+ bool ok = trace_value->GetAsDictionary(&dictionary); |
+ DCHECK(ok); |
+ ListValue* list = NULL; |
+ ok = dictionary->GetList("traceEvents", &list); |
+ DCHECK(ok); |
+ std::string buffer; |
+ for (size_t i = 0; i < list->GetSize(); ++i) { |
+ std::string item; |
+ base::Value* item_value; |
+ list->Get(i, &item_value); |
+ base::JSONWriter::Write(item_value, &item); |
+ if (buffer.size()) |
+ buffer.append(","); |
+ buffer.append(item); |
+ if (i % 1000 == 0) { |
+ OnTraceDataCollected(buffer); |
+ buffer.clear(); |
+ } |
+ } |
+ if (buffer.size()) |
+ OnTraceDataCollected(buffer); |
+ } |
+ |
SendNotification(devtools::Tracing::tracingComplete::kName, NULL); |
} |
void DevToolsTracingHandler::OnTraceDataCollected( |
- const scoped_refptr<base::RefCountedString>& trace_fragment) { |
- if (is_running_) { |
- // Hand-craft protocol notification message so we can substitute JSON |
- // that we already got as string as a bare object, not a quoted string. |
- std::string message = base::StringPrintf( |
- "{ \"method\": \"%s\", \"params\": { \"%s\": [ %s ] } }", |
- devtools::Tracing::dataCollected::kName, |
- devtools::Tracing::dataCollected::kValue, |
- trace_fragment->data().c_str()); |
- SendRawMessage(message); |
- } |
+ const std::string& trace_fragment) { |
+ // Hand-craft protocol notification message so we can substitute JSON |
+ // that we already got as string as a bare object, not a quoted string. |
+ std::string message = base::StringPrintf( |
+ "{ \"method\": \"%s\", \"params\": { \"%s\": [ %s ] } }", |
+ devtools::Tracing::dataCollected::kName, |
+ devtools::Tracing::dataCollected::kValue, |
+ trace_fragment.c_str()); |
+ SendRawMessage(message); |
} |
-// Note, if you add more options here you also need to update: |
-// base/debug/trace_event_impl:TraceOptionsFromString |
-base::debug::TraceLog::Options DevToolsTracingHandler::TraceOptionsFromString( |
+TracingController::Options DevToolsTracingHandler::TraceOptionsFromString( |
const std::string& options) { |
std::vector<std::string> split; |
std::vector<std::string>::iterator iter; |
@@ -68,18 +117,14 @@ base::debug::TraceLog::Options DevToolsTracingHandler::TraceOptionsFromString( |
base::SplitString(options, ',', &split); |
for (iter = split.begin(); iter != split.end(); ++iter) { |
if (*iter == kRecordUntilFull) { |
- ret |= base::debug::TraceLog::RECORD_UNTIL_FULL; |
+ ret &= ~TracingController::RECORD_CONTINUOUSLY; |
} else if (*iter == kRecordContinuously) { |
- ret |= base::debug::TraceLog::RECORD_CONTINUOUSLY; |
+ ret |= TracingController::RECORD_CONTINUOUSLY; |
} else if (*iter == kEnableSampling) { |
- ret |= base::debug::TraceLog::ENABLE_SAMPLING; |
+ ret |= TracingController::ENABLE_SAMPLING; |
} |
} |
- if (!(ret & base::debug::TraceLog::RECORD_UNTIL_FULL) && |
- !(ret & base::debug::TraceLog::RECORD_CONTINUOUSLY)) |
- ret |= base::debug::TraceLog::RECORD_UNTIL_FULL; |
- |
- return static_cast<base::debug::TraceLog::Options>(ret); |
+ return static_cast<TracingController::Options>(ret); |
} |
scoped_refptr<DevToolsProtocol::Response> |
@@ -90,23 +135,26 @@ DevToolsTracingHandler::OnStart( |
if (params) |
params->GetString(devtools::Tracing::start::kCategories, &categories); |
- base::debug::TraceLog::Options options = |
- base::debug::TraceLog::RECORD_UNTIL_FULL; |
+ TracingController::Options options = TracingController::DEFAULT_OPTIONS; |
if (params && params->HasKey(devtools::Tracing::start::kTraceOptions)) { |
std::string options_param; |
params->GetString(devtools::Tracing::start::kTraceOptions, &options_param); |
options = TraceOptionsFromString(options_param); |
} |
- TraceController::GetInstance()->BeginTracing(this, categories, options); |
- is_running_ = true; |
+ TracingController::GetInstance()->EnableRecording( |
+ categories, options, |
+ TracingController::EnableRecordingDoneCallback()); |
return command->SuccessResponse(NULL); |
} |
scoped_refptr<DevToolsProtocol::Response> |
DevToolsTracingHandler::OnEnd( |
scoped_refptr<DevToolsProtocol::Command> command) { |
- TraceController::GetInstance()->EndTracingAsync(this); |
+ TracingController::GetInstance()->DisableRecording( |
+ base::FilePath(), |
+ base::Bind(&DevToolsTracingHandler::BeginReadingRecordingResult, |
+ weak_factory_.GetWeakPtr())); |
return command->SuccessResponse(NULL); |
} |