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

Side by Side Diff: content/shell/browser/shell_devtools_frontend.cc

Issue 969573002: DevTools: response writers need to post to the UI while sending into streams. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@loadNetwork
Patch Set: Created 5 years, 9 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/shell/browser/shell_devtools_frontend.h" 5 #include "content/shell/browser/shell_devtools_frontend.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/lazy_instance.h"
10 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/devtools_http_handler.h" 15 #include "content/public/browser/devtools_http_handler.h"
14 #include "content/public/browser/render_frame_host.h" 16 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/render_view_host.h" 17 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/web_contents.h" 18 #include "content/public/browser/web_contents.h"
17 #include "content/public/common/content_client.h" 19 #include "content/public/common/content_client.h"
18 #include "content/shell/browser/shell.h" 20 #include "content/shell/browser/shell.h"
19 #include "content/shell/browser/shell_browser_context.h" 21 #include "content/shell/browser/shell_browser_context.h"
20 #include "content/shell/browser/shell_browser_main_parts.h" 22 #include "content/shell/browser/shell_browser_main_parts.h"
21 #include "content/shell/browser/shell_content_browser_client.h" 23 #include "content/shell/browser/shell_content_browser_client.h"
22 #include "content/shell/browser/shell_devtools_manager_delegate.h" 24 #include "content/shell/browser/shell_devtools_manager_delegate.h"
23 #include "content/shell/browser/webkit_test_controller.h" 25 #include "content/shell/browser/webkit_test_controller.h"
24 #include "content/shell/common/shell_switches.h" 26 #include "content/shell/common/shell_switches.h"
25 #include "net/base/io_buffer.h" 27 #include "net/base/io_buffer.h"
26 #include "net/base/net_errors.h" 28 #include "net/base/net_errors.h"
27 #include "net/http/http_response_headers.h" 29 #include "net/http/http_response_headers.h"
28 #include "net/url_request/url_fetcher.h" 30 #include "net/url_request/url_fetcher.h"
29 #include "net/url_request/url_fetcher_response_writer.h" 31 #include "net/url_request/url_fetcher_response_writer.h"
30 32
31 namespace content { 33 namespace content {
32 34
33 namespace { 35 namespace {
34 36
37 using StreamOwners = std::map<int, Shell*>;
38 base::LazyInstance<StreamOwners>::Leaky g_stream_owners =
39 LAZY_INSTANCE_INITIALIZER;
35 40
36 // ResponseWriter ------------------------------------------------------------- 41 // ResponseWriter -------------------------------------------------------------
37 42
38 class ResponseWriter : public net::URLFetcherResponseWriter { 43 class ResponseWriter : public net::URLFetcherResponseWriter {
39 public: 44 public:
40 ResponseWriter(Shell* shell, int stream_id); 45 explicit ResponseWriter(int stream_id);
41 ~ResponseWriter() override; 46 ~ResponseWriter() override;
42 47
43 // URLFetcherResponseWriter overrides: 48 // URLFetcherResponseWriter overrides:
44 int Initialize(const net::CompletionCallback& callback) override; 49 int Initialize(const net::CompletionCallback& callback) override;
45 int Write(net::IOBuffer* buffer, 50 int Write(net::IOBuffer* buffer,
46 int num_bytes, 51 int num_bytes,
47 const net::CompletionCallback& callback) override; 52 const net::CompletionCallback& callback) override;
48 int Finish(const net::CompletionCallback& callback) override; 53 int Finish(const net::CompletionCallback& callback) override;
49 54
50 private: 55 private:
51 Shell* shell_;
52 int stream_id_; 56 int stream_id_;
53 57
54 DISALLOW_COPY_AND_ASSIGN(ResponseWriter); 58 DISALLOW_COPY_AND_ASSIGN(ResponseWriter);
55 }; 59 };
56 60
57 ResponseWriter::ResponseWriter(Shell* shell, 61 ResponseWriter::ResponseWriter(int stream_id)
58 int stream_id) 62 : stream_id_(stream_id) {
59 : shell_(shell),
60 stream_id_(stream_id) {
61 } 63 }
62 64
63 ResponseWriter::~ResponseWriter() { 65 ResponseWriter::~ResponseWriter() {
64 } 66 }
65 67
66 int ResponseWriter::Initialize(const net::CompletionCallback& callback) { 68 int ResponseWriter::Initialize(const net::CompletionCallback& callback) {
67 return net::OK; 69 return net::OK;
68 } 70 }
69 71
72 static void RespondOnUI(int stream_id, const std::string& code) {
73 auto it = g_stream_owners.Get().find(stream_id);
74 if (it != g_stream_owners.Get().end()) {
75 it->second->web_contents()->GetMainFrame()->ExecuteJavaScript(
76 base::UTF8ToUTF16(code));
77 }
78 }
79
70 int ResponseWriter::Write(net::IOBuffer* buffer, 80 int ResponseWriter::Write(net::IOBuffer* buffer,
71 int num_bytes, 81 int num_bytes,
72 const net::CompletionCallback& callback) { 82 const net::CompletionCallback& callback) {
73 base::StringValue chunk(std::string(buffer->data(), num_bytes)); 83 base::StringValue chunk(std::string(buffer->data(), num_bytes));
74 std::string encoded; 84 std::string encoded;
75 base::JSONWriter::Write(&chunk, &encoded); 85 base::JSONWriter::Write(&chunk, &encoded);
76
77 std::string code = base::StringPrintf( 86 std::string code = base::StringPrintf(
78 "DevToolsAPI.streamWrite(%d, %s)", stream_id_, encoded.c_str()); 87 "DevToolsAPI.streamWrite(%d, %s)", stream_id_, encoded.c_str());
79 shell_->web_contents()->GetMainFrame()->ExecuteJavaScript(
80 base::UTF8ToUTF16(code));
81 88
89 content::BrowserThread::PostTask(
90 content::BrowserThread::UI, FROM_HERE,
91 base::Bind(&RespondOnUI, stream_id_, code));
82 return num_bytes; 92 return num_bytes;
83 } 93 }
84 94
85 int ResponseWriter::Finish(const net::CompletionCallback& callback) { 95 int ResponseWriter::Finish(const net::CompletionCallback& callback) {
86 std::string code = base::StringPrintf( 96 std::string code = base::StringPrintf(
87 "DevToolsAPI.streamFinish(%d)", stream_id_); 97 "DevToolsAPI.streamFinish(%d)", stream_id_);
88 shell_->web_contents()->GetMainFrame()->ExecuteJavaScript( 98 content::BrowserThread::PostTask(
89 base::UTF8ToUTF16(code)); 99 content::BrowserThread::UI, FROM_HERE,
100 base::Bind(&RespondOnUI, stream_id_, code));
90 return net::OK; 101 return net::OK;
91 } 102 }
92 103
93 } // namespace 104 } // namespace
94 105
95 // This constant should be in sync with 106 // This constant should be in sync with
96 // the constant at devtools_ui_bindings.cc. 107 // the constant at devtools_ui_bindings.cc.
97 const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4; 108 const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
98 109
99 // static 110 // static
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell, 155 ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell,
145 DevToolsAgentHost* agent_host) 156 DevToolsAgentHost* agent_host)
146 : WebContentsObserver(frontend_shell->web_contents()), 157 : WebContentsObserver(frontend_shell->web_contents()),
147 frontend_shell_(frontend_shell), 158 frontend_shell_(frontend_shell),
148 agent_host_(agent_host) { 159 agent_host_(agent_host) {
149 } 160 }
150 161
151 ShellDevToolsFrontend::~ShellDevToolsFrontend() { 162 ShellDevToolsFrontend::~ShellDevToolsFrontend() {
152 for (const auto& pair : pending_requests_) 163 for (const auto& pair : pending_requests_)
153 delete pair.first; 164 delete pair.first;
165
166 for (auto it = g_stream_owners.Get().begin();
167 it != g_stream_owners.Get().end(); ) {
168 if (it->second == frontend_shell())
169 g_stream_owners.Get().erase(it);
170 else
171 ++it;
172 }
154 } 173 }
155 174
156 void ShellDevToolsFrontend::RenderViewCreated( 175 void ShellDevToolsFrontend::RenderViewCreated(
157 RenderViewHost* render_view_host) { 176 RenderViewHost* render_view_host) {
158 if (!frontend_host_) { 177 if (!frontend_host_) {
159 frontend_host_.reset( 178 frontend_host_.reset(
160 DevToolsFrontendHost::Create(web_contents()->GetMainFrame(), this)); 179 DevToolsFrontendHost::Create(web_contents()->GetMainFrame(), this));
161 } 180 }
162 } 181 }
163 182
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 229 }
211 GURL gurl(url); 230 GURL gurl(url);
212 if (!gurl.is_valid()) { 231 if (!gurl.is_valid()) {
213 std::string code = base::StringPrintf( 232 std::string code = base::StringPrintf(
214 "DevToolsAPI.embedderMessageAck(%d, { statusCode: 404 });", id); 233 "DevToolsAPI.embedderMessageAck(%d, { statusCode: 404 });", id);
215 web_contents()->GetMainFrame()->ExecuteJavaScript( 234 web_contents()->GetMainFrame()->ExecuteJavaScript(
216 base::UTF8ToUTF16(code)); 235 base::UTF8ToUTF16(code));
217 return; 236 return;
218 } 237 }
219 238
239 g_stream_owners.Get()[stream_id] = frontend_shell();
240
220 net::URLFetcher* fetcher = 241 net::URLFetcher* fetcher =
221 net::URLFetcher::Create(gurl, net::URLFetcher::GET, this); 242 net::URLFetcher::Create(gurl, net::URLFetcher::GET, this);
222 pending_requests_[fetcher] = id; 243 pending_requests_[fetcher] = std::make_pair(id, stream_id);
223 fetcher->SetRequestContext(web_contents()->GetBrowserContext()-> 244 fetcher->SetRequestContext(web_contents()->GetBrowserContext()->
224 GetRequestContext()); 245 GetRequestContext());
225 fetcher->SetExtraRequestHeaders(headers); 246 fetcher->SetExtraRequestHeaders(headers);
226 fetcher->SaveResponseWithWriter(scoped_ptr<net::URLFetcherResponseWriter>( 247 fetcher->SaveResponseWithWriter(scoped_ptr<net::URLFetcherResponseWriter>(
227 new ResponseWriter(frontend_shell(), stream_id))); 248 new ResponseWriter(stream_id)));
228 fetcher->Start(); 249 fetcher->Start();
229 return; 250 return;
230 } else { 251 } else {
231 return; 252 return;
232 } 253 }
233 254
234 if (id) { 255 if (id) {
235 std::string code = "DevToolsAPI.embedderMessageAck(" + 256 std::string code = "DevToolsAPI.embedderMessageAck(" +
236 base::IntToString(id) + ",\"\");"; 257 base::IntToString(id) + ",\"\");";
237 base::string16 javascript = base::UTF8ToUTF16(code); 258 base::string16 javascript = base::UTF8ToUTF16(code);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 302
282 void* iterator = NULL; 303 void* iterator = NULL;
283 std::string name; 304 std::string name;
284 std::string value; 305 std::string value;
285 while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) 306 while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value))
286 headers->SetString(name, value); 307 headers->SetString(name, value);
287 308
288 std::string json; 309 std::string json;
289 base::JSONWriter::Write(&response, &json); 310 base::JSONWriter::Write(&response, &json);
290 311
312 int request_id = it->second.first;
313 int stream_id = it->second.second;
291 std::string message = base::StringPrintf( 314 std::string message = base::StringPrintf(
292 "DevToolsAPI.embedderMessageAck(%d, %s)", 315 "DevToolsAPI.embedderMessageAck(%d, %s)",
293 it->second, 316 request_id,
294 json.c_str()); 317 json.c_str());
295 web_contents()->GetMainFrame()-> 318 web_contents()->GetMainFrame()->
296 ExecuteJavaScript(base::UTF8ToUTF16(message)); 319 ExecuteJavaScript(base::UTF8ToUTF16(message));
297 320
321 g_stream_owners.Get().erase(stream_id);
298 pending_requests_.erase(it); 322 pending_requests_.erase(it);
299 delete source; 323 delete source;
300 } 324 }
301 325
302 void ShellDevToolsFrontend::AttachTo(WebContents* inspected_contents) { 326 void ShellDevToolsFrontend::AttachTo(WebContents* inspected_contents) {
303 DisconnectFromTarget(); 327 DisconnectFromTarget();
304 agent_host_ = DevToolsAgentHost::GetOrCreateFor(inspected_contents); 328 agent_host_ = DevToolsAgentHost::GetOrCreateFor(inspected_contents);
305 } 329 }
306 330
307 void ShellDevToolsFrontend::AgentHostClosed( 331 void ShellDevToolsFrontend::AgentHostClosed(
308 DevToolsAgentHost* agent_host, bool replaced) { 332 DevToolsAgentHost* agent_host, bool replaced) {
309 frontend_shell_->Close(); 333 frontend_shell_->Close();
310 } 334 }
311 335
312 } // namespace content 336 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698