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

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

Issue 2864103002: [DevTools] Support multiple DevToolsMessageChunkProcessor instances (Closed)
Patch Set: fix Created 3 years, 7 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 (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 <tuple> 7 #include <tuple>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/containers/flat_map.h"
10 #include "base/guid.h" 11 #include "base/guid.h"
11 #include "base/json/json_reader.h" 12 #include "base/json/json_reader.h"
12 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
13 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
14 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
15 #include "build/build_config.h" 16 #include "build/build_config.h"
16 #include "content/browser/bad_message.h" 17 #include "content/browser/bad_message.h"
17 #include "content/browser/child_process_security_policy_impl.h" 18 #include "content/browser/child_process_security_policy_impl.h"
18 #include "content/browser/devtools/devtools_frame_trace_recorder.h" 19 #include "content/browser/devtools/devtools_frame_trace_recorder.h"
19 #include "content/browser/devtools/devtools_manager.h" 20 #include "content/browser/devtools/devtools_manager.h"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 public: 112 public:
112 FrameHostHolder( 113 FrameHostHolder(
113 RenderFrameDevToolsAgentHost* agent, RenderFrameHostImpl* host); 114 RenderFrameDevToolsAgentHost* agent, RenderFrameHostImpl* host);
114 ~FrameHostHolder(); 115 ~FrameHostHolder();
115 116
116 RenderFrameHostImpl* host() const { return host_; } 117 RenderFrameHostImpl* host() const { return host_; }
117 118
118 void Attach(DevToolsSession* session); 119 void Attach(DevToolsSession* session);
119 void Reattach(FrameHostHolder* old); 120 void Reattach(FrameHostHolder* old);
120 void Detach(int session_id); 121 void Detach(int session_id);
122 void Disconnect();
121 void DispatchProtocolMessage(int session_id, 123 void DispatchProtocolMessage(int session_id,
122 int call_id, 124 int call_id,
123 const std::string& method, 125 const std::string& method,
124 const std::string& message); 126 const std::string& message);
125 void InspectElement(int session_id, int x, int y); 127 void InspectElement(int session_id, int x, int y);
126 bool ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk); 128 bool ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk);
127 void Suspend(); 129 void Suspend();
128 void Resume(); 130 void Resume();
129 131
130 private: 132 private:
131 void GrantPolicy(); 133 void GrantPolicy();
132 void RevokePolicy(); 134 void RevokePolicy();
133 void SendMessageToClient(int session_id, const std::string& message); 135 void SendChunkedMessage(int session_id, const std::string& message);
136
137 struct MethodAndMessage {
138 std::string method;
139 std::string message;
140 };
141
142 struct SessionInfo {
143 std::unique_ptr<DevToolsMessageChunkProcessor> chunk_processor;
144 std::vector<std::string> pending_messages;
145 // <call_id> -> MethodAndMessage
146 std::map<int, MethodAndMessage> sent_messages;
147 // These are sent messages for which we got a reply while suspended.
148 std::map<int, MethodAndMessage>
149 sent_messages_whose_reply_came_while_suspended;
150 };
134 151
135 RenderFrameDevToolsAgentHost* agent_; 152 RenderFrameDevToolsAgentHost* agent_;
136 RenderFrameHostImpl* host_; 153 RenderFrameHostImpl* host_;
137 bool attached_;
138 bool suspended_; 154 bool suspended_;
139 DevToolsMessageChunkProcessor chunk_processor_; 155 bool disconnected_;
140 // <session_id, message> 156 base::flat_map<int, SessionInfo> session_infos_;
141 std::vector<std::pair<int, std::string>> pending_messages_;
142 // <call_id> -> PendingMessage
143 std::map<int, PendingMessage> sent_messages_;
144 // These are sent messages for which we got a reply while suspended.
145 std::map<int, PendingMessage> sent_messages_whose_reply_came_while_suspended_;
146 }; 157 };
147 158
148 RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder( 159 RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder(
149 RenderFrameDevToolsAgentHost* agent, RenderFrameHostImpl* host) 160 RenderFrameDevToolsAgentHost* agent,
150 : agent_(agent), 161 RenderFrameHostImpl* host)
151 host_(host), 162 : agent_(agent), host_(host), suspended_(false), disconnected_(false) {
152 attached_(false),
153 suspended_(false),
154 chunk_processor_(base::Bind(
155 &RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient,
156 base::Unretained(this))) {
157 DCHECK(agent_); 163 DCHECK(agent_);
158 DCHECK(host_); 164 DCHECK(host_);
159 } 165 }
160 166
161 RenderFrameDevToolsAgentHost::FrameHostHolder::~FrameHostHolder() { 167 RenderFrameDevToolsAgentHost::FrameHostHolder::~FrameHostHolder() {
162 if (attached_) 168 if (!disconnected_ && !session_infos_.empty())
163 RevokePolicy(); 169 RevokePolicy();
164 } 170 }
165 171
166 void RenderFrameDevToolsAgentHost::FrameHostHolder::Attach( 172 void RenderFrameDevToolsAgentHost::FrameHostHolder::Attach(
167 DevToolsSession* session) { 173 DevToolsSession* session) {
168 host_->Send(new DevToolsAgentMsg_Attach( 174 host_->Send(new DevToolsAgentMsg_Attach(
169 host_->GetRoutingID(), agent_->GetId(), session->session_id())); 175 host_->GetRoutingID(), agent_->GetId(), session->session_id()));
170 GrantPolicy(); 176 GrantPolicy();
171 attached_ = true; 177 SessionInfo& info = session_infos_[session->session_id()];
178 info.chunk_processor.reset(new DevToolsMessageChunkProcessor(base::Bind(
179 &RenderFrameDevToolsAgentHost::FrameHostHolder::SendChunkedMessage,
180 base::Unretained(this))));
172 } 181 }
173 182
174 void RenderFrameDevToolsAgentHost::FrameHostHolder::Reattach( 183 void RenderFrameDevToolsAgentHost::FrameHostHolder::Reattach(
175 FrameHostHolder* old) { 184 FrameHostHolder* old) {
176 if (old) 185 int session_id = agent_->session()->session_id();
177 chunk_processor_.set_state_cookie(old->chunk_processor_.state_cookie()); 186 SessionInfo& info = session_infos_[session_id];
187 info.chunk_processor.reset(new DevToolsMessageChunkProcessor(base::Bind(
188 &RenderFrameDevToolsAgentHost::FrameHostHolder::SendChunkedMessage,
189 base::Unretained(this))));
190 SessionInfo* old_info = nullptr;
191 if (old) {
192 auto it = old->session_infos_.find(session_id);
193 old_info = it != old->session_infos_.end() ? &(it->second) : nullptr;
194 }
195 if (old_info)
196 info.chunk_processor->set_state_cookie(
197 old_info->chunk_processor->state_cookie());
178 host_->Send(new DevToolsAgentMsg_Reattach( 198 host_->Send(new DevToolsAgentMsg_Reattach(
179 host_->GetRoutingID(), agent_->GetId(), agent_->session()->session_id(), 199 host_->GetRoutingID(), agent_->GetId(), session_id,
180 chunk_processor_.state_cookie())); 200 info.chunk_processor->state_cookie()));
181 if (old) { 201 if (old_info) {
182 if (IsBrowserSideNavigationEnabled()) { 202 if (IsBrowserSideNavigationEnabled()) {
183 for (const auto& pair : 203 for (const auto& pair :
184 old->sent_messages_whose_reply_came_while_suspended_) { 204 old_info->sent_messages_whose_reply_came_while_suspended) {
185 DispatchProtocolMessage(pair.second.session_id, pair.first, 205 DispatchProtocolMessage(session_id, pair.first, pair.second.method,
186 pair.second.method, pair.second.message); 206 pair.second.message);
187 } 207 }
188 } 208 }
189 for (const auto& pair : old->sent_messages_) { 209 for (const auto& pair : old_info->sent_messages) {
190 DispatchProtocolMessage(pair.second.session_id, pair.first, 210 DispatchProtocolMessage(session_id, pair.first, pair.second.method,
191 pair.second.method, pair.second.message); 211 pair.second.message);
192 } 212 }
193 } 213 }
194 GrantPolicy(); 214 GrantPolicy();
195 attached_ = true;
196 } 215 }
197 216
198 void RenderFrameDevToolsAgentHost::FrameHostHolder::Detach(int session_id) { 217 void RenderFrameDevToolsAgentHost::FrameHostHolder::Detach(int session_id) {
199 host_->Send(new DevToolsAgentMsg_Detach(host_->GetRoutingID(), session_id)); 218 host_->Send(new DevToolsAgentMsg_Detach(host_->GetRoutingID(), session_id));
200 RevokePolicy(); 219 RevokePolicy();
201 attached_ = false; 220 session_infos_.erase(session_id);
221 }
222
223 void RenderFrameDevToolsAgentHost::FrameHostHolder::Disconnect() {
224 for (auto& it : session_infos_)
225 host_->Send(new DevToolsAgentMsg_Detach(host_->GetRoutingID(), it.first));
226 RevokePolicy();
227 disconnected_ = true;
202 } 228 }
203 229
204 void RenderFrameDevToolsAgentHost::FrameHostHolder::GrantPolicy() { 230 void RenderFrameDevToolsAgentHost::FrameHostHolder::GrantPolicy() {
205 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies( 231 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies(
206 host_->GetProcess()->GetID()); 232 host_->GetProcess()->GetID());
207 } 233 }
208 234
209 void RenderFrameDevToolsAgentHost::FrameHostHolder::RevokePolicy() { 235 void RenderFrameDevToolsAgentHost::FrameHostHolder::RevokePolicy() {
210 bool process_has_agents = false; 236 bool process_has_agents = false;
211 RenderProcessHost* process_host = host_->GetProcess(); 237 RenderProcessHost* process_host = host_->GetProcess();
(...skipping 16 matching lines...) Expand all
228 process_host->GetID()); 254 process_host->GetID());
229 } 255 }
230 } 256 }
231 void RenderFrameDevToolsAgentHost::FrameHostHolder::DispatchProtocolMessage( 257 void RenderFrameDevToolsAgentHost::FrameHostHolder::DispatchProtocolMessage(
232 int session_id, 258 int session_id,
233 int call_id, 259 int call_id,
234 const std::string& method, 260 const std::string& method,
235 const std::string& message) { 261 const std::string& message) {
236 host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend( 262 host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
237 host_->GetRoutingID(), session_id, call_id, method, message)); 263 host_->GetRoutingID(), session_id, call_id, method, message));
238 sent_messages_[call_id] = { session_id, method, message }; 264 session_infos_[session_id].sent_messages[call_id] = {method, message};
239 } 265 }
240 266
241 void RenderFrameDevToolsAgentHost::FrameHostHolder::InspectElement( 267 void RenderFrameDevToolsAgentHost::FrameHostHolder::InspectElement(
242 int session_id, int x, int y) { 268 int session_id, int x, int y) {
243 DCHECK(attached_); 269 DCHECK(session_infos_.find(session_id) != session_infos_.end());
244 host_->Send(new DevToolsAgentMsg_InspectElement( 270 host_->Send(new DevToolsAgentMsg_InspectElement(
245 host_->GetRoutingID(), session_id, x, y)); 271 host_->GetRoutingID(), session_id, x, y));
246 } 272 }
247 273
248 bool 274 bool
249 RenderFrameDevToolsAgentHost::FrameHostHolder::ProcessChunkedMessageFromAgent( 275 RenderFrameDevToolsAgentHost::FrameHostHolder::ProcessChunkedMessageFromAgent(
250 const DevToolsMessageChunk& chunk) { 276 const DevToolsMessageChunk& chunk) {
251 return chunk_processor_.ProcessChunkedMessageFromAgent(chunk); 277 auto it = session_infos_.find(chunk.session_id);
278 if (it != session_infos_.end())
279 return it->second.chunk_processor->ProcessChunkedMessageFromAgent(chunk);
280 return false;
252 } 281 }
253 282
254 void RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient( 283 void RenderFrameDevToolsAgentHost::FrameHostHolder::SendChunkedMessage(
255 int session_id, 284 int session_id,
256 const std::string& message) { 285 const std::string& message) {
257 int id = chunk_processor_.last_call_id(); 286 auto it = session_infos_.find(session_id);
258 PendingMessage sent_message = sent_messages_[id]; 287 if (it == session_infos_.end())
259 sent_messages_.erase(id); 288 return;
289 SessionInfo& info = it->second;
290 int id = info.chunk_processor->last_call_id();
291 MethodAndMessage sent_message = info.sent_messages[id];
292 info.sent_messages.erase(id);
260 if (suspended_) { 293 if (suspended_) {
261 sent_messages_whose_reply_came_while_suspended_[id] = sent_message; 294 info.sent_messages_whose_reply_came_while_suspended[id] = sent_message;
262 pending_messages_.push_back(std::make_pair(session_id, message)); 295 info.pending_messages.push_back(message);
263 } else { 296 } else {
264 agent_->SendMessageToClient(session_id, message); 297 // Filter any messages from previous sessions.
298 if (agent_->session() && agent_->session()->session_id() == session_id)
299 agent_->session()->SendMessageToClient(message);
265 // |this| may be deleted at this point. 300 // |this| may be deleted at this point.
266 } 301 }
267 } 302 }
268 303
269 void RenderFrameDevToolsAgentHost::FrameHostHolder::Suspend() { 304 void RenderFrameDevToolsAgentHost::FrameHostHolder::Suspend() {
270 suspended_ = true; 305 suspended_ = true;
271 } 306 }
272 307
273 void RenderFrameDevToolsAgentHost::FrameHostHolder::Resume() { 308 void RenderFrameDevToolsAgentHost::FrameHostHolder::Resume() {
274 suspended_ = false; 309 suspended_ = false;
275 for (const auto& pair : pending_messages_) 310 for (auto& it : session_infos_) {
276 agent_->SendMessageToClient(pair.first, pair.second); 311 SessionInfo& info = it.second;
277 std::vector<std::pair<int, std::string>> empty; 312 if (agent_->session() && agent_->session()->session_id() == it.first) {
278 pending_messages_.swap(empty); 313 for (const std::string& message : info.pending_messages)
279 sent_messages_whose_reply_came_while_suspended_.clear(); 314 agent_->session()->SendMessageToClient(message);
315 }
316 std::vector<std::string> empty;
317 info.pending_messages.swap(empty);
318 info.sent_messages_whose_reply_came_while_suspended.clear();
319 }
280 } 320 }
281 321
282 // RenderFrameDevToolsAgentHost ------------------------------------------------ 322 // RenderFrameDevToolsAgentHost ------------------------------------------------
283 323
284 // static 324 // static
285 scoped_refptr<DevToolsAgentHost> 325 scoped_refptr<DevToolsAgentHost>
286 DevToolsAgentHost::GetOrCreateFor(RenderFrameHost* frame_host) { 326 DevToolsAgentHost::GetOrCreateFor(RenderFrameHost* frame_host) {
287 while (frame_host && !ShouldCreateDevToolsFor(frame_host)) 327 while (frame_host && !ShouldCreateDevToolsFor(frame_host))
288 frame_host = frame_host->GetParent(); 328 frame_host = frame_host->GetParent();
289 DCHECK(frame_host); 329 DCHECK(frame_host);
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 handlers_frame_host_ = host; 1009 handlers_frame_host_ = host;
970 if (session()) 1010 if (session())
971 session()->SetRenderFrameHost(host); 1011 session()->SetRenderFrameHost(host);
972 } 1012 }
973 1013
974 void RenderFrameDevToolsAgentHost::DisconnectWebContents() { 1014 void RenderFrameDevToolsAgentHost::DisconnectWebContents() {
975 if (pending_) 1015 if (pending_)
976 DiscardPending(); 1016 DiscardPending();
977 UpdateProtocolHandlers(nullptr); 1017 UpdateProtocolHandlers(nullptr);
978 disconnected_ = std::move(current_); 1018 disconnected_ = std::move(current_);
979 if (session()) 1019 disconnected_->Disconnect();
980 disconnected_->Detach(session()->session_id());
981 frame_tree_node_ = nullptr; 1020 frame_tree_node_ = nullptr;
982 in_navigation_protocol_message_buffer_.clear(); 1021 in_navigation_protocol_message_buffer_.clear();
983 navigating_handles_.clear(); 1022 navigating_handles_.clear();
984 pending_handle_ = nullptr; 1023 pending_handle_ = nullptr;
985 WebContentsObserver::Observe(nullptr); 1024 WebContentsObserver::Observe(nullptr);
986 } 1025 }
987 1026
988 void RenderFrameDevToolsAgentHost::ConnectWebContents(WebContents* wc) { 1027 void RenderFrameDevToolsAgentHost::ConnectWebContents(WebContents* wc) {
989 // CommitPending may destruct |this|. 1028 // CommitPending may destruct |this|.
990 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this); 1029 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 RenderFrameHost* host) { 1204 RenderFrameHost* host) {
1166 return (current_ && current_->host() == host) || 1205 return (current_ && current_->host() == host) ||
1167 (pending_ && pending_->host() == host); 1206 (pending_ && pending_->host() == host);
1168 } 1207 }
1169 1208
1170 bool RenderFrameDevToolsAgentHost::IsChildFrame() { 1209 bool RenderFrameDevToolsAgentHost::IsChildFrame() {
1171 return current_ && current_->host()->GetParent(); 1210 return current_ && current_->host()->GetParent();
1172 } 1211 }
1173 1212
1174 } // namespace content 1213 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/forwarding_agent_host.cc ('k') | content/browser/devtools/worker_devtools_agent_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698