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

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: same with no streamfinish 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
« no previous file with comments | « content/shell/browser/shell_devtools_frontend.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.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
35 37
36 // ResponseWriter ------------------------------------------------------------- 38 // ResponseWriter -------------------------------------------------------------
37 39
38 class ResponseWriter : public net::URLFetcherResponseWriter { 40 class ResponseWriter : public net::URLFetcherResponseWriter {
39 public: 41 public:
40 ResponseWriter(Shell* shell, int stream_id); 42 ResponseWriter(base::WeakPtr<ShellDevToolsFrontend> shell_devtools_,
43 int stream_id);
41 ~ResponseWriter() override; 44 ~ResponseWriter() override;
42 45
43 // URLFetcherResponseWriter overrides: 46 // URLFetcherResponseWriter overrides:
44 int Initialize(const net::CompletionCallback& callback) override; 47 int Initialize(const net::CompletionCallback& callback) override;
45 int Write(net::IOBuffer* buffer, 48 int Write(net::IOBuffer* buffer,
46 int num_bytes, 49 int num_bytes,
47 const net::CompletionCallback& callback) override; 50 const net::CompletionCallback& callback) override;
48 int Finish(const net::CompletionCallback& callback) override; 51 int Finish(const net::CompletionCallback& callback) override;
49 52
50 private: 53 private:
51 Shell* shell_; 54 base::WeakPtr<ShellDevToolsFrontend> shell_devtools_;
52 int stream_id_; 55 int stream_id_;
53 56
54 DISALLOW_COPY_AND_ASSIGN(ResponseWriter); 57 DISALLOW_COPY_AND_ASSIGN(ResponseWriter);
55 }; 58 };
56 59
57 ResponseWriter::ResponseWriter(Shell* shell, 60 ResponseWriter::ResponseWriter(
58 int stream_id) 61 base::WeakPtr<ShellDevToolsFrontend> shell_devtools,
59 : shell_(shell), 62 int stream_id)
63 : shell_devtools_(shell_devtools),
60 stream_id_(stream_id) { 64 stream_id_(stream_id) {
61 } 65 }
62 66
63 ResponseWriter::~ResponseWriter() { 67 ResponseWriter::~ResponseWriter() {
64 } 68 }
65 69
66 int ResponseWriter::Initialize(const net::CompletionCallback& callback) { 70 int ResponseWriter::Initialize(const net::CompletionCallback& callback) {
67 return net::OK; 71 return net::OK;
68 } 72 }
69 73
70 int ResponseWriter::Write(net::IOBuffer* buffer, 74 int ResponseWriter::Write(net::IOBuffer* buffer,
71 int num_bytes, 75 int num_bytes,
72 const net::CompletionCallback& callback) { 76 const net::CompletionCallback& callback) {
73 base::StringValue chunk(std::string(buffer->data(), num_bytes)); 77 base::FundamentalValue* id = new base::FundamentalValue(stream_id_);
74 std::string encoded; 78 base::StringValue* chunk =
75 base::JSONWriter::Write(&chunk, &encoded); 79 new base::StringValue(std::string(buffer->data(), num_bytes));
76 80
77 std::string code = base::StringPrintf( 81 content::BrowserThread::PostTask(
78 "DevToolsAPI.streamWrite(%d, %s)", stream_id_, encoded.c_str()); 82 content::BrowserThread::UI, FROM_HERE,
79 shell_->web_contents()->GetMainFrame()->ExecuteJavaScript( 83 base::Bind(&ShellDevToolsFrontend::CallClientFunction,
80 base::UTF8ToUTF16(code)); 84 shell_devtools_, "DevToolsAPI.streamWrite",
81 85 base::Owned(id), base::Owned(chunk), nullptr));
82 return num_bytes; 86 return num_bytes;
83 } 87 }
84 88
85 int ResponseWriter::Finish(const net::CompletionCallback& callback) { 89 int ResponseWriter::Finish(const net::CompletionCallback& callback) {
86 std::string code = base::StringPrintf(
87 "DevToolsAPI.streamFinish(%d)", stream_id_);
88 shell_->web_contents()->GetMainFrame()->ExecuteJavaScript(
89 base::UTF8ToUTF16(code));
90 return net::OK; 90 return net::OK;
91 } 91 }
92 92
93 } // namespace 93 } // namespace
94 94
95 // This constant should be in sync with 95 // This constant should be in sync with
96 // the constant at devtools_ui_bindings.cc. 96 // the constant at devtools_ui_bindings.cc.
97 const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4; 97 const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4;
98 98
99 // static 99 // static
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 if (!agent_host_) 138 if (!agent_host_)
139 return; 139 return;
140 agent_host_->DetachClient(); 140 agent_host_->DetachClient();
141 agent_host_ = NULL; 141 agent_host_ = NULL;
142 } 142 }
143 143
144 ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell, 144 ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell,
145 DevToolsAgentHost* agent_host) 145 DevToolsAgentHost* agent_host)
146 : WebContentsObserver(frontend_shell->web_contents()), 146 : WebContentsObserver(frontend_shell->web_contents()),
147 frontend_shell_(frontend_shell), 147 frontend_shell_(frontend_shell),
148 agent_host_(agent_host) { 148 agent_host_(agent_host),
149 weak_factory_(this) {
149 } 150 }
150 151
151 ShellDevToolsFrontend::~ShellDevToolsFrontend() { 152 ShellDevToolsFrontend::~ShellDevToolsFrontend() {
152 for (const auto& pair : pending_requests_) 153 for (const auto& pair : pending_requests_)
153 delete pair.first; 154 delete pair.first;
154 } 155 }
155 156
156 void ShellDevToolsFrontend::RenderViewCreated( 157 void ShellDevToolsFrontend::RenderViewCreated(
157 RenderViewHost* render_view_host) { 158 RenderViewHost* render_view_host) {
158 if (!frontend_host_) { 159 if (!frontend_host_) {
(...skipping 21 matching lines...) Expand all
180 return; 181 return;
181 std::string method; 182 std::string method;
182 base::ListValue* params = NULL; 183 base::ListValue* params = NULL;
183 base::DictionaryValue* dict = NULL; 184 base::DictionaryValue* dict = NULL;
184 scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message)); 185 scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
185 if (!parsed_message || 186 if (!parsed_message ||
186 !parsed_message->GetAsDictionary(&dict) || 187 !parsed_message->GetAsDictionary(&dict) ||
187 !dict->GetString("method", &method)) { 188 !dict->GetString("method", &method)) {
188 return; 189 return;
189 } 190 }
190 int id = 0; 191 int request_id = 0;
191 dict->GetInteger("id", &id); 192 dict->GetInteger("id", &request_id);
192 dict->GetList("params", &params); 193 dict->GetList("params", &params);
193 194
194 std::string browser_message; 195 std::string browser_message;
195 if (method == "sendMessageToBrowser" && params && 196 if (method == "sendMessageToBrowser" && params &&
196 params->GetSize() == 1 && params->GetString(0, &browser_message)) { 197 params->GetSize() == 1 && params->GetString(0, &browser_message)) {
197 agent_host_->DispatchProtocolMessage(browser_message); 198 agent_host_->DispatchProtocolMessage(browser_message);
198 } else if (method == "loadCompleted") { 199 } else if (method == "loadCompleted") {
199 web_contents()->GetMainFrame()->ExecuteJavaScript( 200 web_contents()->GetMainFrame()->ExecuteJavaScript(
200 base::ASCIIToUTF16("DevToolsAPI.setUseSoftMenu(true);")); 201 base::ASCIIToUTF16("DevToolsAPI.setUseSoftMenu(true);"));
201 } else if (method == "loadNetworkResource" && params->GetSize() == 3) { 202 } else if (method == "loadNetworkResource" && params->GetSize() == 3) {
202 // TODO(pfeldman): handle some of the embedder messages in content. 203 // TODO(pfeldman): handle some of the embedder messages in content.
203 std::string url; 204 std::string url;
204 std::string headers; 205 std::string headers;
205 int stream_id; 206 int stream_id;
206 if (!params->GetString(0, &url) || 207 if (!params->GetString(0, &url) ||
207 !params->GetString(1, &headers) || 208 !params->GetString(1, &headers) ||
208 !params->GetInteger(2, &stream_id)) { 209 !params->GetInteger(2, &stream_id)) {
209 return; 210 return;
210 } 211 }
212
211 GURL gurl(url); 213 GURL gurl(url);
212 if (!gurl.is_valid()) { 214 if (!gurl.is_valid()) {
213 std::string code = base::StringPrintf( 215 base::DictionaryValue response;
214 "DevToolsAPI.embedderMessageAck(%d, { statusCode: 404 });", id); 216 response.SetInteger("statusCode", 404);
215 web_contents()->GetMainFrame()->ExecuteJavaScript( 217 SendMessageAck(request_id, &response);
216 base::UTF8ToUTF16(code));
217 return; 218 return;
218 } 219 }
219 220
220 net::URLFetcher* fetcher = 221 net::URLFetcher* fetcher =
221 net::URLFetcher::Create(gurl, net::URLFetcher::GET, this); 222 net::URLFetcher::Create(gurl, net::URLFetcher::GET, this);
222 pending_requests_[fetcher] = id; 223 pending_requests_[fetcher] = request_id;
223 fetcher->SetRequestContext(web_contents()->GetBrowserContext()-> 224 fetcher->SetRequestContext(web_contents()->GetBrowserContext()->
224 GetRequestContext()); 225 GetRequestContext());
225 fetcher->SetExtraRequestHeaders(headers); 226 fetcher->SetExtraRequestHeaders(headers);
226 fetcher->SaveResponseWithWriter(scoped_ptr<net::URLFetcherResponseWriter>( 227 fetcher->SaveResponseWithWriter(scoped_ptr<net::URLFetcherResponseWriter>(
227 new ResponseWriter(frontend_shell(), stream_id))); 228 new ResponseWriter(weak_factory_.GetWeakPtr(), stream_id)));
228 fetcher->Start(); 229 fetcher->Start();
229 return; 230 return;
230 } else { 231 } else {
231 return; 232 return;
232 } 233 }
233 234
234 if (id) { 235 if (request_id)
235 std::string code = "DevToolsAPI.embedderMessageAck(" + 236 SendMessageAck(request_id, nullptr);
236 base::IntToString(id) + ",\"\");";
237 base::string16 javascript = base::UTF8ToUTF16(code);
238 web_contents()->GetMainFrame()->ExecuteJavaScript(javascript);
239 }
240 } 237 }
241 238
242 void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontendToBackend( 239 void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontendToBackend(
243 const std::string& message) { 240 const std::string& message) {
244 if (agent_host_) 241 if (agent_host_)
245 agent_host_->DispatchProtocolMessage(message); 242 agent_host_->DispatchProtocolMessage(message);
246 } 243 }
247 244
248 void ShellDevToolsFrontend::DispatchProtocolMessage( 245 void ShellDevToolsFrontend::DispatchProtocolMessage(
249 DevToolsAgentHost* agent_host, const std::string& message) { 246 DevToolsAgentHost* agent_host, const std::string& message) {
(...skipping 28 matching lines...) Expand all
278 net::HttpResponseHeaders* rh = source->GetResponseHeaders(); 275 net::HttpResponseHeaders* rh = source->GetResponseHeaders();
279 response.SetInteger("statusCode", rh ? rh->response_code() : 200); 276 response.SetInteger("statusCode", rh ? rh->response_code() : 200);
280 response.Set("headers", headers); 277 response.Set("headers", headers);
281 278
282 void* iterator = NULL; 279 void* iterator = NULL;
283 std::string name; 280 std::string name;
284 std::string value; 281 std::string value;
285 while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) 282 while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value))
286 headers->SetString(name, value); 283 headers->SetString(name, value);
287 284
288 std::string json; 285 SendMessageAck(it->second, &response);
289 base::JSONWriter::Write(&response, &json);
290
291 std::string message = base::StringPrintf(
292 "DevToolsAPI.embedderMessageAck(%d, %s)",
293 it->second,
294 json.c_str());
295 web_contents()->GetMainFrame()->
296 ExecuteJavaScript(base::UTF8ToUTF16(message));
297
298 pending_requests_.erase(it); 286 pending_requests_.erase(it);
299 delete source; 287 delete source;
300 } 288 }
301 289
290 void ShellDevToolsFrontend::CallClientFunction(
291 const std::string& function_name,
292 const base::Value* arg1,
293 const base::Value* arg2,
294 const base::Value* arg3) {
295 std::string javascript = function_name + "(";
296 if (arg1) {
297 std::string json;
298 base::JSONWriter::Write(arg1, &json);
299 javascript.append(json);
300 if (arg2) {
301 base::JSONWriter::Write(arg2, &json);
302 javascript.append(", ").append(json);
303 if (arg3) {
304 base::JSONWriter::Write(arg3, &json);
305 javascript.append(", ").append(json);
306 }
307 }
308 }
309 javascript.append(");");
310 web_contents()->GetMainFrame()->ExecuteJavaScript(
311 base::UTF8ToUTF16(javascript));
312 }
313
314 void ShellDevToolsFrontend::SendMessageAck(int request_id,
315 const base::Value* arg) {
316 base::FundamentalValue id_value(request_id);
317 CallClientFunction("DevToolsAPI.embedderMessageAck",
318 &id_value, arg, nullptr);
319 }
320
302 void ShellDevToolsFrontend::AttachTo(WebContents* inspected_contents) { 321 void ShellDevToolsFrontend::AttachTo(WebContents* inspected_contents) {
303 DisconnectFromTarget(); 322 DisconnectFromTarget();
304 agent_host_ = DevToolsAgentHost::GetOrCreateFor(inspected_contents); 323 agent_host_ = DevToolsAgentHost::GetOrCreateFor(inspected_contents);
305 } 324 }
306 325
307 void ShellDevToolsFrontend::AgentHostClosed( 326 void ShellDevToolsFrontend::AgentHostClosed(
308 DevToolsAgentHost* agent_host, bool replaced) { 327 DevToolsAgentHost* agent_host, bool replaced) {
309 frontend_shell_->Close(); 328 frontend_shell_->Close();
310 } 329 }
311 330
312 } // namespace content 331 } // namespace content
OLDNEW
« no previous file with comments | « content/shell/browser/shell_devtools_frontend.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698