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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 // Messages. | 81 // Messages. |
82 void OnTracingControllerInitialized(const base::ListValue* list); | 82 void OnTracingControllerInitialized(const base::ListValue* list); |
83 void OnBeginTracing(const base::ListValue* list); | 83 void OnBeginTracing(const base::ListValue* list); |
84 void OnEndTracingAsync(const base::ListValue* list); | 84 void OnEndTracingAsync(const base::ListValue* list); |
85 void OnBeginRequestBufferPercentFull(const base::ListValue* list); | 85 void OnBeginRequestBufferPercentFull(const base::ListValue* list); |
86 void OnLoadTraceFile(const base::ListValue* list); | 86 void OnLoadTraceFile(const base::ListValue* list); |
87 void OnSaveTraceFile(const base::ListValue* list); | 87 void OnSaveTraceFile(const base::ListValue* list); |
88 void OnGetKnownCategories(const base::ListValue* list); | 88 void OnGetKnownCategories(const base::ListValue* list); |
89 | 89 |
90 // Callbacks. | 90 // Callbacks. |
91 void LoadTraceFileComplete(string16* file_contents); | 91 void LoadTraceFileComplete(string16* file_contents, |
92 const base::FilePath &path); | |
92 void SaveTraceFileComplete(); | 93 void SaveTraceFileComplete(); |
93 | 94 |
94 private: | 95 private: |
95 // The file dialog to select a file for loading or saving traces. | 96 // The file dialog to select a file for loading or saving traces. |
96 scoped_refptr<ui::SelectFileDialog> select_trace_file_dialog_; | 97 scoped_refptr<ui::SelectFileDialog> select_trace_file_dialog_; |
97 | 98 |
98 // The type of the file dialog as the same one is used for loading or saving | 99 // The type of the file dialog as the same one is used for loading or saving |
99 // traces. | 100 // traces. |
100 ui::SelectFileDialog::Type select_trace_file_dialog_type_; | 101 ui::SelectFileDialog::Type select_trace_file_dialog_type_; |
101 | 102 |
(...skipping 11 matching lines...) Expand all Loading... | |
113 | 114 |
114 DISALLOW_COPY_AND_ASSIGN(TracingMessageHandler); | 115 DISALLOW_COPY_AND_ASSIGN(TracingMessageHandler); |
115 }; | 116 }; |
116 | 117 |
117 // A proxy passed to the Read and Write tasks used when loading or saving trace | 118 // A proxy passed to the Read and Write tasks used when loading or saving trace |
118 // data. | 119 // data. |
119 class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { | 120 class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { |
120 public: | 121 public: |
121 explicit TaskProxy(const base::WeakPtr<TracingMessageHandler>& handler) | 122 explicit TaskProxy(const base::WeakPtr<TracingMessageHandler>& handler) |
122 : handler_(handler) {} | 123 : handler_(handler) {} |
123 void LoadTraceFileCompleteProxy(string16* file_contents) { | 124 void LoadTraceFileCompleteProxy(string16* file_contents, |
125 const base::FilePath& path) { | |
124 if (handler_) | 126 if (handler_) |
125 handler_->LoadTraceFileComplete(file_contents); | 127 handler_->LoadTraceFileComplete(file_contents, path); |
126 delete file_contents; | 128 delete file_contents; |
127 } | 129 } |
128 | 130 |
129 void SaveTraceFileCompleteProxy() { | 131 void SaveTraceFileCompleteProxy() { |
130 if (handler_) | 132 if (handler_) |
131 handler_->SaveTraceFileComplete(); | 133 handler_->SaveTraceFileComplete(); |
132 } | 134 } |
133 | 135 |
134 private: | 136 private: |
135 friend class base::RefCountedThreadSafe<TaskProxy>; | 137 friend class base::RefCountedThreadSafe<TaskProxy>; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 escaped_contents.push_back(c); | 252 escaped_contents.push_back(c); |
251 } | 253 } |
252 file_contents.clear(); | 254 file_contents.clear(); |
253 | 255 |
254 scoped_ptr<string16> contents16(new string16); | 256 scoped_ptr<string16> contents16(new string16); |
255 UTF8ToUTF16(escaped_contents).swap(*contents16); | 257 UTF8ToUTF16(escaped_contents).swap(*contents16); |
256 | 258 |
257 BrowserThread::PostTask( | 259 BrowserThread::PostTask( |
258 BrowserThread::UI, FROM_HERE, | 260 BrowserThread::UI, FROM_HERE, |
259 base::Bind(&TaskProxy::LoadTraceFileCompleteProxy, proxy, | 261 base::Bind(&TaskProxy::LoadTraceFileCompleteProxy, proxy, |
260 contents16.release())); | 262 contents16.release(), |
263 path)); | |
261 } | 264 } |
262 | 265 |
263 // A callback used for asynchronously writing a file from a string. Calls the | 266 // A callback used for asynchronously writing a file from a string. Calls the |
264 // TaskProxy callback when writing is complete. | 267 // TaskProxy callback when writing is complete. |
265 void WriteTraceFileCallback(TaskProxy* proxy, | 268 void WriteTraceFileCallback(TaskProxy* proxy, |
266 const base::FilePath& path, | 269 const base::FilePath& path, |
267 std::string* contents) { | 270 std::string* contents) { |
268 if (!file_util::WriteFile(path, contents->c_str(), contents->size())) | 271 if (!file_util::WriteFile(path, contents->c_str(), contents->size())) |
269 return; | 272 return; |
270 | 273 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
317 ui::SelectFileDialog::SELECT_OPEN_FILE, | 320 ui::SelectFileDialog::SELECT_OPEN_FILE, |
318 string16(), | 321 string16(), |
319 base::FilePath(), | 322 base::FilePath(), |
320 NULL, | 323 NULL, |
321 0, | 324 0, |
322 base::FilePath::StringType(), | 325 base::FilePath::StringType(), |
323 web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), | 326 web_ui()->GetWebContents()->GetView()->GetTopLevelNativeWindow(), |
324 NULL); | 327 NULL); |
325 } | 328 } |
326 | 329 |
327 void TracingMessageHandler::LoadTraceFileComplete(string16* contents) { | 330 void TracingMessageHandler::LoadTraceFileComplete(string16* contents, |
331 const base::FilePath& path) { | |
328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 332 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
329 | 333 |
330 // We need to pass contents to tracingController.onLoadTraceFileComplete, but | 334 // We need to pass contents to tracingController.onLoadTraceFileComplete, but |
331 // that may be arbitrarily big, and IPCs messages are limited in size. So we | 335 // that may be arbitrarily big, and IPCs messages are limited in size. So we |
332 // need to cut it into pieces and rebuild the string in Javascript. | 336 // need to cut it into pieces and rebuild the string in Javascript. |
333 // |contents| has already been escaped in ReadTraceFileCallback. | 337 // |contents| has already been escaped in ReadTraceFileCallback. |
334 // IPC::Channel::kMaximumMessageSize is in bytes, and we need to account for | 338 // IPC::Channel::kMaximumMessageSize is in bytes, and we need to account for |
335 // overhead. | 339 // overhead. |
336 const size_t kMaxSize = IPC::Channel::kMaximumMessageSize / 2 - 128; | 340 const size_t kMaxSize = IPC::Channel::kMaximumMessageSize / 2 - 128; |
337 string16 first_prefix = UTF8ToUTF16("window.traceData = '"); | 341 string16 first_prefix = UTF8ToUTF16("window.traceData = '"); |
338 string16 prefix = UTF8ToUTF16("window.traceData += '"); | 342 string16 prefix = UTF8ToUTF16("window.traceData += '"); |
339 string16 suffix = UTF8ToUTF16("';"); | 343 string16 suffix = UTF8ToUTF16("';"); |
340 | 344 |
341 RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost(); | 345 RenderViewHost* rvh = web_ui()->GetWebContents()->GetRenderViewHost(); |
342 for (size_t i = 0; i < contents->size(); i += kMaxSize) { | 346 for (size_t i = 0; i < contents->size(); i += kMaxSize) { |
343 string16 javascript = i == 0 ? first_prefix : prefix; | 347 string16 javascript = i == 0 ? first_prefix : prefix; |
344 javascript += contents->substr(i, kMaxSize) + suffix; | 348 javascript += contents->substr(i, kMaxSize) + suffix; |
345 rvh->ExecuteJavascriptInWebFrame(string16(), javascript); | 349 rvh->ExecuteJavascriptInWebFrame(string16(), javascript); |
346 } | 350 } |
351 | |
352 std::string escaped_path; | |
353 size_t size = path.value().size(); | |
354 escaped_path.reserve(size); | |
355 for (size_t i = 0; i < size; ++i) { | |
356 char c = path.value()[i]; | |
357 if (c < ' ') { | |
358 escaped_path += base::StringPrintf("\\u%04x", c); | |
359 continue; | |
360 } | |
361 if (c == '\\' || c == '\'') | |
362 escaped_path.push_back('\\'); | |
363 escaped_path.push_back(c); | |
364 } | |
365 | |
nduca
2013/05/13 19:43:46
i think if we switch from ExecuteJavascriptInWebFr
| |
347 rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16( | 366 rvh->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16( |
348 "tracingController.onLoadTraceFileComplete(window.traceData);" | 367 "tracingController.onLoadTraceFileComplete(window.traceData,'" + |
368 escaped_path + "');" + | |
349 "delete window.traceData;")); | 369 "delete window.traceData;")); |
350 } | 370 } |
351 | 371 |
352 void TracingMessageHandler::OnSaveTraceFile(const base::ListValue* list) { | 372 void TracingMessageHandler::OnSaveTraceFile(const base::ListValue* list) { |
353 // Only allow a single dialog at a time. | 373 // Only allow a single dialog at a time. |
354 if (select_trace_file_dialog_) | 374 if (select_trace_file_dialog_) |
355 return; | 375 return; |
356 | 376 |
357 DCHECK(list->GetSize() == 1); | 377 DCHECK(list->GetSize() == 1); |
358 | 378 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
544 TracingUI::TracingUI(WebUI* web_ui) : WebUIController(web_ui) { | 564 TracingUI::TracingUI(WebUI* web_ui) : WebUIController(web_ui) { |
545 web_ui->AddMessageHandler(new TracingMessageHandler()); | 565 web_ui->AddMessageHandler(new TracingMessageHandler()); |
546 | 566 |
547 // Set up the chrome://tracing/ source. | 567 // Set up the chrome://tracing/ source. |
548 BrowserContext* browser_context = | 568 BrowserContext* browser_context = |
549 web_ui->GetWebContents()->GetBrowserContext(); | 569 web_ui->GetWebContents()->GetBrowserContext(); |
550 WebUIDataSource::Add(browser_context, CreateTracingHTMLSource()); | 570 WebUIDataSource::Add(browser_context, CreateTracingHTMLSource()); |
551 } | 571 } |
552 | 572 |
553 } // namespace content | 573 } // namespace content |
OLD | NEW |