Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1320)

Unified Diff: content/browser/tracing/tracing_ui.cc

Issue 12194007: Revert 180055: Very likely caused http://crbug.com/173885 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/tracing/tracing_ui.h ('k') | content/browser/webui/content_web_ui_controller_factory.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/tracing/tracing_ui.cc
===================================================================
--- content/browser/tracing/tracing_ui.cc (revision 180281)
+++ content/browser/tracing/tracing_ui.cc (working copy)
@@ -1,492 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/tracing/tracing_ui.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/debug/trace_event.h"
-#include "base/file_util.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/string_number_conversions.h"
-#include "base/stringprintf.h"
-#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/trace_controller.h"
-#include "content/public/browser/trace_subscriber.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "content/public/browser/web_ui.h"
-#include "content/public/browser/web_ui_data_source.h"
-#include "content/public/browser/web_ui_message_handler.h"
-#include "content/public/common/url_constants.h"
-#include "grit/content_resources.h"
-#include "ipc/ipc_channel.h"
-#include "ui/shell_dialogs/select_file_dialog.h"
-
-#if defined(OS_CHROMEOS)
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/debug_daemon_client.h"
-#endif
-
-namespace content {
-namespace {
-
-WebUIDataSource* CreateTracingHTMLSource() {
- WebUIDataSource* source =
- WebUIDataSource::Create(chrome::kChromeUITracingHost);
-
- source->SetJsonPath("strings.js");
- source->SetDefaultResource(IDR_TRACING_HTML);
- source->AddResourcePath("tracing.js", IDR_TRACING_JS);
- source->AddLocalizedString("tracingTitle", IDS_TRACING_TITLE);
- return source;
-}
-
-// This class receives javascript messages from the renderer.
-// Note that the WebUI infrastructure runs on the UI thread, therefore all of
-// this class's methods are expected to run on the UI thread.
-class TracingMessageHandler
- : public WebUIMessageHandler,
- public ui::SelectFileDialog::Listener,
- public base::SupportsWeakPtr<TracingMessageHandler>,
- public TraceSubscriber {
- public:
- TracingMessageHandler();
- virtual ~TracingMessageHandler();
-
- // WebUIMessageHandler implementation.
- virtual void RegisterMessages();
-
- // SelectFileDialog::Listener implementation
- virtual void FileSelected(const FilePath& path, int index, void* params);
- virtual void FileSelectionCanceled(void* params);
-
- // TraceSubscriber implementation.
- virtual void OnEndTracingComplete();
- virtual void OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& trace_fragment);
- virtual void OnTraceBufferPercentFullReply(float percent_full);
-
- // Messages.
- void OnTracingControllerInitialized(const ListValue* list);
- void OnBeginTracing(const ListValue* list);
- void OnEndTracingAsync(const ListValue* list);
- void OnBeginRequestBufferPercentFull(const ListValue* list);
- void OnLoadTraceFile(const ListValue* list);
- void OnSaveTraceFile(const ListValue* list);
-
- // Callbacks.
- void LoadTraceFileComplete(string16* file_contents);
- void SaveTraceFileComplete();
-
- private:
- // The file dialog to select a file for loading or saving traces.
- scoped_refptr<ui::SelectFileDialog> select_trace_file_dialog_;
-
- // The type of the file dialog as the same one is used for loading or saving
- // traces.
- ui::SelectFileDialog::Type select_trace_file_dialog_type_;
-
- // The trace data that is to be written to the file on saving.
- scoped_ptr<std::string> trace_data_to_save_;
-
- // True while tracing is active.
- bool trace_enabled_;
-
- // True while system tracing is active.
- bool system_trace_in_progress_;
-
- void OnEndSystemTracingAck(
- const scoped_refptr<base::RefCountedString>& events_str_ptr);
-
- DISALLOW_COPY_AND_ASSIGN(TracingMessageHandler);
-};
-
-// A proxy passed to the Read and Write tasks used when loading or saving trace
-// data.
-class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
- public:
- explicit TaskProxy(const base::WeakPtr<TracingMessageHandler>& handler)
- : handler_(handler) {}
- void LoadTraceFileCompleteProxy(string16* file_contents) {
- if (handler_)
- handler_->LoadTraceFileComplete(file_contents);
- delete file_contents;
- }
-
- void SaveTraceFileCompleteProxy() {
- if (handler_)
- handler_->SaveTraceFileComplete();
- }
-
- private:
- friend class base::RefCountedThreadSafe<TaskProxy>;
- ~TaskProxy() {}
-
- // The message handler to call callbacks on.
- base::WeakPtr<TracingMessageHandler> handler_;
-
- DISALLOW_COPY_AND_ASSIGN(TaskProxy);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// TracingMessageHandler
-//
-////////////////////////////////////////////////////////////////////////////////
-
-TracingMessageHandler::TracingMessageHandler()
- : select_trace_file_dialog_type_(ui::SelectFileDialog::SELECT_NONE),
- trace_enabled_(false),
- system_trace_in_progress_(false) {
-}
-
-TracingMessageHandler::~TracingMessageHandler() {
- if (select_trace_file_dialog_)
- select_trace_file_dialog_->ListenerDestroyed();
-
- // If we are the current subscriber, this will result in ending tracing.
- TraceController::GetInstance()->CancelSubscriber(this);
-
- // Shutdown any system tracing too.
- if (system_trace_in_progress_) {
-#if defined(OS_CHROMEOS)
- chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
- RequestStopSystemTracing(
- chromeos::DebugDaemonClient::EmptyStopSystemTracingCallback());
-#endif
- }
-}
-
-void TracingMessageHandler::RegisterMessages() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- web_ui()->RegisterMessageCallback("tracingControllerInitialized",
- base::Bind(&TracingMessageHandler::OnTracingControllerInitialized,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback("beginTracing",
- base::Bind(&TracingMessageHandler::OnBeginTracing,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback("endTracingAsync",
- base::Bind(&TracingMessageHandler::OnEndTracingAsync,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback("beginRequestBufferPercentFull",
- base::Bind(&TracingMessageHandler::OnBeginRequestBufferPercentFull,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback("loadTraceFile",
- base::Bind(&TracingMessageHandler::OnLoadTraceFile,
- base::Unretained(this)));
- web_ui()->RegisterMessageCallback("saveTraceFile",
- base::Bind(&TracingMessageHandler::OnSaveTraceFile,
- base::Unretained(this)));
-}
-
-void TracingMessageHandler::OnTracingControllerInitialized(
- const ListValue* args) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // Send the client info to the tracingController
- {
- scoped_ptr<DictionaryValue> dict(new DictionaryValue());
- dict->SetString("version", GetContentClient()->GetProduct());
-
- dict->SetString("command_line",
- CommandLine::ForCurrentProcess()->GetCommandLineString());
-
- web_ui()->CallJavascriptFunction("tracingController.onClientInfoUpdate",
- *dict);
- }
-}
-
-void TracingMessageHandler::OnBeginRequestBufferPercentFull(
- const ListValue* list) {
- TraceController::GetInstance()->GetTraceBufferPercentFullAsync(this);
-}
-
-// A callback used for asynchronously reading a file to a string. Calls the
-// TaskProxy callback when reading is complete.
-void ReadTraceFileCallback(TaskProxy* proxy, const FilePath& path) {
- std::string file_contents;
- if (!file_util::ReadFileToString(path, &file_contents))
- return;
-
- // We need to escape the file contents, because it will go into a javascript
- // quoted string in TracingMessageHandler::LoadTraceFileComplete. We need to
- // escape control characters (to have well-formed javascript statements), as
- // well as \ and ' (the only special characters in a ''-quoted string).
- // Do the escaping on this thread, it may take a little while for big files
- // and we don't want to block the UI during that time. Also do the UTF-16
- // conversion here.
- // Note: we're using UTF-16 because we'll need to cut the string into slices
- // to give to Javascript, and it's easier to cut than UTF-8 (since JS strings
- // are arrays of 16-bit values, UCS-2 really, whereas we can't cut inside of a
- // multibyte UTF-8 codepoint).
- size_t size = file_contents.size();
- std::string escaped_contents;
- escaped_contents.reserve(size);
- for (size_t i = 0; i < size; ++i) {
- char c = file_contents[i];
- if (c < ' ') {
- escaped_contents += base::StringPrintf("\\u%04x", c);
- continue;
- }
- if (c == '\\' || c == '\'')
- escaped_contents.push_back('\\');
- escaped_contents.push_back(c);
- }
- file_contents.clear();
-
- scoped_ptr<string16> contents16(new string16);
- UTF8ToUTF16(escaped_contents).swap(*contents16);
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&TaskProxy::LoadTraceFileCompleteProxy, proxy,
- contents16.release()));
-}
-
-// A callback used for asynchronously writing a file from a string. Calls the
-// TaskProxy callback when writing is complete.
-void WriteTraceFileCallback(TaskProxy* proxy,
- const FilePath& path,
- std::string* contents) {
- if (!file_util::WriteFile(path, contents->c_str(), contents->size()))
- return;
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&TaskProxy::SaveTraceFileCompleteProxy, proxy));
-}
-
-void TracingMessageHandler::FileSelected(
- const FilePath& path, int index, void* params) {
- if (select_trace_file_dialog_type_ ==
- ui::SelectFileDialog::SELECT_OPEN_FILE) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&ReadTraceFileCallback,
- make_scoped_refptr(new TaskProxy(AsWeakPtr())), path));
- } else {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- base::Bind(&WriteTraceFileCallback,
- make_scoped_refptr(new TaskProxy(AsWeakPtr())), path,
- trace_data_to_save_.release()));
- }
-
- select_trace_file_dialog_ = NULL;
-}
-
-void TracingMessageHandler::FileSelectionCanceled(void* params) {
- select_trace_file_dialog_ = NULL;
- if (select_trace_file_dialog_type_ ==
- ui::SelectFileDialog::SELECT_OPEN_FILE) {
- web_ui()->CallJavascriptFunction(
- "tracingController.onLoadTraceFileCanceled");
- } else {
- web_ui()->CallJavascriptFunction(
- "tracingController.onSaveTraceFileCanceled");
- }
-}
-
-void TracingMessageHandler::OnLoadTraceFile(const ListValue* list) {
- // Only allow a single dialog at a time.
- if (select_trace_file_dialog_.get())
- return;
- select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE;
- select_trace_file_dialog_ = ui::SelectFileDialog::Create(
- this,
- GetContentClient()->browser()->CreateSelectFilePolicy(
- web_ui()->GetWebContents()));
- select_trace_file_dialog_->SelectFile(
- ui::SelectFileDialog::SELECT_OPEN_FILE,
- string16(),
- FilePath(),
- NULL, 0, FILE_PATH_LITERAL(""),
- web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL);
-}
-
-void TracingMessageHandler::LoadTraceFileComplete(string16* contents) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // We need to pass contents to tracingController.onLoadTraceFileComplete, but
- // that may be arbitrarily big, and IPCs messages are limited in size. So we
- // need to cut it into pieces and rebuild the string in Javascript.
- // |contents| has already been escaped in ReadTraceFileCallback.
- // IPC::Channel::kMaximumMessageSize is in bytes, and we need to account for
- // overhead.
- const size_t kMaxSize = IPC::Channel::kMaximumMessageSize / 2 - 128;
- string16 first_prefix = UTF8ToUTF16("window.traceData = '");
- string16 prefix = UTF8ToUTF16("window.traceData += '");
- string16 suffix = UTF8ToUTF16("';");
-
- RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost();
- for (size_t i = 0; i < contents->size(); i += kMaxSize) {
- string16 javascript = i == 0 ? first_prefix : prefix;
- javascript += contents->substr(i, kMaxSize) + suffix;
- rvh->ExecuteJavascriptInWebFrame(string16(), javascript);
- }
- rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(
- "tracingController.onLoadTraceFileComplete(JSON.parse(window.traceData));"
- "delete window.traceData;"));
-}
-
-void TracingMessageHandler::OnSaveTraceFile(const ListValue* list) {
- // Only allow a single dialog at a time.
- if (select_trace_file_dialog_.get())
- return;
-
- DCHECK(list->GetSize() == 1);
-
- std::string* trace_data = new std::string();
- bool ok = list->GetString(0, trace_data);
- DCHECK(ok);
- trace_data_to_save_.reset(trace_data);
-
- select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE;
- select_trace_file_dialog_ = ui::SelectFileDialog::Create(
- this,
- GetContentClient()->browser()->CreateSelectFilePolicy(
- web_ui()->GetWebContents()));
- select_trace_file_dialog_->SelectFile(
- ui::SelectFileDialog::SELECT_SAVEAS_FILE,
- string16(),
- FilePath(),
- NULL, 0, FILE_PATH_LITERAL(""),
- web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL);
-}
-
-void TracingMessageHandler::SaveTraceFileComplete() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- web_ui()->CallJavascriptFunction("tracingController.onSaveTraceFileComplete");
-}
-
-void TracingMessageHandler::OnBeginTracing(const ListValue* args) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK_EQ(args->GetSize(), (size_t) 2);
-
- bool system_tracing_requested = false;
- bool ok = args->GetBoolean(0, &system_tracing_requested);
- DCHECK(ok);
-
- std::string chrome_categories;
- ok = args->GetString(1, &chrome_categories);
- DCHECK(ok);
-
- trace_enabled_ = true;
- // TODO(jbates) This may fail, but that's OK for current use cases.
- // Ex: Multiple about:gpu traces can not trace simultaneously.
- // TODO(nduca) send feedback to javascript about whether or not BeginTracing
- // was successful.
- TraceController::GetInstance()->BeginTracing(this, chrome_categories);
-
- if (system_tracing_requested) {
-#if defined(OS_CHROMEOS)
- DCHECK(!system_trace_in_progress_);
- chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
- StartSystemTracing();
- // TODO(sleffler) async, could wait for completion
- system_trace_in_progress_ = true;
-#endif
- }
-}
-
-void TracingMessageHandler::OnEndTracingAsync(const ListValue* list) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // TODO(nduca): fix javascript code to make sure trace_enabled_ is always true
- // here. triggered a false condition by just clicking stop
- // trace a few times when it was going slow, and maybe switching
- // between tabs.
- if (trace_enabled_ &&
- !TraceController::GetInstance()->EndTracingAsync(this)) {
- // Set to false now, since it turns out we never were the trace subscriber.
- OnEndTracingComplete();
- }
-}
-
-void TracingMessageHandler::OnEndTracingComplete() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- trace_enabled_ = false;
- if (system_trace_in_progress_) {
- // 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.
- system_trace_in_progress_ = false;
-#if defined(OS_CHROMEOS)
- chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()->
- RequestStopSystemTracing(
- base::Bind(&TracingMessageHandler::OnEndSystemTracingAck,
- base::Unretained(this)));
- return;
-#endif
- }
- web_ui()->CallJavascriptFunction("tracingController.onEndTracingComplete");
-}
-
-void TracingMessageHandler::OnEndSystemTracingAck(
- const scoped_refptr<base::RefCountedString>& events_str_ptr) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- web_ui()->CallJavascriptFunction(
- "tracingController.onSystemTraceDataCollected",
- *scoped_ptr<Value>(Value::CreateStringValue(events_str_ptr->data())));
- DCHECK(!system_trace_in_progress_);
-
- OnEndTracingComplete();
-}
-
-void TracingMessageHandler::OnTraceDataCollected(
- const scoped_refptr<base::RefCountedString>& trace_fragment) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- base::debug::TraceResultBuffer::SimpleOutput output;
- base::debug::TraceResultBuffer trace_buffer;
- trace_buffer.SetOutputCallback(output.GetCallback());
- output.Append("tracingController.onTraceDataCollected(");
- trace_buffer.Start();
- trace_buffer.AddFragment(trace_fragment->data());
- trace_buffer.Finish();
- output.Append(");");
-
- web_ui()->GetWebContents()->GetRenderViewHost()->
- ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(output.json_output));
-}
-
-void TracingMessageHandler::OnTraceBufferPercentFullReply(float percent_full) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- web_ui()->CallJavascriptFunction(
- "tracingController.onRequestBufferPercentFullComplete",
- *scoped_ptr<Value>(Value::CreateDoubleValue(percent_full)));
-}
-
-} // namespace
-
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// TracingUI
-//
-////////////////////////////////////////////////////////////////////////////////
-
-TracingUI::TracingUI(WebUI* web_ui) : WebUIController(web_ui) {
- web_ui->AddMessageHandler(new TracingMessageHandler());
-
- // Set up the chrome://tracing/ source.
- BrowserContext* browser_context =
- web_ui->GetWebContents()->GetBrowserContext();
- WebUIDataSource::Add(browser_context, CreateTracingHTMLSource());
-}
-
-} // namespace content
« no previous file with comments | « content/browser/tracing/tracing_ui.h ('k') | content/browser/webui/content_web_ui_controller_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698