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 |