| 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/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 Loading... |
| 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 Loading... |
| 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", ¶ms)) |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |