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

Side by Side Diff: content/browser/devtools/render_frame_devtools_agent_host.cc

Issue 1520883002: Allow devtools clients to handle slow cross-process navigations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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 | « no previous file | 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 (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/devtools/render_frame_devtools_agent_host.h" 5 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/json/json_reader.h"
9 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
10 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
11 #include "content/browser/child_process_security_policy_impl.h" 13 #include "content/browser/child_process_security_policy_impl.h"
12 #include "content/browser/devtools/devtools_frame_trace_recorder.h" 14 #include "content/browser/devtools/devtools_frame_trace_recorder.h"
13 #include "content/browser/devtools/devtools_protocol_handler.h" 15 #include "content/browser/devtools/devtools_protocol_handler.h"
14 #include "content/browser/devtools/protocol/dom_handler.h" 16 #include "content/browser/devtools/protocol/dom_handler.h"
15 #include "content/browser/devtools/protocol/emulation_handler.h" 17 #include "content/browser/devtools/protocol/emulation_handler.h"
16 #include "content/browser/devtools/protocol/input_handler.h" 18 #include "content/browser/devtools/protocol/input_handler.h"
17 #include "content/browser/devtools/protocol/inspector_handler.h" 19 #include "content/browser/devtools/protocol/inspector_handler.h"
18 #include "content/browser/devtools/protocol/io_handler.h" 20 #include "content/browser/devtools/protocol/io_handler.h"
19 #include "content/browser/devtools/protocol/network_handler.h" 21 #include "content/browser/devtools/protocol/network_handler.h"
20 #include "content/browser/devtools/protocol/page_handler.h" 22 #include "content/browser/devtools/protocol/page_handler.h"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 void Reattach(FrameHostHolder* old); 94 void Reattach(FrameHostHolder* old);
93 void Detach(); 95 void Detach();
94 void DispatchProtocolMessage(int session_id, 96 void DispatchProtocolMessage(int session_id,
95 int call_id, 97 int call_id,
96 const std::string& message); 98 const std::string& message);
97 void InspectElement(int x, int y); 99 void InspectElement(int x, int y);
98 void ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk); 100 void ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk);
99 void Suspend(); 101 void Suspend();
100 void Resume(); 102 void Resume();
101 103
104 bool suspended() const { return suspended_; }
105 const std::string& last_loading_frame_id() const {
106 return last_loading_frame_id_;
107 }
108
102 private: 109 private:
103 void GrantPolicy(); 110 void GrantPolicy();
104 void RevokePolicy(); 111 void RevokePolicy();
105 void SendMessageToClient(int session_id, const std::string& message); 112 void SendMessageToClient(int session_id, const std::string& message);
106 113
107 RenderFrameDevToolsAgentHost* agent_; 114 RenderFrameDevToolsAgentHost* agent_;
108 RenderFrameHostImpl* host_; 115 RenderFrameHostImpl* host_;
109 bool attached_; 116 bool attached_;
110 bool suspended_; 117 bool suspended_;
111 DevToolsMessageChunkProcessor chunk_processor_; 118 DevToolsMessageChunkProcessor chunk_processor_;
112 // <session_id, message> 119 // <session_id, message>
113 std::vector<std::pair<int, std::string>> pending_messages_; 120 std::vector<std::pair<int, std::string>> pending_messages_;
114 // <call_id> -> <session_id, message> 121 // <call_id> -> <session_id, message>
115 std::map<int, std::pair<int, std::string>> sent_messages_; 122 std::map<int, std::pair<int, std::string>> sent_messages_;
123 std::string last_loading_frame_id_;
116 }; 124 };
117 125
118 RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder( 126 RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder(
119 RenderFrameDevToolsAgentHost* agent, RenderFrameHostImpl* host) 127 RenderFrameDevToolsAgentHost* agent, RenderFrameHostImpl* host)
120 : agent_(agent), 128 : agent_(agent),
121 host_(host), 129 host_(host),
122 attached_(false), 130 attached_(false),
123 suspended_(false), 131 suspended_(false),
124 chunk_processor_(base::Bind( 132 chunk_processor_(base::Bind(
125 &RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient, 133 &RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 221 }
214 222
215 void RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient( 223 void RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient(
216 int session_id, 224 int session_id,
217 const std::string& message) { 225 const std::string& message) {
218 sent_messages_.erase(chunk_processor_.last_call_id()); 226 sent_messages_.erase(chunk_processor_.last_call_id());
219 if (suspended_) 227 if (suspended_)
220 pending_messages_.push_back(std::make_pair(session_id, message)); 228 pending_messages_.push_back(std::make_pair(session_id, message));
221 else 229 else
222 agent_->SendMessageToClient(session_id, message); 230 agent_->SendMessageToClient(session_id, message);
231
232 // Store frameId when the frame starts loading to use it in case if the
233 // pending frame host is discarded.
234 if (last_loading_frame_id_.empty() &&
235 message.find("Page.frameStartedLoading") != std::string::npos) {
236 scoped_ptr<base::Value> message_content = base::JSONReader::Read(message);
237 base::DictionaryValue* message_dict;
238 if (message_content && message_content->GetAsDictionary(&message_dict)) {
239 base::DictionaryValue* params;
240 if (message_dict->GetDictionary("params", &params))
241 params->GetString("frameId", &last_loading_frame_id_);
242 }
243 }
223 } 244 }
224 245
225 void RenderFrameDevToolsAgentHost::FrameHostHolder::Suspend() { 246 void RenderFrameDevToolsAgentHost::FrameHostHolder::Suspend() {
226 suspended_ = true; 247 suspended_ = true;
227 } 248 }
228 249
229 void RenderFrameDevToolsAgentHost::FrameHostHolder::Resume() { 250 void RenderFrameDevToolsAgentHost::FrameHostHolder::Resume() {
230 suspended_ = false; 251 suspended_ = false;
231 for (const auto& pair : pending_messages_) 252 for (const auto& pair : pending_messages_)
232 agent_->SendMessageToClient(pair.first, pair.second); 253 agent_->SendMessageToClient(pair.first, pair.second);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 void RenderFrameDevToolsAgentHost::SetPending(RenderFrameHostImpl* host) { 404 void RenderFrameDevToolsAgentHost::SetPending(RenderFrameHostImpl* host) {
384 DCHECK(!pending_); 405 DCHECK(!pending_);
385 current_frame_crashed_ = false; 406 current_frame_crashed_ = false;
386 pending_.reset(new FrameHostHolder(this, host)); 407 pending_.reset(new FrameHostHolder(this, host));
387 if (IsAttached()) 408 if (IsAttached())
388 pending_->Reattach(current_.get()); 409 pending_->Reattach(current_.get());
389 410
390 // Can only be null in constructor. 411 // Can only be null in constructor.
391 if (current_) 412 if (current_)
392 current_->Suspend(); 413 current_->Suspend();
393 pending_->Suspend(); 414 // Don't suspend pending_ as it may break clients.
394 415
395 UpdateProtocolHandlers(host); 416 UpdateProtocolHandlers(host);
396 } 417 }
397 418
398 void RenderFrameDevToolsAgentHost::CommitPending() { 419 void RenderFrameDevToolsAgentHost::CommitPending() {
399 DCHECK(pending_); 420 DCHECK(pending_);
400 current_frame_crashed_ = false; 421 current_frame_crashed_ = false;
401 422
402 if (!ShouldCreateDevToolsFor(pending_->host())) { 423 if (!ShouldCreateDevToolsFor(pending_->host())) {
403 DestroyOnRenderFrameGone(); 424 DestroyOnRenderFrameGone();
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 } 738 }
718 739
719 void RenderFrameDevToolsAgentHost::DidFailProvisionalLoad( 740 void RenderFrameDevToolsAgentHost::DidFailProvisionalLoad(
720 RenderFrameHost* render_frame_host, 741 RenderFrameHost* render_frame_host,
721 const GURL& validated_url, 742 const GURL& validated_url,
722 int error_code, 743 int error_code,
723 const base::string16& error_description, 744 const base::string16& error_description,
724 bool was_ignored_by_handler) { 745 bool was_ignored_by_handler) {
725 if (browser_side_navigation) 746 if (browser_side_navigation)
726 return; 747 return;
727 if (pending_ && pending_->host() == render_frame_host) 748 if (pending_ && pending_->host() == render_frame_host) {
749 // When a pending cross-process navigation gets cancelled, the client does
750 // not receive frameStoppedLoading event, which can cause problems with
751 // further operation. Forge the event to avoid that.
752 if (!pending_->suspended() && !pending_->last_loading_frame_id().empty()) {
753 SendMessageToClient(
754 session_id(),
755 "{\"method\":\"Page.frameStoppedLoading\",\"params\":"
756 "{\"frameId\":\"" + pending_->last_loading_frame_id() + "\"}}");
757 }
758
728 DiscardPending(); 759 DiscardPending();
760 }
729 } 761 }
730 762
731 void RenderFrameDevToolsAgentHost:: 763 void RenderFrameDevToolsAgentHost::
732 DispatchBufferedProtocolMessagesIfNecessary() { 764 DispatchBufferedProtocolMessagesIfNecessary() {
733 if (in_navigation_ == 0 && in_navigation_protocol_message_buffer_.size()) { 765 if (in_navigation_ == 0 && in_navigation_protocol_message_buffer_.size()) {
734 DCHECK(current_); 766 DCHECK(current_);
735 for (const auto& pair : in_navigation_protocol_message_buffer_) { 767 for (const auto& pair : in_navigation_protocol_message_buffer_) {
736 current_->DispatchProtocolMessage(pair.second.first, pair.first, 768 current_->DispatchProtocolMessage(pair.second.first, pair.first,
737 pair.second.second); 769 pair.second.second);
738 } 770 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 } 895 }
864 896
865 bool RenderFrameDevToolsAgentHost::MatchesMyTreeNode( 897 bool RenderFrameDevToolsAgentHost::MatchesMyTreeNode(
866 NavigationHandle* navigation_handle) { 898 NavigationHandle* navigation_handle) {
867 return frame_tree_node_ == 899 return frame_tree_node_ ==
868 static_cast<NavigationHandleImpl*>(navigation_handle) 900 static_cast<NavigationHandleImpl*>(navigation_handle)
869 ->frame_tree_node(); 901 ->frame_tree_node();
870 } 902 }
871 903
872 } // namespace content 904 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698