| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 | 4 |
| 5 #include "chrome/browser/ui/webui/tracing_ui.h" | 5 #include "content/browser/tracing/tracing_ui.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
| 13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
| 16 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
| 17 #include "base/utf_string_conversions.h" | 17 #include "base/utf_string_conversions.h" |
| 18 #include "base/values.h" | 18 #include "base/values.h" |
| 19 #include "chrome/browser/profiles/profile.h" | |
| 20 #include "chrome/browser/ui/chrome_select_file_policy.h" | |
| 21 #include "chrome/common/chrome_version_info.h" | |
| 22 #include "chrome/common/url_constants.h" | |
| 23 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 20 #include "content/public/browser/content_browser_client.h" |
| 24 #include "content/public/browser/render_view_host.h" | 21 #include "content/public/browser/render_view_host.h" |
| 25 #include "content/public/browser/trace_controller.h" | 22 #include "content/public/browser/trace_controller.h" |
| 26 #include "content/public/browser/trace_subscriber.h" | 23 #include "content/public/browser/trace_subscriber.h" |
| 27 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
| 28 #include "content/public/browser/web_contents_view.h" | 25 #include "content/public/browser/web_contents_view.h" |
| 29 #include "content/public/browser/web_ui.h" | 26 #include "content/public/browser/web_ui.h" |
| 30 #include "content/public/browser/web_ui_data_source.h" | 27 #include "content/public/browser/web_ui_data_source.h" |
| 31 #include "content/public/browser/web_ui_message_handler.h" | 28 #include "content/public/browser/web_ui_message_handler.h" |
| 32 #include "grit/browser_resources.h" | 29 #include "content/public/common/url_constants.h" |
| 33 #include "grit/generated_resources.h" | 30 #include "grit/content_resources.h" |
| 34 #include "ipc/ipc_channel.h" | 31 #include "ipc/ipc_channel.h" |
| 35 #include "ui/base/l10n/l10n_util.h" | |
| 36 #include "ui/shell_dialogs/select_file_dialog.h" | 32 #include "ui/shell_dialogs/select_file_dialog.h" |
| 37 | 33 |
| 38 #if defined(OS_CHROMEOS) | 34 #if defined(OS_CHROMEOS) |
| 39 #include "chromeos/dbus/dbus_thread_manager.h" | 35 #include "chromeos/dbus/dbus_thread_manager.h" |
| 40 #include "chromeos/dbus/debug_daemon_client.h" | 36 #include "chromeos/dbus/debug_daemon_client.h" |
| 41 #endif | 37 #endif |
| 42 | 38 |
| 43 using content::BrowserThread; | 39 namespace content { |
| 44 using content::TraceController; | |
| 45 using content::WebContents; | |
| 46 using content::WebUIMessageHandler; | |
| 47 | |
| 48 namespace { | 40 namespace { |
| 49 | 41 |
| 50 content::WebUIDataSource* CreateTracingHTMLSource() { | 42 WebUIDataSource* CreateTracingHTMLSource() { |
| 51 content::WebUIDataSource* source = | 43 WebUIDataSource* source = |
| 52 content::WebUIDataSource::Create(chrome::kChromeUITracingHost); | 44 WebUIDataSource::Create(chrome::kChromeUITracingHost); |
| 53 | 45 |
| 54 source->SetJsonPath("strings.js"); | 46 source->SetJsonPath("strings.js"); |
| 55 source->SetDefaultResource(IDR_TRACING_HTML); | 47 source->SetDefaultResource(IDR_TRACING_HTML); |
| 56 source->AddResourcePath("tracing.js", IDR_TRACING_JS); | 48 source->AddResourcePath("tracing.js", IDR_TRACING_JS); |
| 57 source->AddLocalizedString("tracingTitle", IDS_TRACING_TITLE); | 49 source->AddLocalizedString("tracingTitle", IDS_TRACING_TITLE); |
| 58 return source; | 50 return source; |
| 59 } | 51 } |
| 60 | 52 |
| 61 // This class receives javascript messages from the renderer. | 53 // This class receives javascript messages from the renderer. |
| 62 // Note that the WebUI infrastructure runs on the UI thread, therefore all of | 54 // Note that the WebUI infrastructure runs on the UI thread, therefore all of |
| 63 // this class's methods are expected to run on the UI thread. | 55 // this class's methods are expected to run on the UI thread. |
| 64 class TracingMessageHandler | 56 class TracingMessageHandler |
| 65 : public WebUIMessageHandler, | 57 : public WebUIMessageHandler, |
| 66 public ui::SelectFileDialog::Listener, | 58 public ui::SelectFileDialog::Listener, |
| 67 public base::SupportsWeakPtr<TracingMessageHandler>, | 59 public base::SupportsWeakPtr<TracingMessageHandler>, |
| 68 public content::TraceSubscriber { | 60 public TraceSubscriber { |
| 69 public: | 61 public: |
| 70 TracingMessageHandler(); | 62 TracingMessageHandler(); |
| 71 virtual ~TracingMessageHandler(); | 63 virtual ~TracingMessageHandler(); |
| 72 | 64 |
| 73 // WebUIMessageHandler implementation. | 65 // WebUIMessageHandler implementation. |
| 74 virtual void RegisterMessages(); | 66 virtual void RegisterMessages(); |
| 75 | 67 |
| 76 // SelectFileDialog::Listener implementation | 68 // SelectFileDialog::Listener implementation |
| 77 virtual void FileSelected(const FilePath& path, int index, void* params); | 69 virtual void FileSelected(const FilePath& path, int index, void* params); |
| 78 virtual void FileSelectionCanceled(void* params); | 70 virtual void FileSelectionCanceled(void* params); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 base::Unretained(this))); | 189 base::Unretained(this))); |
| 198 } | 190 } |
| 199 | 191 |
| 200 void TracingMessageHandler::OnTracingControllerInitialized( | 192 void TracingMessageHandler::OnTracingControllerInitialized( |
| 201 const ListValue* args) { | 193 const ListValue* args) { |
| 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 203 | 195 |
| 204 // Send the client info to the tracingController | 196 // Send the client info to the tracingController |
| 205 { | 197 { |
| 206 scoped_ptr<DictionaryValue> dict(new DictionaryValue()); | 198 scoped_ptr<DictionaryValue> dict(new DictionaryValue()); |
| 207 chrome::VersionInfo version_info; | 199 dict->SetString("version", GetContentClient()->GetProduct()); |
| 208 | 200 |
| 209 if (!version_info.is_valid()) { | 201 dict->SetString("command_line", |
| 210 DLOG(ERROR) << "Unable to create chrome::VersionInfo"; | 202 CommandLine::ForCurrentProcess()->GetCommandLineString()); |
| 211 } else { | |
| 212 // We have everything we need to send the right values. | |
| 213 dict->SetString("version", version_info.Version()); | |
| 214 dict->SetString("cl", version_info.LastChange()); | |
| 215 dict->SetString("version_mod", | |
| 216 chrome::VersionInfo::GetVersionStringModifier()); | |
| 217 dict->SetString("official", | |
| 218 l10n_util::GetStringUTF16( | |
| 219 version_info.IsOfficialBuild() ? | |
| 220 IDS_ABOUT_VERSION_OFFICIAL : | |
| 221 IDS_ABOUT_VERSION_UNOFFICIAL)); | |
| 222 | |
| 223 dict->SetString("command_line", | |
| 224 CommandLine::ForCurrentProcess()->GetCommandLineString()); | |
| 225 } | |
| 226 | 203 |
| 227 web_ui()->CallJavascriptFunction("tracingController.onClientInfoUpdate", | 204 web_ui()->CallJavascriptFunction("tracingController.onClientInfoUpdate", |
| 228 *dict); | 205 *dict); |
| 229 } | 206 } |
| 230 } | 207 } |
| 231 | 208 |
| 232 void TracingMessageHandler::OnBeginRequestBufferPercentFull( | 209 void TracingMessageHandler::OnBeginRequestBufferPercentFull( |
| 233 const ListValue* list) { | 210 const ListValue* list) { |
| 234 TraceController::GetInstance()->GetTraceBufferPercentFullAsync(this); | 211 TraceController::GetInstance()->GetTraceBufferPercentFullAsync(this); |
| 235 } | 212 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 "tracingController.onSaveTraceFileCanceled"); | 296 "tracingController.onSaveTraceFileCanceled"); |
| 320 } | 297 } |
| 321 } | 298 } |
| 322 | 299 |
| 323 void TracingMessageHandler::OnLoadTraceFile(const ListValue* list) { | 300 void TracingMessageHandler::OnLoadTraceFile(const ListValue* list) { |
| 324 // Only allow a single dialog at a time. | 301 // Only allow a single dialog at a time. |
| 325 if (select_trace_file_dialog_.get()) | 302 if (select_trace_file_dialog_.get()) |
| 326 return; | 303 return; |
| 327 select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; | 304 select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; |
| 328 select_trace_file_dialog_ = ui::SelectFileDialog::Create( | 305 select_trace_file_dialog_ = ui::SelectFileDialog::Create( |
| 329 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); | 306 this, |
| 307 GetContentClient()->browser()->CreateSelectFilePolicy( |
| 308 web_ui()->GetWebContents())); |
| 330 select_trace_file_dialog_->SelectFile( | 309 select_trace_file_dialog_->SelectFile( |
| 331 ui::SelectFileDialog::SELECT_OPEN_FILE, | 310 ui::SelectFileDialog::SELECT_OPEN_FILE, |
| 332 string16(), | 311 string16(), |
| 333 FilePath(), | 312 FilePath(), |
| 334 NULL, 0, FILE_PATH_LITERAL(""), | 313 NULL, 0, FILE_PATH_LITERAL(""), |
| 335 web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL); | 314 web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL); |
| 336 } | 315 } |
| 337 | 316 |
| 338 void TracingMessageHandler::LoadTraceFileComplete(string16* contents) { | 317 void TracingMessageHandler::LoadTraceFileComplete(string16* contents) { |
| 339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 340 | 319 |
| 341 // We need to pass contents to tracingController.onLoadTraceFileComplete, but | 320 // We need to pass contents to tracingController.onLoadTraceFileComplete, but |
| 342 // that may be arbitrarily big, and IPCs messages are limited in size. So we | 321 // that may be arbitrarily big, and IPCs messages are limited in size. So we |
| 343 // need to cut it into pieces and rebuild the string in Javascript. | 322 // need to cut it into pieces and rebuild the string in Javascript. |
| 344 // |contents| has already been escaped in ReadTraceFileCallback. | 323 // |contents| has already been escaped in ReadTraceFileCallback. |
| 345 // IPC::Channel::kMaximumMessageSize is in bytes, and we need to account for | 324 // IPC::Channel::kMaximumMessageSize is in bytes, and we need to account for |
| 346 // overhead. | 325 // overhead. |
| 347 const size_t kMaxSize = IPC::Channel::kMaximumMessageSize / 2 - 128; | 326 const size_t kMaxSize = IPC::Channel::kMaximumMessageSize / 2 - 128; |
| 348 string16 first_prefix = UTF8ToUTF16("window.traceData = '"); | 327 string16 first_prefix = UTF8ToUTF16("window.traceData = '"); |
| 349 string16 prefix = UTF8ToUTF16("window.traceData += '"); | 328 string16 prefix = UTF8ToUTF16("window.traceData += '"); |
| 350 string16 suffix = UTF8ToUTF16("';"); | 329 string16 suffix = UTF8ToUTF16("';"); |
| 351 | 330 |
| 352 content::RenderViewHost* rvh = | 331 RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost(); |
| 353 web_ui()->GetWebContents()->GetRenderViewHost(); | |
| 354 for (size_t i = 0; i < contents->size(); i += kMaxSize) { | 332 for (size_t i = 0; i < contents->size(); i += kMaxSize) { |
| 355 string16 javascript = i == 0 ? first_prefix : prefix; | 333 string16 javascript = i == 0 ? first_prefix : prefix; |
| 356 javascript += contents->substr(i, kMaxSize) + suffix; | 334 javascript += contents->substr(i, kMaxSize) + suffix; |
| 357 rvh->ExecuteJavascriptInWebFrame(string16(), javascript); | 335 rvh->ExecuteJavascriptInWebFrame(string16(), javascript); |
| 358 } | 336 } |
| 359 rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16( | 337 rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16( |
| 360 "tracingController.onLoadTraceFileComplete(JSON.parse(window.traceData));" | 338 "tracingController.onLoadTraceFileComplete(JSON.parse(window.traceData));" |
| 361 "delete window.traceData;")); | 339 "delete window.traceData;")); |
| 362 } | 340 } |
| 363 | 341 |
| 364 void TracingMessageHandler::OnSaveTraceFile(const ListValue* list) { | 342 void TracingMessageHandler::OnSaveTraceFile(const ListValue* list) { |
| 365 // Only allow a single dialog at a time. | 343 // Only allow a single dialog at a time. |
| 366 if (select_trace_file_dialog_.get()) | 344 if (select_trace_file_dialog_.get()) |
| 367 return; | 345 return; |
| 368 | 346 |
| 369 DCHECK(list->GetSize() == 1); | 347 DCHECK(list->GetSize() == 1); |
| 370 | 348 |
| 371 std::string* trace_data = new std::string(); | 349 std::string* trace_data = new std::string(); |
| 372 bool ok = list->GetString(0, trace_data); | 350 bool ok = list->GetString(0, trace_data); |
| 373 DCHECK(ok); | 351 DCHECK(ok); |
| 374 trace_data_to_save_.reset(trace_data); | 352 trace_data_to_save_.reset(trace_data); |
| 375 | 353 |
| 376 select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE; | 354 select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE; |
| 377 select_trace_file_dialog_ = ui::SelectFileDialog::Create( | 355 select_trace_file_dialog_ = ui::SelectFileDialog::Create( |
| 378 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents())); | 356 this, |
| 357 GetContentClient()->browser()->CreateSelectFilePolicy( |
| 358 web_ui()->GetWebContents())); |
| 379 select_trace_file_dialog_->SelectFile( | 359 select_trace_file_dialog_->SelectFile( |
| 380 ui::SelectFileDialog::SELECT_SAVEAS_FILE, | 360 ui::SelectFileDialog::SELECT_SAVEAS_FILE, |
| 381 string16(), | 361 string16(), |
| 382 FilePath(), | 362 FilePath(), |
| 383 NULL, 0, FILE_PATH_LITERAL(""), | 363 NULL, 0, FILE_PATH_LITERAL(""), |
| 384 web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL); | 364 web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL); |
| 385 } | 365 } |
| 386 | 366 |
| 387 void TracingMessageHandler::SaveTraceFileComplete() { | 367 void TracingMessageHandler::SaveTraceFileComplete() { |
| 388 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 368 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 | 473 |
| 494 } // namespace | 474 } // namespace |
| 495 | 475 |
| 496 | 476 |
| 497 //////////////////////////////////////////////////////////////////////////////// | 477 //////////////////////////////////////////////////////////////////////////////// |
| 498 // | 478 // |
| 499 // TracingUI | 479 // TracingUI |
| 500 // | 480 // |
| 501 //////////////////////////////////////////////////////////////////////////////// | 481 //////////////////////////////////////////////////////////////////////////////// |
| 502 | 482 |
| 503 TracingUI::TracingUI(content::WebUI* web_ui) : WebUIController(web_ui) { | 483 TracingUI::TracingUI(WebUI* web_ui) : WebUIController(web_ui) { |
| 504 web_ui->AddMessageHandler(new TracingMessageHandler()); | 484 web_ui->AddMessageHandler(new TracingMessageHandler()); |
| 505 | 485 |
| 506 // Set up the chrome://tracing/ source. | 486 // Set up the chrome://tracing/ source. |
| 507 Profile* profile = Profile::FromWebUI(web_ui); | 487 BrowserContext* browser_context = |
| 508 content::WebUIDataSource::Add(profile, CreateTracingHTMLSource()); | 488 web_ui->GetWebContents()->GetBrowserContext(); |
| 489 WebUIDataSource::Add(browser_context, CreateTracingHTMLSource()); |
| 509 } | 490 } |
| 491 |
| 492 } // namespace content |
| OLD | NEW |