| 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 "content/browser/tracing/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" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 void* params); | 70 void* params); |
| 71 virtual void FileSelectionCanceled(void* params); | 71 virtual void FileSelectionCanceled(void* params); |
| 72 | 72 |
| 73 // TraceSubscriber implementation. | 73 // TraceSubscriber implementation. |
| 74 virtual void OnEndTracingComplete(); | 74 virtual void OnEndTracingComplete(); |
| 75 virtual void OnTraceDataCollected( | 75 virtual void OnTraceDataCollected( |
| 76 const scoped_refptr<base::RefCountedString>& trace_fragment); | 76 const scoped_refptr<base::RefCountedString>& trace_fragment); |
| 77 virtual void OnTraceBufferPercentFullReply(float percent_full); | 77 virtual void OnTraceBufferPercentFullReply(float percent_full); |
| 78 | 78 |
| 79 // Messages. | 79 // Messages. |
| 80 void OnTracingControllerInitialized(const ListValue* list); | 80 void OnTracingControllerInitialized(const base::ListValue* list); |
| 81 void OnBeginTracing(const ListValue* list); | 81 void OnBeginTracing(const base::ListValue* list); |
| 82 void OnEndTracingAsync(const ListValue* list); | 82 void OnEndTracingAsync(const base::ListValue* list); |
| 83 void OnBeginRequestBufferPercentFull(const ListValue* list); | 83 void OnBeginRequestBufferPercentFull(const base::ListValue* list); |
| 84 void OnLoadTraceFile(const ListValue* list); | 84 void OnLoadTraceFile(const base::ListValue* list); |
| 85 void OnSaveTraceFile(const ListValue* list); | 85 void OnSaveTraceFile(const base::ListValue* list); |
| 86 | 86 |
| 87 // Callbacks. | 87 // Callbacks. |
| 88 void LoadTraceFileComplete(string16* file_contents); | 88 void LoadTraceFileComplete(string16* file_contents); |
| 89 void SaveTraceFileComplete(); | 89 void SaveTraceFileComplete(); |
| 90 | 90 |
| 91 private: | 91 private: |
| 92 // The file dialog to select a file for loading or saving traces. | 92 // The file dialog to select a file for loading or saving traces. |
| 93 scoped_refptr<ui::SelectFileDialog> select_trace_file_dialog_; | 93 scoped_refptr<ui::SelectFileDialog> select_trace_file_dialog_; |
| 94 | 94 |
| 95 // The type of the file dialog as the same one is used for loading or saving | 95 // The type of the file dialog as the same one is used for loading or saving |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 base::Unretained(this))); | 184 base::Unretained(this))); |
| 185 web_ui()->RegisterMessageCallback("loadTraceFile", | 185 web_ui()->RegisterMessageCallback("loadTraceFile", |
| 186 base::Bind(&TracingMessageHandler::OnLoadTraceFile, | 186 base::Bind(&TracingMessageHandler::OnLoadTraceFile, |
| 187 base::Unretained(this))); | 187 base::Unretained(this))); |
| 188 web_ui()->RegisterMessageCallback("saveTraceFile", | 188 web_ui()->RegisterMessageCallback("saveTraceFile", |
| 189 base::Bind(&TracingMessageHandler::OnSaveTraceFile, | 189 base::Bind(&TracingMessageHandler::OnSaveTraceFile, |
| 190 base::Unretained(this))); | 190 base::Unretained(this))); |
| 191 } | 191 } |
| 192 | 192 |
| 193 void TracingMessageHandler::OnTracingControllerInitialized( | 193 void TracingMessageHandler::OnTracingControllerInitialized( |
| 194 const ListValue* args) { | 194 const base::ListValue* args) { |
| 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 196 | 196 |
| 197 // Send the client info to the tracingController | 197 // Send the client info to the tracingController |
| 198 { | 198 { |
| 199 scoped_ptr<DictionaryValue> dict(new DictionaryValue()); | 199 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 200 dict->SetString("version", GetContentClient()->GetProduct()); | 200 dict->SetString("version", GetContentClient()->GetProduct()); |
| 201 | 201 |
| 202 dict->SetString("command_line", | 202 dict->SetString("command_line", |
| 203 CommandLine::ForCurrentProcess()->GetCommandLineString()); | 203 CommandLine::ForCurrentProcess()->GetCommandLineString()); |
| 204 | 204 |
| 205 web_ui()->CallJavascriptFunction("tracingController.onClientInfoUpdate", | 205 web_ui()->CallJavascriptFunction("tracingController.onClientInfoUpdate", |
| 206 *dict); | 206 *dict); |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 | 209 |
| 210 void TracingMessageHandler::OnBeginRequestBufferPercentFull( | 210 void TracingMessageHandler::OnBeginRequestBufferPercentFull( |
| 211 const ListValue* list) { | 211 const base::ListValue* list) { |
| 212 TraceController::GetInstance()->GetTraceBufferPercentFullAsync(this); | 212 TraceController::GetInstance()->GetTraceBufferPercentFullAsync(this); |
| 213 } | 213 } |
| 214 | 214 |
| 215 // A callback used for asynchronously reading a file to a string. Calls the | 215 // A callback used for asynchronously reading a file to a string. Calls the |
| 216 // TaskProxy callback when reading is complete. | 216 // TaskProxy callback when reading is complete. |
| 217 void ReadTraceFileCallback(TaskProxy* proxy, const base::FilePath& path) { | 217 void ReadTraceFileCallback(TaskProxy* proxy, const base::FilePath& path) { |
| 218 std::string file_contents; | 218 std::string file_contents; |
| 219 if (!file_util::ReadFileToString(path, &file_contents)) | 219 if (!file_util::ReadFileToString(path, &file_contents)) |
| 220 return; | 220 return; |
| 221 | 221 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 if (select_trace_file_dialog_type_ == | 291 if (select_trace_file_dialog_type_ == |
| 292 ui::SelectFileDialog::SELECT_OPEN_FILE) { | 292 ui::SelectFileDialog::SELECT_OPEN_FILE) { |
| 293 web_ui()->CallJavascriptFunction( | 293 web_ui()->CallJavascriptFunction( |
| 294 "tracingController.onLoadTraceFileCanceled"); | 294 "tracingController.onLoadTraceFileCanceled"); |
| 295 } else { | 295 } else { |
| 296 web_ui()->CallJavascriptFunction( | 296 web_ui()->CallJavascriptFunction( |
| 297 "tracingController.onSaveTraceFileCanceled"); | 297 "tracingController.onSaveTraceFileCanceled"); |
| 298 } | 298 } |
| 299 } | 299 } |
| 300 | 300 |
| 301 void TracingMessageHandler::OnLoadTraceFile(const ListValue* list) { | 301 void TracingMessageHandler::OnLoadTraceFile(const base::ListValue* list) { |
| 302 // Only allow a single dialog at a time. | 302 // Only allow a single dialog at a time. |
| 303 if (select_trace_file_dialog_.get()) | 303 if (select_trace_file_dialog_.get()) |
| 304 return; | 304 return; |
| 305 select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; | 305 select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_OPEN_FILE; |
| 306 select_trace_file_dialog_ = ui::SelectFileDialog::Create( | 306 select_trace_file_dialog_ = ui::SelectFileDialog::Create( |
| 307 this, | 307 this, |
| 308 GetContentClient()->browser()->CreateSelectFilePolicy( | 308 GetContentClient()->browser()->CreateSelectFilePolicy( |
| 309 web_ui()->GetWebContents())); | 309 web_ui()->GetWebContents())); |
| 310 select_trace_file_dialog_->SelectFile( | 310 select_trace_file_dialog_->SelectFile( |
| 311 ui::SelectFileDialog::SELECT_OPEN_FILE, | 311 ui::SelectFileDialog::SELECT_OPEN_FILE, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 333 for (size_t i = 0; i < contents->size(); i += kMaxSize) { | 333 for (size_t i = 0; i < contents->size(); i += kMaxSize) { |
| 334 string16 javascript = i == 0 ? first_prefix : prefix; | 334 string16 javascript = i == 0 ? first_prefix : prefix; |
| 335 javascript += contents->substr(i, kMaxSize) + suffix; | 335 javascript += contents->substr(i, kMaxSize) + suffix; |
| 336 rvh->ExecuteJavascriptInWebFrame(string16(), javascript); | 336 rvh->ExecuteJavascriptInWebFrame(string16(), javascript); |
| 337 } | 337 } |
| 338 rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16( | 338 rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16( |
| 339 "tracingController.onLoadTraceFileComplete(JSON.parse(window.traceData));" | 339 "tracingController.onLoadTraceFileComplete(JSON.parse(window.traceData));" |
| 340 "delete window.traceData;")); | 340 "delete window.traceData;")); |
| 341 } | 341 } |
| 342 | 342 |
| 343 void TracingMessageHandler::OnSaveTraceFile(const ListValue* list) { | 343 void TracingMessageHandler::OnSaveTraceFile(const base::ListValue* list) { |
| 344 // Only allow a single dialog at a time. | 344 // Only allow a single dialog at a time. |
| 345 if (select_trace_file_dialog_.get()) | 345 if (select_trace_file_dialog_.get()) |
| 346 return; | 346 return; |
| 347 | 347 |
| 348 DCHECK(list->GetSize() == 1); | 348 DCHECK(list->GetSize() == 1); |
| 349 | 349 |
| 350 std::string* trace_data = new std::string(); | 350 std::string* trace_data = new std::string(); |
| 351 bool ok = list->GetString(0, trace_data); | 351 bool ok = list->GetString(0, trace_data); |
| 352 DCHECK(ok); | 352 DCHECK(ok); |
| 353 trace_data_to_save_.reset(trace_data); | 353 trace_data_to_save_.reset(trace_data); |
| 354 | 354 |
| 355 select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE; | 355 select_trace_file_dialog_type_ = ui::SelectFileDialog::SELECT_SAVEAS_FILE; |
| 356 select_trace_file_dialog_ = ui::SelectFileDialog::Create( | 356 select_trace_file_dialog_ = ui::SelectFileDialog::Create( |
| 357 this, | 357 this, |
| 358 GetContentClient()->browser()->CreateSelectFilePolicy( | 358 GetContentClient()->browser()->CreateSelectFilePolicy( |
| 359 web_ui()->GetWebContents())); | 359 web_ui()->GetWebContents())); |
| 360 select_trace_file_dialog_->SelectFile( | 360 select_trace_file_dialog_->SelectFile( |
| 361 ui::SelectFileDialog::SELECT_SAVEAS_FILE, | 361 ui::SelectFileDialog::SELECT_SAVEAS_FILE, |
| 362 string16(), | 362 string16(), |
| 363 base::FilePath(), | 363 base::FilePath(), |
| 364 NULL, 0, FILE_PATH_LITERAL(""), | 364 NULL, 0, FILE_PATH_LITERAL(""), |
| 365 web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL); | 365 web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), NULL); |
| 366 } | 366 } |
| 367 | 367 |
| 368 void TracingMessageHandler::SaveTraceFileComplete() { | 368 void TracingMessageHandler::SaveTraceFileComplete() { |
| 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 370 web_ui()->CallJavascriptFunction("tracingController.onSaveTraceFileComplete"); | 370 web_ui()->CallJavascriptFunction("tracingController.onSaveTraceFileComplete"); |
| 371 } | 371 } |
| 372 | 372 |
| 373 void TracingMessageHandler::OnBeginTracing(const ListValue* args) { | 373 void TracingMessageHandler::OnBeginTracing(const base::ListValue* args) { |
| 374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 375 DCHECK_EQ(args->GetSize(), (size_t) 2); | 375 DCHECK_EQ(args->GetSize(), (size_t) 2); |
| 376 | 376 |
| 377 bool system_tracing_requested = false; | 377 bool system_tracing_requested = false; |
| 378 bool ok = args->GetBoolean(0, &system_tracing_requested); | 378 bool ok = args->GetBoolean(0, &system_tracing_requested); |
| 379 DCHECK(ok); | 379 DCHECK(ok); |
| 380 | 380 |
| 381 std::string chrome_categories; | 381 std::string chrome_categories; |
| 382 ok = args->GetString(1, &chrome_categories); | 382 ok = args->GetString(1, &chrome_categories); |
| 383 DCHECK(ok); | 383 DCHECK(ok); |
| 384 | 384 |
| 385 trace_enabled_ = true; | 385 trace_enabled_ = true; |
| 386 // TODO(jbates) This may fail, but that's OK for current use cases. | 386 // TODO(jbates) This may fail, but that's OK for current use cases. |
| 387 // Ex: Multiple about:gpu traces can not trace simultaneously. | 387 // Ex: Multiple about:gpu traces can not trace simultaneously. |
| 388 // TODO(nduca) send feedback to javascript about whether or not BeginTracing | 388 // TODO(nduca) send feedback to javascript about whether or not BeginTracing |
| 389 // was successful. | 389 // was successful. |
| 390 TraceController::GetInstance()->BeginTracing(this, chrome_categories); | 390 TraceController::GetInstance()->BeginTracing(this, chrome_categories); |
| 391 | 391 |
| 392 if (system_tracing_requested) { | 392 if (system_tracing_requested) { |
| 393 #if defined(OS_CHROMEOS) | 393 #if defined(OS_CHROMEOS) |
| 394 DCHECK(!system_trace_in_progress_); | 394 DCHECK(!system_trace_in_progress_); |
| 395 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> | 395 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()-> |
| 396 StartSystemTracing(); | 396 StartSystemTracing(); |
| 397 // TODO(sleffler) async, could wait for completion | 397 // TODO(sleffler) async, could wait for completion |
| 398 system_trace_in_progress_ = true; | 398 system_trace_in_progress_ = true; |
| 399 #endif | 399 #endif |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 | 402 |
| 403 void TracingMessageHandler::OnEndTracingAsync(const ListValue* list) { | 403 void TracingMessageHandler::OnEndTracingAsync(const base::ListValue* list) { |
| 404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 405 | 405 |
| 406 // TODO(nduca): fix javascript code to make sure trace_enabled_ is always true | 406 // TODO(nduca): fix javascript code to make sure trace_enabled_ is always true |
| 407 // here. triggered a false condition by just clicking stop | 407 // here. triggered a false condition by just clicking stop |
| 408 // trace a few times when it was going slow, and maybe switching | 408 // trace a few times when it was going slow, and maybe switching |
| 409 // between tabs. | 409 // between tabs. |
| 410 if (trace_enabled_ && | 410 if (trace_enabled_ && |
| 411 !TraceController::GetInstance()->EndTracingAsync(this)) { | 411 !TraceController::GetInstance()->EndTracingAsync(this)) { |
| 412 // Set to false now, since it turns out we never were the trace subscriber. | 412 // Set to false now, since it turns out we never were the trace subscriber. |
| 413 OnEndTracingComplete(); | 413 OnEndTracingComplete(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 435 } | 435 } |
| 436 web_ui()->CallJavascriptFunction("tracingController.onEndTracingComplete"); | 436 web_ui()->CallJavascriptFunction("tracingController.onEndTracingComplete"); |
| 437 } | 437 } |
| 438 | 438 |
| 439 void TracingMessageHandler::OnEndSystemTracingAck( | 439 void TracingMessageHandler::OnEndSystemTracingAck( |
| 440 const scoped_refptr<base::RefCountedString>& events_str_ptr) { | 440 const scoped_refptr<base::RefCountedString>& events_str_ptr) { |
| 441 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 441 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 442 | 442 |
| 443 web_ui()->CallJavascriptFunction( | 443 web_ui()->CallJavascriptFunction( |
| 444 "tracingController.onSystemTraceDataCollected", | 444 "tracingController.onSystemTraceDataCollected", |
| 445 *scoped_ptr<Value>(Value::CreateStringValue(events_str_ptr->data()))); | 445 *scoped_ptr<base::Value>(new base::StringValue(events_str_ptr->data()))); |
| 446 DCHECK(!system_trace_in_progress_); | 446 DCHECK(!system_trace_in_progress_); |
| 447 | 447 |
| 448 OnEndTracingComplete(); | 448 OnEndTracingComplete(); |
| 449 } | 449 } |
| 450 | 450 |
| 451 void TracingMessageHandler::OnTraceDataCollected( | 451 void TracingMessageHandler::OnTraceDataCollected( |
| 452 const scoped_refptr<base::RefCountedString>& trace_fragment) { | 452 const scoped_refptr<base::RefCountedString>& trace_fragment) { |
| 453 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 453 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 454 | 454 |
| 455 base::debug::TraceResultBuffer::SimpleOutput output; | 455 base::debug::TraceResultBuffer::SimpleOutput output; |
| 456 base::debug::TraceResultBuffer trace_buffer; | 456 base::debug::TraceResultBuffer trace_buffer; |
| 457 trace_buffer.SetOutputCallback(output.GetCallback()); | 457 trace_buffer.SetOutputCallback(output.GetCallback()); |
| 458 output.Append("tracingController.onTraceDataCollected("); | 458 output.Append("tracingController.onTraceDataCollected("); |
| 459 trace_buffer.Start(); | 459 trace_buffer.Start(); |
| 460 trace_buffer.AddFragment(trace_fragment->data()); | 460 trace_buffer.AddFragment(trace_fragment->data()); |
| 461 trace_buffer.Finish(); | 461 trace_buffer.Finish(); |
| 462 output.Append(");"); | 462 output.Append(");"); |
| 463 | 463 |
| 464 web_ui()->GetWebContents()->GetRenderViewHost()-> | 464 web_ui()->GetWebContents()->GetRenderViewHost()-> |
| 465 ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(output.json_output)); | 465 ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(output.json_output)); |
| 466 } | 466 } |
| 467 | 467 |
| 468 void TracingMessageHandler::OnTraceBufferPercentFullReply(float percent_full) { | 468 void TracingMessageHandler::OnTraceBufferPercentFullReply(float percent_full) { |
| 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 469 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 470 web_ui()->CallJavascriptFunction( | 470 web_ui()->CallJavascriptFunction( |
| 471 "tracingController.onRequestBufferPercentFullComplete", | 471 "tracingController.onRequestBufferPercentFullComplete", |
| 472 *scoped_ptr<Value>(Value::CreateDoubleValue(percent_full))); | 472 *scoped_ptr<base::Value>(new base::FundamentalValue(percent_full))); |
| 473 } | 473 } |
| 474 | 474 |
| 475 } // namespace | 475 } // namespace |
| 476 | 476 |
| 477 | 477 |
| 478 //////////////////////////////////////////////////////////////////////////////// | 478 //////////////////////////////////////////////////////////////////////////////// |
| 479 // | 479 // |
| 480 // TracingUI | 480 // TracingUI |
| 481 // | 481 // |
| 482 //////////////////////////////////////////////////////////////////////////////// | 482 //////////////////////////////////////////////////////////////////////////////// |
| 483 | 483 |
| 484 TracingUI::TracingUI(WebUI* web_ui) : WebUIController(web_ui) { | 484 TracingUI::TracingUI(WebUI* web_ui) : WebUIController(web_ui) { |
| 485 web_ui->AddMessageHandler(new TracingMessageHandler()); | 485 web_ui->AddMessageHandler(new TracingMessageHandler()); |
| 486 | 486 |
| 487 // Set up the chrome://tracing/ source. | 487 // Set up the chrome://tracing/ source. |
| 488 BrowserContext* browser_context = | 488 BrowserContext* browser_context = |
| 489 web_ui->GetWebContents()->GetBrowserContext(); | 489 web_ui->GetWebContents()->GetBrowserContext(); |
| 490 WebUIDataSource::Add(browser_context, CreateTracingHTMLSource()); | 490 WebUIDataSource::Add(browser_context, CreateTracingHTMLSource()); |
| 491 } | 491 } |
| 492 | 492 |
| 493 } // namespace content | 493 } // namespace content |
| OLD | NEW |