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

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

Issue 2927983004: [DevTools] Rework RFDTAH navigation tracking with browser side navigation (Closed)
Patch Set: removed duplicate policy code Created 3 years, 6 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/guid.h" 10 #include "base/guid.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 const std::string& method, 105 const std::string& method,
106 const std::string& message); 106 const std::string& message);
107 void InspectElement(int session_id, int x, int y); 107 void InspectElement(int session_id, int x, int y);
108 bool ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk); 108 bool ProcessChunkedMessageFromAgent(const DevToolsMessageChunk& chunk);
109 void Suspend(); 109 void Suspend();
110 void Resume(); 110 void Resume();
111 std::string StateCookie() const { return chunk_processor_.state_cookie(); } 111 std::string StateCookie() const { return chunk_processor_.state_cookie(); }
112 void ReattachWithCookie(std::string cookie); 112 void ReattachWithCookie(std::string cookie);
113 113
114 private: 114 private:
115 void GrantPolicy();
116 void RevokePolicy();
117 void SendMessageToClient(int session_id, const std::string& message); 115 void SendMessageToClient(int session_id, const std::string& message);
118 116
119 RenderFrameDevToolsAgentHost* agent_; 117 RenderFrameDevToolsAgentHost* agent_;
120 RenderFrameHostImpl* host_; 118 RenderFrameHostImpl* host_;
121 bool attached_; 119 bool attached_;
122 bool suspended_; 120 bool suspended_;
123 DevToolsMessageChunkProcessor chunk_processor_; 121 DevToolsMessageChunkProcessor chunk_processor_;
124 // <session_id, message> 122 // <session_id, message>
125 std::vector<std::pair<int, std::string>> pending_messages_; 123 std::vector<std::pair<int, std::string>> pending_messages_;
126 // <call_id> -> PendingMessage 124 // <call_id> -> PendingMessage
127 std::map<int, PendingMessage> sent_messages_; 125 std::map<int, Message> sent_messages_;
128 // These are sent messages for which we got a reply while suspended. 126 // These are sent messages for which we got a reply while suspended.
129 std::map<int, PendingMessage> sent_messages_whose_reply_came_while_suspended_; 127 std::map<int, Message> sent_messages_whose_reply_came_while_suspended_;
130 }; 128 };
131 129
132 RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder( 130 RenderFrameDevToolsAgentHost::FrameHostHolder::FrameHostHolder(
133 RenderFrameDevToolsAgentHost* agent, RenderFrameHostImpl* host) 131 RenderFrameDevToolsAgentHost* agent, RenderFrameHostImpl* host)
134 : agent_(agent), 132 : agent_(agent),
135 host_(host), 133 host_(host),
136 attached_(false), 134 attached_(false),
137 suspended_(false), 135 suspended_(false),
138 chunk_processor_(base::Bind( 136 chunk_processor_(base::Bind(
139 &RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient, 137 &RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient,
140 base::Unretained(this))) { 138 base::Unretained(this))) {
141 DCHECK(agent_); 139 DCHECK(agent_);
142 DCHECK(host_); 140 DCHECK(host_);
143 } 141 }
144 142
145 RenderFrameDevToolsAgentHost::FrameHostHolder::~FrameHostHolder() { 143 RenderFrameDevToolsAgentHost::FrameHostHolder::~FrameHostHolder() {
146 if (attached_) 144 if (attached_)
147 RevokePolicy(); 145 agent_->RevokePolicy(host_);
148 } 146 }
149 147
150 void RenderFrameDevToolsAgentHost::FrameHostHolder::Attach( 148 void RenderFrameDevToolsAgentHost::FrameHostHolder::Attach(
151 DevToolsSession* session) { 149 DevToolsSession* session) {
152 host_->Send(new DevToolsAgentMsg_Attach( 150 host_->Send(new DevToolsAgentMsg_Attach(
153 host_->GetRoutingID(), agent_->GetId(), session->session_id())); 151 host_->GetRoutingID(), agent_->GetId(), session->session_id()));
154 GrantPolicy(); 152 agent_->GrantPolicy(host_);
155 attached_ = true; 153 attached_ = true;
156 } 154 }
157 155
158 void RenderFrameDevToolsAgentHost::FrameHostHolder::Reattach( 156 void RenderFrameDevToolsAgentHost::FrameHostHolder::Reattach(
159 FrameHostHolder* old) { 157 FrameHostHolder* old) {
160 std::string cookie = old ? old->chunk_processor_.state_cookie() : ""; 158 std::string cookie = old ? old->chunk_processor_.state_cookie() : "";
161 ReattachWithCookie(std::move(cookie)); 159 ReattachWithCookie(std::move(cookie));
162 if (!old) 160 if (!old)
163 return; 161 return;
164 if (IsBrowserSideNavigationEnabled()) { 162 if (IsBrowserSideNavigationEnabled()) {
165 for (const auto& pair : 163 for (const auto& pair :
166 old->sent_messages_whose_reply_came_while_suspended_) { 164 old->sent_messages_whose_reply_came_while_suspended_) {
167 DispatchProtocolMessage(pair.second.session_id, pair.first, 165 DispatchProtocolMessage(pair.second.session_id, pair.first,
168 pair.second.method, pair.second.message); 166 pair.second.method, pair.second.message);
169 } 167 }
170 } 168 }
171 for (const auto& pair : old->sent_messages_) { 169 for (const auto& pair : old->sent_messages_) {
172 DispatchProtocolMessage(pair.second.session_id, pair.first, 170 DispatchProtocolMessage(pair.second.session_id, pair.first,
173 pair.second.method, pair.second.message); 171 pair.second.method, pair.second.message);
174 } 172 }
175 } 173 }
176 174
177 void RenderFrameDevToolsAgentHost::FrameHostHolder::ReattachWithCookie( 175 void RenderFrameDevToolsAgentHost::FrameHostHolder::ReattachWithCookie(
178 std::string cookie) { 176 std::string cookie) {
179 chunk_processor_.set_state_cookie(cookie); 177 chunk_processor_.set_state_cookie(cookie);
180 host_->Send( 178 host_->Send(
181 new DevToolsAgentMsg_Reattach(host_->GetRoutingID(), agent_->GetId(), 179 new DevToolsAgentMsg_Reattach(host_->GetRoutingID(), agent_->GetId(),
182 agent_->session()->session_id(), cookie)); 180 agent_->session()->session_id(), cookie));
183 GrantPolicy(); 181 agent_->GrantPolicy(host_);
184 attached_ = true; 182 attached_ = true;
185 } 183 }
186 184
187 void RenderFrameDevToolsAgentHost::FrameHostHolder::Detach(int session_id) { 185 void RenderFrameDevToolsAgentHost::FrameHostHolder::Detach(int session_id) {
188 host_->Send(new DevToolsAgentMsg_Detach(host_->GetRoutingID(), session_id)); 186 host_->Send(new DevToolsAgentMsg_Detach(host_->GetRoutingID(), session_id));
189 RevokePolicy(); 187 agent_->RevokePolicy(host_);
190 attached_ = false; 188 attached_ = false;
191 } 189 }
192 190
193 void RenderFrameDevToolsAgentHost::FrameHostHolder::GrantPolicy() {
194 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies(
195 host_->GetProcess()->GetID());
196 }
197
198 void RenderFrameDevToolsAgentHost::FrameHostHolder::RevokePolicy() {
199 bool process_has_agents = false;
200 RenderProcessHost* process_host = host_->GetProcess();
201 for (RenderFrameDevToolsAgentHost* agent : g_instances.Get()) {
202 if (!agent->IsAttached())
203 continue;
204 if (agent->current_ && agent->current_->host() != host_ &&
205 agent->current_->host()->GetProcess() == process_host) {
206 process_has_agents = true;
207 }
208 if (agent->pending_ && agent->pending_->host() != host_ &&
209 agent->pending_->host()->GetProcess() == process_host) {
210 process_has_agents = true;
211 }
212 }
213
214 // We are the last to disconnect from the renderer -> revoke permissions.
215 if (!process_has_agents) {
216 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeReadRawCookies(
217 process_host->GetID());
218 }
219 }
220 void RenderFrameDevToolsAgentHost::FrameHostHolder::DispatchProtocolMessage( 191 void RenderFrameDevToolsAgentHost::FrameHostHolder::DispatchProtocolMessage(
221 int session_id, 192 int session_id,
222 int call_id, 193 int call_id,
223 const std::string& method, 194 const std::string& method,
224 const std::string& message) { 195 const std::string& message) {
225 host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend( 196 host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
226 host_->GetRoutingID(), session_id, call_id, method, message)); 197 host_->GetRoutingID(), session_id, call_id, method, message));
227 sent_messages_[call_id] = { session_id, method, message }; 198 sent_messages_[call_id] = { session_id, method, message };
228 } 199 }
229 200
230 void RenderFrameDevToolsAgentHost::FrameHostHolder::InspectElement( 201 void RenderFrameDevToolsAgentHost::FrameHostHolder::InspectElement(
231 int session_id, int x, int y) { 202 int session_id, int x, int y) {
232 DCHECK(attached_); 203 DCHECK(attached_);
233 host_->Send(new DevToolsAgentMsg_InspectElement( 204 host_->Send(new DevToolsAgentMsg_InspectElement(
234 host_->GetRoutingID(), session_id, x, y)); 205 host_->GetRoutingID(), session_id, x, y));
235 } 206 }
236 207
237 bool 208 bool
238 RenderFrameDevToolsAgentHost::FrameHostHolder::ProcessChunkedMessageFromAgent( 209 RenderFrameDevToolsAgentHost::FrameHostHolder::ProcessChunkedMessageFromAgent(
239 const DevToolsMessageChunk& chunk) { 210 const DevToolsMessageChunk& chunk) {
240 return chunk_processor_.ProcessChunkedMessageFromAgent(chunk); 211 return chunk_processor_.ProcessChunkedMessageFromAgent(chunk);
241 } 212 }
242 213
243 void RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient( 214 void RenderFrameDevToolsAgentHost::FrameHostHolder::SendMessageToClient(
244 int session_id, 215 int session_id,
245 const std::string& message) { 216 const std::string& message) {
246 int id = chunk_processor_.last_call_id(); 217 int id = chunk_processor_.last_call_id();
247 PendingMessage sent_message = sent_messages_[id]; 218 Message sent_message = sent_messages_[id];
248 sent_messages_.erase(id); 219 sent_messages_.erase(id);
249 if (suspended_) { 220 if (suspended_) {
250 sent_messages_whose_reply_came_while_suspended_[id] = sent_message; 221 sent_messages_whose_reply_came_while_suspended_[id] = sent_message;
251 pending_messages_.push_back(std::make_pair(session_id, message)); 222 pending_messages_.push_back(std::make_pair(session_id, message));
252 } else { 223 } else {
253 agent_->SendMessageToClient(session_id, message); 224 agent_->SendMessageToClient(session_id, message);
254 // |this| may be deleted at this point. 225 // |this| may be deleted at this point.
255 } 226 }
256 } 227 }
257 228
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 // static 313 // static
343 void RenderFrameDevToolsAgentHost::OnBeforeNavigation( 314 void RenderFrameDevToolsAgentHost::OnBeforeNavigation(
344 RenderFrameHost* current, RenderFrameHost* pending) { 315 RenderFrameHost* current, RenderFrameHost* pending) {
345 RenderFrameDevToolsAgentHost* agent_host = FindAgentHost( 316 RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(
346 static_cast<RenderFrameHostImpl*>(current)->frame_tree_node()); 317 static_cast<RenderFrameHostImpl*>(current)->frame_tree_node());
347 if (agent_host) 318 if (agent_host)
348 agent_host->AboutToNavigateRenderFrame(current, pending); 319 agent_host->AboutToNavigateRenderFrame(current, pending);
349 } 320 }
350 321
351 // static 322 // static
352 void RenderFrameDevToolsAgentHost::OnBeforeNavigation(
353 NavigationHandle* navigation_handle) {
354 FrameTreeNode* frame_tree_node =
355 static_cast<NavigationHandleImpl*>(navigation_handle)->frame_tree_node();
356 RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(frame_tree_node);
357 if (agent_host)
358 agent_host->AboutToNavigate(navigation_handle);
359 }
360
361 // static
362 void RenderFrameDevToolsAgentHost::OnFailedNavigation( 323 void RenderFrameDevToolsAgentHost::OnFailedNavigation(
363 RenderFrameHost* host, 324 RenderFrameHost* host,
364 const CommonNavigationParams& common_params, 325 const CommonNavigationParams& common_params,
365 const BeginNavigationParams& begin_params, 326 const BeginNavigationParams& begin_params,
366 net::Error error_code) { 327 net::Error error_code) {
367 RenderFrameDevToolsAgentHost* agent_host = 328 RenderFrameDevToolsAgentHost* agent_host =
368 FindAgentHost(static_cast<RenderFrameHostImpl*>(host)->frame_tree_node()); 329 FindAgentHost(static_cast<RenderFrameHostImpl*>(host)->frame_tree_node());
369 if (agent_host) 330 if (!agent_host)
370 agent_host->OnFailedNavigation(common_params, begin_params, error_code); 331 return;
332 for (auto* network : protocol::NetworkHandler::ForAgentHost(agent_host))
333 network->NavigationFailed(common_params, begin_params, error_code);
371 } 334 }
372 335
373 // static 336 // static
374 std::unique_ptr<NavigationThrottle> 337 std::unique_ptr<NavigationThrottle>
375 RenderFrameDevToolsAgentHost::CreateThrottleForNavigation( 338 RenderFrameDevToolsAgentHost::CreateThrottleForNavigation(
376 NavigationHandle* navigation_handle) { 339 NavigationHandle* navigation_handle) {
377 FrameTreeNode* frame_tree_node = 340 FrameTreeNode* frame_tree_node =
378 static_cast<NavigationHandleImpl*>(navigation_handle)->frame_tree_node(); 341 static_cast<NavigationHandleImpl*>(navigation_handle)->frame_tree_node();
379 while (frame_tree_node && frame_tree_node->parent()) { 342 while (frame_tree_node && frame_tree_node->parent()) {
380 frame_tree_node = frame_tree_node->parent(); 343 frame_tree_node = frame_tree_node->parent();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 DevToolsAgentHost::GetOrCreateFor(web_contents); 394 DevToolsAgentHost::GetOrCreateFor(web_contents);
432 } 395 }
433 } 396 }
434 397
435 RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost( 398 RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(
436 FrameTreeNode* frame_tree_node) 399 FrameTreeNode* frame_tree_node)
437 : DevToolsAgentHostImpl(base::GenerateGUID()), 400 : DevToolsAgentHostImpl(base::GenerateGUID()),
438 frame_trace_recorder_(nullptr), 401 frame_trace_recorder_(nullptr),
439 handlers_frame_host_(nullptr), 402 handlers_frame_host_(nullptr),
440 current_frame_crashed_(false), 403 current_frame_crashed_(false),
441 pending_handle_(nullptr), 404 chunk_processor_(
405 base::Bind(&RenderFrameDevToolsAgentHost::SendMessageFromProcessor,
406 base::Unretained(this))),
442 frame_tree_node_(frame_tree_node) { 407 frame_tree_node_(frame_tree_node) {
443 if (frame_tree_node->current_frame_host()) { 408 if (IsBrowserSideNavigationEnabled()) {
444 SetPending(frame_tree_node->current_frame_host()); 409 frame_host_ = frame_tree_node->current_frame_host();
445 CommitPending(); 410 render_frame_alive_ = frame_host_ && frame_host_->IsRenderFrameLive();
411 } else {
412 if (frame_tree_node->current_frame_host()) {
413 SetPending(frame_tree_node->current_frame_host());
414 CommitPending();
415 }
446 } 416 }
447 WebContentsObserver::Observe( 417 WebContentsObserver::Observe(
448 WebContentsImpl::FromFrameTreeNode(frame_tree_node)); 418 WebContentsImpl::FromFrameTreeNode(frame_tree_node));
449 419
450 if (web_contents() && web_contents()->GetCrashedStatus() != 420 if (web_contents() && web_contents()->GetCrashedStatus() !=
451 base::TERMINATION_STATUS_STILL_RUNNING) { 421 base::TERMINATION_STATUS_STILL_RUNNING) {
452 current_frame_crashed_ = true; 422 current_frame_crashed_ = true;
453 } 423 }
454 424
455 g_instances.Get().push_back(this); 425 g_instances.Get().push_back(this);
456 AddRef(); // Balanced in RenderFrameHostDestroyed. 426 AddRef(); // Balanced in RenderFrameHostDestroyed.
457 427
458 NotifyCreated(); 428 NotifyCreated();
459 } 429 }
460 430
461 void RenderFrameDevToolsAgentHost::SetPending(RenderFrameHostImpl* host) { 431 void RenderFrameDevToolsAgentHost::SetPending(RenderFrameHostImpl* host) {
432 DCHECK(!IsBrowserSideNavigationEnabled());
462 DCHECK(!pending_); 433 DCHECK(!pending_);
463 current_frame_crashed_ = false; 434 current_frame_crashed_ = false;
464 pending_.reset(new FrameHostHolder(this, host)); 435 pending_.reset(new FrameHostHolder(this, host));
465 if (IsAttached()) 436 if (IsAttached())
466 pending_->Reattach(current_.get()); 437 pending_->Reattach(current_.get());
467 438
468 if (current_) 439 if (current_)
469 current_->Suspend(); 440 current_->Suspend();
470 pending_->Suspend(); 441 pending_->Suspend();
471 442
472 UpdateProtocolHandlers(host); 443 UpdateProtocolHandlers(host);
473 } 444 }
474 445
475 void RenderFrameDevToolsAgentHost::CommitPending() { 446 void RenderFrameDevToolsAgentHost::CommitPending() {
447 DCHECK(!IsBrowserSideNavigationEnabled());
476 DCHECK(pending_); 448 DCHECK(pending_);
477 current_frame_crashed_ = false; 449 current_frame_crashed_ = false;
478 450
479 if (!ShouldCreateDevToolsForHost(pending_->host())) { 451 if (!ShouldCreateDevToolsForHost(pending_->host())) {
480 DestroyOnRenderFrameGone(); 452 DestroyOnRenderFrameGone();
481 // |this| may be deleted at this point. 453 // |this| may be deleted at this point.
482 return; 454 return;
483 } 455 }
484 456
485 current_ = std::move(pending_); 457 current_ = std::move(pending_);
486 UpdateProtocolHandlers(current_->host()); 458 UpdateProtocolHandlers(current_->host());
487 current_->Resume(); 459 current_->Resume();
488 } 460 }
489 461
490 void RenderFrameDevToolsAgentHost::DiscardPending() { 462 void RenderFrameDevToolsAgentHost::DiscardPending() {
463 DCHECK(!IsBrowserSideNavigationEnabled());
491 DCHECK(pending_); 464 DCHECK(pending_);
492 DCHECK(current_); 465 DCHECK(current_);
493 pending_.reset(); 466 pending_.reset();
494 UpdateProtocolHandlers(current_->host()); 467 UpdateProtocolHandlers(current_->host());
495 current_->Resume(); 468 current_->Resume();
496 } 469 }
497 470
498 BrowserContext* RenderFrameDevToolsAgentHost::GetBrowserContext() { 471 BrowserContext* RenderFrameDevToolsAgentHost::GetBrowserContext() {
499 WebContents* contents = web_contents(); 472 WebContents* contents = web_contents();
500 return contents ? contents->GetBrowserContext() : nullptr; 473 return contents ? contents->GetBrowserContext() : nullptr;
501 } 474 }
502 475
503 WebContents* RenderFrameDevToolsAgentHost::GetWebContents() { 476 WebContents* RenderFrameDevToolsAgentHost::GetWebContents() {
504 return web_contents(); 477 return web_contents();
505 } 478 }
506 479
507 void RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) { 480 void RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) {
508 session->SetFallThroughForNotFound(true); 481 session->SetFallThroughForNotFound(true);
509 session->SetRenderFrameHost(handlers_frame_host_); 482 if (IsBrowserSideNavigationEnabled())
483 session->SetRenderFrameHost(frame_host_);
484 else
485 session->SetRenderFrameHost(handlers_frame_host_);
510 if (frame_tree_node_ && !frame_tree_node_->parent()) { 486 if (frame_tree_node_ && !frame_tree_node_->parent()) {
511 session->AddHandler(base::WrapUnique(new protocol::PageHandler())); 487 session->AddHandler(base::WrapUnique(new protocol::PageHandler()));
512 session->AddHandler(base::WrapUnique(new protocol::SecurityHandler())); 488 session->AddHandler(base::WrapUnique(new protocol::SecurityHandler()));
513 } 489 }
514 session->AddHandler(base::WrapUnique(new protocol::DOMHandler())); 490 session->AddHandler(base::WrapUnique(new protocol::DOMHandler()));
515 session->AddHandler(base::WrapUnique(new protocol::EmulationHandler())); 491 session->AddHandler(base::WrapUnique(new protocol::EmulationHandler()));
516 session->AddHandler(base::WrapUnique(new protocol::InputHandler())); 492 session->AddHandler(base::WrapUnique(new protocol::InputHandler()));
517 session->AddHandler(base::WrapUnique(new protocol::InspectorHandler())); 493 session->AddHandler(base::WrapUnique(new protocol::InspectorHandler()));
518 session->AddHandler(base::WrapUnique(new protocol::IOHandler( 494 session->AddHandler(base::WrapUnique(new protocol::IOHandler(
519 GetIOContext()))); 495 GetIOContext())));
520 session->AddHandler(base::WrapUnique(new protocol::NetworkHandler())); 496 session->AddHandler(base::WrapUnique(new protocol::NetworkHandler()));
521 session->AddHandler(base::WrapUnique(new protocol::SchemaHandler())); 497 session->AddHandler(base::WrapUnique(new protocol::SchemaHandler()));
522 session->AddHandler(base::WrapUnique(new protocol::ServiceWorkerHandler())); 498 session->AddHandler(base::WrapUnique(new protocol::ServiceWorkerHandler()));
523 session->AddHandler(base::WrapUnique(new protocol::StorageHandler())); 499 session->AddHandler(base::WrapUnique(new protocol::StorageHandler()));
524 session->AddHandler(base::WrapUnique(new protocol::TargetHandler())); 500 session->AddHandler(base::WrapUnique(new protocol::TargetHandler()));
525 session->AddHandler(base::WrapUnique(new protocol::TracingHandler( 501 session->AddHandler(base::WrapUnique(new protocol::TracingHandler(
526 protocol::TracingHandler::Renderer, 502 protocol::TracingHandler::Renderer,
527 frame_tree_node_ ? frame_tree_node_->frame_tree_node_id() : 0, 503 frame_tree_node_ ? frame_tree_node_->frame_tree_node_id() : 0,
528 GetIOContext()))); 504 GetIOContext())));
529 505
530 if (current_) 506 if (IsBrowserSideNavigationEnabled()) {
531 current_->Attach(session); 507 if (frame_host_) {
532 if (pending_) 508 frame_host_->Send(new DevToolsAgentMsg_Attach(
533 pending_->Attach(session); 509 frame_host_->GetRoutingID(), GetId(), session->session_id()));
510 }
511 } else {
512 if (current_)
513 current_->Attach(session);
514 if (pending_)
515 pending_->Attach(session);
516 }
534 OnClientAttached(); 517 OnClientAttached();
535 } 518 }
536 519
537 void RenderFrameDevToolsAgentHost::DetachSession(int session_id) { 520 void RenderFrameDevToolsAgentHost::DetachSession(int session_id) {
538 if (current_) 521 if (IsBrowserSideNavigationEnabled()) {
539 current_->Detach(session_id); 522 if (frame_host_) {
540 if (pending_) 523 frame_host_->Send(
541 pending_->Detach(session_id); 524 new DevToolsAgentMsg_Detach(frame_host_->GetRoutingID(), session_id));
525 }
526 } else {
527 if (current_)
528 current_->Detach(session_id);
529 if (pending_)
530 pending_->Detach(session_id);
531 }
542 OnClientDetached(); 532 OnClientDetached();
543 } 533 }
544 534
545 bool RenderFrameDevToolsAgentHost::DispatchProtocolMessage( 535 bool RenderFrameDevToolsAgentHost::DispatchProtocolMessage(
546 DevToolsSession* session, 536 DevToolsSession* session,
547 const std::string& message) { 537 const std::string& message) {
548 int call_id = 0; 538 int call_id = 0;
549 std::string method; 539 std::string method;
540 int session_id = session->session_id();
550 if (session->Dispatch(message, &call_id, &method) != 541 if (session->Dispatch(message, &call_id, &method) !=
551 protocol::Response::kFallThrough) { 542 protocol::Response::kFallThrough) {
552 return true; 543 return true;
553 } 544 }
554 545
555 if (!navigating_handles_.empty()) { 546 if (IsBrowserSideNavigationEnabled()) {
556 DCHECK(IsBrowserSideNavigationEnabled()); 547 if (!navigation_handles_.empty()) {
557 in_navigation_protocol_message_buffer_[call_id] = 548 suspended_messages_[call_id] = {session_id, method, message};
558 { session->session_id(), method, message }; 549 return true;
559 return true; 550 }
560 } 551 if (frame_host_) {
561 552 frame_host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
562 if (current_) { 553 frame_host_->GetRoutingID(), session_id, call_id, method, message));
563 current_->DispatchProtocolMessage( 554 }
564 session->session_id(), call_id, method, message); 555 waiting_for_response_messages_[call_id] = {session_id, method, message};
565 } 556 } else {
566 if (pending_) { 557 if (current_)
567 pending_->DispatchProtocolMessage( 558 current_->DispatchProtocolMessage(session_id, call_id, method, message);
568 session->session_id(), call_id, method, message); 559 if (pending_)
560 pending_->DispatchProtocolMessage(session_id, call_id, method, message);
569 } 561 }
570 return true; 562 return true;
571 } 563 }
572 564
573 void RenderFrameDevToolsAgentHost::InspectElement( 565 void RenderFrameDevToolsAgentHost::InspectElement(
574 DevToolsSession* session, 566 DevToolsSession* session,
575 int x, 567 int x,
576 int y) { 568 int y) {
577 if (current_) 569 if (IsBrowserSideNavigationEnabled()) {
578 current_->InspectElement(session->session_id(), x, y); 570 if (frame_host_) {
579 if (pending_) 571 frame_host_->Send(new DevToolsAgentMsg_InspectElement(
580 pending_->InspectElement(session->session_id(), x, y); 572 frame_host_->GetRoutingID(), session->session_id(), x, y));
573 }
574 } else {
575 if (current_)
576 current_->InspectElement(session->session_id(), x, y);
577 if (pending_)
578 pending_->InspectElement(session->session_id(), x, y);
579 }
581 } 580 }
582 581
583 void RenderFrameDevToolsAgentHost::OnClientAttached() { 582 void RenderFrameDevToolsAgentHost::OnClientAttached() {
584 if (!web_contents()) 583 if (!web_contents())
585 return; 584 return;
586 585
587 frame_trace_recorder_.reset(new DevToolsFrameTraceRecorder()); 586 frame_trace_recorder_.reset(new DevToolsFrameTraceRecorder());
588 #if defined(OS_ANDROID) 587 #if defined(OS_ANDROID)
589 GetWakeLock()->RequestWakeLock(); 588 GetWakeLock()->RequestWakeLock();
590 #endif 589 #endif
590 if (IsBrowserSideNavigationEnabled())
591 GrantPolicy(frame_host_);
591 } 592 }
592 593
593 void RenderFrameDevToolsAgentHost::OnClientDetached() { 594 void RenderFrameDevToolsAgentHost::OnClientDetached() {
594 #if defined(OS_ANDROID) 595 #if defined(OS_ANDROID)
595 GetWakeLock()->CancelWakeLock(); 596 GetWakeLock()->CancelWakeLock();
596 #endif 597 #endif
597 frame_trace_recorder_.reset(); 598 frame_trace_recorder_.reset();
598 in_navigation_protocol_message_buffer_.clear(); 599 waiting_for_response_messages_.clear();
600 suspended_messages_.clear();
601 chunk_processor_.Reset();
602 if (IsBrowserSideNavigationEnabled())
603 RevokePolicy(frame_host_);
599 } 604 }
600 605
601 RenderFrameDevToolsAgentHost::~RenderFrameDevToolsAgentHost() { 606 RenderFrameDevToolsAgentHost::~RenderFrameDevToolsAgentHost() {
602 Instances::iterator it = std::find(g_instances.Get().begin(), 607 Instances::iterator it = std::find(g_instances.Get().begin(),
603 g_instances.Get().end(), 608 g_instances.Get().end(),
604 this); 609 this);
605 if (it != g_instances.Get().end()) 610 if (it != g_instances.Get().end())
606 g_instances.Get().erase(it); 611 g_instances.Get().erase(it);
607 } 612 }
608 613
609 void RenderFrameDevToolsAgentHost::ReadyToCommitNavigation( 614 void RenderFrameDevToolsAgentHost::ReadyToCommitNavigation(
610 NavigationHandle* navigation_handle) { 615 NavigationHandle* navigation_handle) {
611 // CommitPending may destruct |this|.
612 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
613
614 // TODO(clamy): Switch RenderFrameDevToolsAgentHost to always buffer messages
615 // until ReadyToCommitNavigation is called, now that it is also called in
616 // non-PlzNavigate mode.
617 if (!IsBrowserSideNavigationEnabled()) 616 if (!IsBrowserSideNavigationEnabled())
618 return; 617 return;
619 618 NavigationHandleImpl* handle =
620 // If the navigation is not tracked, return; 619 static_cast<NavigationHandleImpl*>(navigation_handle);
621 if (navigating_handles_.count(navigation_handle) == 0) 620 if (handle->frame_tree_node() != frame_tree_node_)
622 return; 621 return;
623 622
624 RenderFrameHostImpl* render_frame_host_impl = 623 // UpdateFrameHost may destruct |this|.
625 static_cast<RenderFrameHostImpl*>( 624 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
626 navigation_handle->GetRenderFrameHost()); 625 UpdateFrameHost(handle->GetRenderFrameHost());
627 if (current_->host() != render_frame_host_impl || current_frame_crashed_) {
628 SetPending(render_frame_host_impl);
629 pending_handle_ = navigation_handle;
630 // Commit when navigating the same frame after crash, avoiding the same
631 // host in current_ and pending_.
632 if (current_->host() == render_frame_host_impl) {
633 pending_handle_ = nullptr;
634 CommitPending();
635 }
636 }
637 DCHECK(CheckConsistency()); 626 DCHECK(CheckConsistency());
638 } 627 }
639 628
640 void RenderFrameDevToolsAgentHost::DidFinishNavigation( 629 void RenderFrameDevToolsAgentHost::DidFinishNavigation(
641 NavigationHandle* navigation_handle) { 630 NavigationHandle* navigation_handle) {
642 // CommitPending may destruct |this|.
643 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
644
645 if (!IsBrowserSideNavigationEnabled()) { 631 if (!IsBrowserSideNavigationEnabled()) {
632 // CommitPending may destruct |this|.
633 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
646 if (navigation_handle->HasCommitted() && 634 if (navigation_handle->HasCommitted() &&
647 !navigation_handle->IsErrorPage()) { 635 !navigation_handle->IsErrorPage()) {
648 if (pending_ && 636 if (pending_ &&
649 pending_->host() == navigation_handle->GetRenderFrameHost()) { 637 pending_->host() == navigation_handle->GetRenderFrameHost()) {
650 CommitPending(); 638 CommitPending();
651 } 639 }
652 for (auto* target : protocol::TargetHandler::ForAgentHost(this)) 640 for (auto* target : protocol::TargetHandler::ForAgentHost(this))
653 target->UpdateServiceWorkers(); 641 target->UpdateServiceWorkers();
654 } else if (pending_ && pending_->host()->GetFrameTreeNodeId() == 642 } else if (pending_ && pending_->host()->GetFrameTreeNodeId() ==
655 navigation_handle->GetFrameTreeNodeId()) { 643 navigation_handle->GetFrameTreeNodeId()) {
656 DiscardPending(); 644 DiscardPending();
657 } 645 }
658 DCHECK(CheckConsistency()); 646 DCHECK(CheckConsistency());
659 return; 647 return;
660 } 648 }
661 649
662 // If the navigation is not tracked, return; 650 NavigationHandleImpl* handle =
663 if (navigating_handles_.count(navigation_handle) == 0) 651 static_cast<NavigationHandleImpl*>(navigation_handle);
652 if (handle->frame_tree_node() != frame_tree_node_)
653 return;
654 navigation_handles_.erase(handle);
655
656 // UpdateFrameHost may destruct |this|.
657 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
658 if (handle->HasCommitted() && !handle->IsErrorPage())
659 UpdateFrameHost(handle->GetRenderFrameHost());
660 DCHECK(CheckConsistency());
661 if (navigation_handles_.empty()) {
662 if (session() && frame_host_) {
663 for (const auto& pair : suspended_messages_) {
664 const Message& message = pair.second;
665 frame_host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
666 frame_host_->GetRoutingID(), message.session_id, pair.first,
667 message.method, message.message));
668 }
669 }
670 waiting_for_response_messages_.insert(suspended_messages_.begin(),
671 suspended_messages_.end());
672 suspended_messages_.clear();
673 }
674 if (handle->HasCommitted()) {
675 for (auto* target : protocol::TargetHandler::ForAgentHost(this))
676 target->UpdateServiceWorkers();
677 }
678 }
679
680 void RenderFrameDevToolsAgentHost::UpdateFrameHost(
681 RenderFrameHostImpl* frame_host) {
682 if (frame_host == frame_host_) {
683 if (frame_host && !render_frame_alive_) {
684 render_frame_alive_ = true;
685 MaybeReattachToRenderFrame();
686 }
687 return;
688 }
689
690 if (session())
691 RevokePolicy(frame_host_);
692
693 if (frame_host && !ShouldCreateDevToolsForHost(frame_host)) {
694 DestroyOnRenderFrameGone();
695 // |this| may be deleted at this point.
696 return;
697 }
698
699 frame_host_ = frame_host;
700 render_frame_alive_ = true;
701 if (session()) {
702 GrantPolicy(frame_host_);
703 session()->SetRenderFrameHost(frame_host);
704 MaybeReattachToRenderFrame();
705 }
706 }
707
708 void RenderFrameDevToolsAgentHost::MaybeReattachToRenderFrame() {
709 DCHECK(IsBrowserSideNavigationEnabled());
710 if (!session() || !frame_host_)
711 return;
712 int session_id = session()->session_id();
713 frame_host_->Send(new DevToolsAgentMsg_Reattach(
714 frame_host_->GetRoutingID(), GetId(), session_id,
715 chunk_processor_.state_cookie()));
716 for (const auto& pair : waiting_for_response_messages_) {
717 const Message& message = pair.second;
718 frame_host_->Send(new DevToolsAgentMsg_DispatchOnInspectorBackend(
719 frame_host_->GetRoutingID(), message.session_id, pair.first,
720 message.method, message.message));
721 }
722 }
723
724 void RenderFrameDevToolsAgentHost::SendMessageFromProcessor(
725 int session_id,
726 const std::string& message) {
727 int id = chunk_processor_.last_call_id();
728 waiting_for_response_messages_.erase(id);
729 SendMessageToClient(session_id, message);
730 // |this| may be deleted at this point.
731 }
732
733 void RenderFrameDevToolsAgentHost::GrantPolicy(RenderFrameHostImpl* host) {
734 if (!host)
735 return;
736 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadRawCookies(
737 host->GetProcess()->GetID());
738 }
739
740 void RenderFrameDevToolsAgentHost::RevokePolicy(RenderFrameHostImpl* host) {
741 if (!host)
664 return; 742 return;
665 743
666 // Now that the navigation is finished, remove the handle from the list of 744 bool process_has_agents = false;
667 // navigating handles. 745 RenderProcessHost* process_host = host->GetProcess();
668 navigating_handles_.erase(navigation_handle); 746 for (RenderFrameDevToolsAgentHost* agent : g_instances.Get()) {
747 if (!agent->IsAttached())
748 continue;
749 if (IsBrowserSideNavigationEnabled()) {
750 if (agent->frame_host_ && agent->frame_host_ != host &&
751 agent->frame_host_->GetProcess() == process_host) {
752 process_has_agents = true;
753 }
754 continue;
755 }
756 if (agent->current_ && agent->current_->host() != host &&
757 agent->current_->host()->GetProcess() == process_host) {
758 process_has_agents = true;
759 }
760 if (agent->pending_ && agent->pending_->host() != host &&
761 agent->pending_->host()->GetProcess() == process_host) {
762 process_has_agents = true;
763 }
764 }
669 765
670 if (pending_handle_ == navigation_handle) { 766 // We are the last to disconnect from the renderer -> revoke permissions.
671 // This navigation handle did set the pending FrameHostHolder. 767 if (!process_has_agents) {
672 DCHECK(pending_); 768 ChildProcessSecurityPolicyImpl::GetInstance()->RevokeReadRawCookies(
673 if (navigation_handle->HasCommitted()) { 769 process_host->GetID());
674 DCHECK(pending_->host() == navigation_handle->GetRenderFrameHost());
675 CommitPending();
676 } else {
677 DiscardPending();
678 }
679 pending_handle_ = nullptr;
680 } else if (navigating_handles_.empty()) {
681 current_->Resume();
682 }
683 DispatchBufferedProtocolMessagesIfNecessary();
684
685 DCHECK(CheckConsistency());
686 if (navigation_handle->HasCommitted()) {
687 for (auto* target : protocol::TargetHandler::ForAgentHost(this))
688 target->UpdateServiceWorkers();
689 } 770 }
690 } 771 }
691 772
692 void RenderFrameDevToolsAgentHost::AboutToNavigateRenderFrame( 773 void RenderFrameDevToolsAgentHost::AboutToNavigateRenderFrame(
693 RenderFrameHost* old_host, 774 RenderFrameHost* old_host,
694 RenderFrameHost* new_host) { 775 RenderFrameHost* new_host) {
776 if (IsBrowserSideNavigationEnabled())
777 return;
778
695 // CommitPending may destruct |this|. 779 // CommitPending may destruct |this|.
696 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this); 780 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
697 781
698 if (IsBrowserSideNavigationEnabled())
699 return;
700
701 DCHECK(!pending_ || pending_->host() != old_host); 782 DCHECK(!pending_ || pending_->host() != old_host);
702 if (!current_ || current_->host() != old_host) { 783 if (!current_ || current_->host() != old_host) {
703 DCHECK(CheckConsistency()); 784 DCHECK(CheckConsistency());
704 return; 785 return;
705 } 786 }
706 if (old_host == new_host && !current_frame_crashed_) { 787 if (old_host == new_host && !current_frame_crashed_) {
707 DCHECK(CheckConsistency()); 788 DCHECK(CheckConsistency());
708 return; 789 return;
709 } 790 }
710 DCHECK(!pending_); 791 DCHECK(!pending_);
711 SetPending(static_cast<RenderFrameHostImpl*>(new_host)); 792 SetPending(static_cast<RenderFrameHostImpl*>(new_host));
712 // Commit when navigating the same frame after crash, avoiding the same 793 // Commit when navigating the same frame after crash, avoiding the same
713 // host in current_ and pending_. 794 // host in current_ and pending_.
714 if (old_host == new_host) 795 if (old_host == new_host)
715 CommitPending(); 796 CommitPending();
716 DCHECK(CheckConsistency()); 797 DCHECK(CheckConsistency());
717 } 798 }
718 799
719 void RenderFrameDevToolsAgentHost::AboutToNavigate( 800 void RenderFrameDevToolsAgentHost::DidStartNavigation(
720 NavigationHandle* navigation_handle) { 801 NavigationHandle* navigation_handle) {
721 if (!IsBrowserSideNavigationEnabled()) 802 if (!IsBrowserSideNavigationEnabled())
722 return; 803 return;
723 DCHECK(current_); 804 NavigationHandleImpl* handle =
724 navigating_handles_.insert(navigation_handle); 805 static_cast<NavigationHandleImpl*>(navigation_handle);
725 current_->Suspend(); 806 if (handle->frame_tree_node() != frame_tree_node_)
807 return;
808 navigation_handles_.insert(handle);
726 DCHECK(CheckConsistency()); 809 DCHECK(CheckConsistency());
727 } 810 }
728 811
729 void RenderFrameDevToolsAgentHost::OnFailedNavigation(
730 const CommonNavigationParams& common_params,
731 const BeginNavigationParams& begin_params,
732 net::Error error_code) {
733 DCHECK(IsBrowserSideNavigationEnabled());
734 for (auto* network : protocol::NetworkHandler::ForAgentHost(this))
735 network->NavigationFailed(common_params, begin_params, error_code);
736 }
737
738 void RenderFrameDevToolsAgentHost::RenderFrameHostChanged( 812 void RenderFrameDevToolsAgentHost::RenderFrameHostChanged(
739 RenderFrameHost* old_host, 813 RenderFrameHost* old_host,
740 RenderFrameHost* new_host) { 814 RenderFrameHost* new_host) {
815 for (auto* target : protocol::TargetHandler::ForAgentHost(this))
816 target->UpdateFrames();
817
818 if (IsBrowserSideNavigationEnabled()) {
819 if (old_host != frame_host_)
820 return;
821
822 // UpdateFrameHost may destruct |this|.
823 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
824 UpdateFrameHost(nullptr);
825 DCHECK(CheckConsistency());
826 return;
827 }
828
741 // CommitPending may destruct |this|. 829 // CommitPending may destruct |this|.
742 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this); 830 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
743 831
744 for (auto* target : protocol::TargetHandler::ForAgentHost(this))
745 target->UpdateFrames();
746
747 if (IsBrowserSideNavigationEnabled() && !current_frame_crashed_)
748 return;
749
750 DCHECK(!pending_ || pending_->host() != old_host); 832 DCHECK(!pending_ || pending_->host() != old_host);
751 if (!current_ || current_->host() != old_host) { 833 if (!current_ || current_->host() != old_host) {
752 DCHECK(CheckConsistency()); 834 DCHECK(CheckConsistency());
753 return; 835 return;
754 } 836 }
755 837
756 // AboutToNavigateRenderFrame was not called for renderer-initiated 838 // AboutToNavigateRenderFrame was not called for renderer-initiated
757 // navigation. 839 // navigation.
758 if (!pending_) 840 if (!pending_)
759 SetPending(static_cast<RenderFrameHostImpl*>(new_host)); 841 SetPending(static_cast<RenderFrameHostImpl*>(new_host));
760 CommitPending(); 842 CommitPending();
761 DCHECK(CheckConsistency()); 843 DCHECK(CheckConsistency());
762 } 844 }
763 845
764 void RenderFrameDevToolsAgentHost::FrameDeleted(RenderFrameHost* rfh) { 846 void RenderFrameDevToolsAgentHost::FrameDeleted(RenderFrameHost* rfh) {
847 if (IsBrowserSideNavigationEnabled()) {
848 if (static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node() ==
849 frame_tree_node_)
850 DestroyOnRenderFrameGone(); // |this| may be deleted at this point.
851 else
852 DCHECK(CheckConsistency());
853 return;
854 }
855
765 if (pending_ && pending_->host() == rfh) { 856 if (pending_ && pending_->host() == rfh) {
766 if (!IsBrowserSideNavigationEnabled()) 857 if (!IsBrowserSideNavigationEnabled())
767 DiscardPending(); 858 DiscardPending();
768 DCHECK(CheckConsistency()); 859 DCHECK(CheckConsistency());
769 return; 860 return;
770 } 861 }
771 862
772 if (current_ && current_->host() == rfh) 863 if (current_ && current_->host() == rfh)
773 DestroyOnRenderFrameGone(); // |this| may be deleted at this point. 864 DestroyOnRenderFrameGone(); // |this| may be deleted at this point.
774 } 865 }
775 866
776 void RenderFrameDevToolsAgentHost::RenderFrameDeleted(RenderFrameHost* rfh) { 867 void RenderFrameDevToolsAgentHost::RenderFrameDeleted(RenderFrameHost* rfh) {
868 if (IsBrowserSideNavigationEnabled()) {
869 if (rfh == frame_host_)
870 render_frame_alive_ = false;
871 DCHECK(CheckConsistency());
872 return;
873 }
874
777 if (!current_frame_crashed_) 875 if (!current_frame_crashed_)
778 FrameDeleted(rfh); 876 FrameDeleted(rfh);
779 else 877 else
780 DCHECK(CheckConsistency()); 878 DCHECK(CheckConsistency());
781 } 879 }
782 880
783 void RenderFrameDevToolsAgentHost::DestroyOnRenderFrameGone() { 881 void RenderFrameDevToolsAgentHost::DestroyOnRenderFrameGone() {
784 DCHECK(current_);
785 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this); 882 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
786 UpdateProtocolHandlers(nullptr); 883 UpdateProtocolHandlers(nullptr);
787 if (IsAttached()) 884 if (IsAttached())
788 OnClientDetached(); 885 OnClientDetached();
789 ForceDetach(false); 886 ForceDetach(false);
887 frame_host_ = nullptr;
790 pending_.reset(); 888 pending_.reset();
791 current_.reset(); 889 current_.reset();
792 frame_tree_node_ = nullptr; 890 frame_tree_node_ = nullptr;
793 pending_handle_ = nullptr;
794 WebContentsObserver::Observe(nullptr); 891 WebContentsObserver::Observe(nullptr);
795 Release(); 892 Release();
796 } 893 }
797 894
798 bool RenderFrameDevToolsAgentHost::CheckConsistency() { 895 bool RenderFrameDevToolsAgentHost::CheckConsistency() {
799 if (current_ && pending_ && current_->host() == pending_->host()) 896 if (!IsBrowserSideNavigationEnabled()) {
800 return false; 897 if (current_ && pending_ && current_->host() == pending_->host())
801 if (IsBrowserSideNavigationEnabled()) 898 return false;
802 return true; 899 } else {
900 if (current_ || pending_)
901 return false;
902 }
903
803 if (!frame_tree_node_) 904 if (!frame_tree_node_)
804 return !handlers_frame_host_; 905 return !frame_host_;
906
805 RenderFrameHostManager* manager = frame_tree_node_->render_manager(); 907 RenderFrameHostManager* manager = frame_tree_node_->render_manager();
806 return handlers_frame_host_ == manager->current_frame_host() || 908 RenderFrameHostImpl* current = manager->current_frame_host();
807 handlers_frame_host_ == manager->pending_frame_host(); 909 RenderFrameHostImpl* pending = manager->pending_frame_host();
910 RenderFrameHostImpl* speculative = manager->speculative_frame_host();
911 RenderFrameHostImpl* host =
912 IsBrowserSideNavigationEnabled() ? frame_host_ : handlers_frame_host_;
913 return host == current || host == pending || host == speculative;
808 } 914 }
809 915
810 #if defined(OS_ANDROID) 916 #if defined(OS_ANDROID)
811 device::mojom::WakeLock* RenderFrameDevToolsAgentHost::GetWakeLock() { 917 device::mojom::WakeLock* RenderFrameDevToolsAgentHost::GetWakeLock() {
812 // Here is a lazy binding, and will not reconnect after connection error. 918 // Here is a lazy binding, and will not reconnect after connection error.
813 if (!wake_lock_) { 919 if (!wake_lock_) {
814 device::mojom::WakeLockRequest request = mojo::MakeRequest(&wake_lock_); 920 device::mojom::WakeLockRequest request = mojo::MakeRequest(&wake_lock_);
815 device::mojom::WakeLockContext* wake_lock_context = 921 device::mojom::WakeLockContext* wake_lock_context =
816 web_contents()->GetWakeLockContext(); 922 web_contents()->GetWakeLockContext();
817 if (wake_lock_context) { 923 if (wake_lock_context) {
(...skipping 28 matching lines...) Expand all
846 for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this)) 952 for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
847 inspector->TargetDetached("Render process gone."); 953 inspector->TargetDetached("Render process gone.");
848 break; 954 break;
849 } 955 }
850 DCHECK(CheckConsistency()); 956 DCHECK(CheckConsistency());
851 } 957 }
852 958
853 bool RenderFrameDevToolsAgentHost::OnMessageReceived( 959 bool RenderFrameDevToolsAgentHost::OnMessageReceived(
854 const IPC::Message& message, 960 const IPC::Message& message,
855 RenderFrameHost* render_frame_host) { 961 RenderFrameHost* render_frame_host) {
856 bool is_current = current_ && current_->host() == render_frame_host; 962 if (IsBrowserSideNavigationEnabled()) {
857 bool is_pending = pending_ && pending_->host() == render_frame_host; 963 if (render_frame_host != frame_host_)
858 if (!is_current && !is_pending) 964 return false;
859 return false; 965 } else {
966 bool is_current = current_ && current_->host() == render_frame_host;
967 bool is_pending = pending_ && pending_->host() == render_frame_host;
968 if (!is_current && !is_pending)
969 return false;
970 }
860 if (!IsAttached()) 971 if (!IsAttached())
861 return false; 972 return false;
862 bool handled = true; 973 bool handled = true;
863 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(RenderFrameDevToolsAgentHost, message, 974 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(RenderFrameDevToolsAgentHost, message,
864 render_frame_host) 975 render_frame_host)
865 IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend, 976 IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
866 OnDispatchOnInspectorFrontend) 977 OnDispatchOnInspectorFrontend)
867 IPC_MESSAGE_HANDLER(DevToolsAgentHostMsg_RequestNewWindow, 978 IPC_MESSAGE_HANDLER(DevToolsAgentHostMsg_RequestNewWindow,
868 OnRequestNewWindow) 979 OnRequestNewWindow)
869 IPC_MESSAGE_UNHANDLED(handled = false) 980 IPC_MESSAGE_UNHANDLED(handled = false)
870 IPC_END_MESSAGE_MAP() 981 IPC_END_MESSAGE_MAP()
871 return handled; 982 return handled;
872 } 983 }
873 984
874 void RenderFrameDevToolsAgentHost::DidAttachInterstitialPage() { 985 void RenderFrameDevToolsAgentHost::DidAttachInterstitialPage() {
875 for (auto* page : protocol::PageHandler::ForAgentHost(this)) 986 for (auto* page : protocol::PageHandler::ForAgentHost(this))
876 page->DidAttachInterstitialPage(); 987 page->DidAttachInterstitialPage();
877 988
989 if (IsBrowserSideNavigationEnabled())
990 return;
991
878 // TODO(dgozman): this may break for cross-process subframes. 992 // TODO(dgozman): this may break for cross-process subframes.
879 if (!pending_) { 993 if (!pending_) {
880 DCHECK(CheckConsistency()); 994 DCHECK(CheckConsistency());
881 return; 995 return;
882 } 996 }
883 // Pending set in AboutToNavigateRenderFrame turned out to be interstitial. 997 // Pending set in AboutToNavigateRenderFrame turned out to be interstitial.
884 // Connect back to the real one. 998 // Connect back to the real one.
885 DiscardPending(); 999 DiscardPending();
886 pending_handle_ = nullptr;
887 DCHECK(CheckConsistency()); 1000 DCHECK(CheckConsistency());
888 } 1001 }
889 1002
890 void RenderFrameDevToolsAgentHost::DidDetachInterstitialPage() { 1003 void RenderFrameDevToolsAgentHost::DidDetachInterstitialPage() {
891 for (auto* page : protocol::PageHandler::ForAgentHost(this)) 1004 for (auto* page : protocol::PageHandler::ForAgentHost(this))
892 page->DidDetachInterstitialPage(); 1005 page->DidDetachInterstitialPage();
893 } 1006 }
894 1007
895 void RenderFrameDevToolsAgentHost::WasShown() { 1008 void RenderFrameDevToolsAgentHost::WasShown() {
896 #if defined(OS_ANDROID) 1009 #if defined(OS_ANDROID)
(...skipping 16 matching lines...) Expand all
913 page->OnSwapCompositorFrame(metadata.Clone()); 1026 page->OnSwapCompositorFrame(metadata.Clone());
914 for (auto* input : protocol::InputHandler::ForAgentHost(this)) 1027 for (auto* input : protocol::InputHandler::ForAgentHost(this))
915 input->OnSwapCompositorFrame(metadata); 1028 input->OnSwapCompositorFrame(metadata);
916 1029
917 if (!frame_trace_recorder_) 1030 if (!frame_trace_recorder_)
918 return; 1031 return;
919 bool did_initiate_recording = false; 1032 bool did_initiate_recording = false;
920 for (auto* tracing : protocol::TracingHandler::ForAgentHost(this)) 1033 for (auto* tracing : protocol::TracingHandler::ForAgentHost(this))
921 did_initiate_recording |= tracing->did_initiate_recording(); 1034 did_initiate_recording |= tracing->did_initiate_recording();
922 if (did_initiate_recording) { 1035 if (did_initiate_recording) {
923 frame_trace_recorder_->OnSwapCompositorFrame( 1036 if (IsBrowserSideNavigationEnabled()) {
924 current_ ? current_->host() : nullptr, metadata); 1037 frame_trace_recorder_->OnSwapCompositorFrame(frame_host_, metadata);
925 } 1038 } else {
926 } 1039 frame_trace_recorder_->OnSwapCompositorFrame(
927 1040 current_ ? current_->host() : nullptr, metadata);
928 void RenderFrameDevToolsAgentHost::
929 DispatchBufferedProtocolMessagesIfNecessary() {
930 if (navigating_handles_.empty() &&
931 in_navigation_protocol_message_buffer_.size()) {
932 DCHECK(current_);
933 for (const auto& pair : in_navigation_protocol_message_buffer_) {
934 current_->DispatchProtocolMessage(
935 pair.second.session_id, pair.first, pair.second.method,
936 pair.second.message);
937 } 1041 }
938 in_navigation_protocol_message_buffer_.clear();
939 } 1042 }
940 } 1043 }
941 1044
942 void RenderFrameDevToolsAgentHost::UpdateProtocolHandlers( 1045 void RenderFrameDevToolsAgentHost::UpdateProtocolHandlers(
943 RenderFrameHostImpl* host) { 1046 RenderFrameHostImpl* host) {
1047 if (IsBrowserSideNavigationEnabled())
1048 return;
944 #if DCHECK_IS_ON() 1049 #if DCHECK_IS_ON()
945 // TODO(dgozman): fix this for browser side navigation. 1050 // Check that we don't have stale host object here by accessing some random
946 if (!IsBrowserSideNavigationEnabled()) { 1051 // properties inside.
947 // Check that we don't have stale host object here by accessing some random 1052 if (handlers_frame_host_ && handlers_frame_host_->GetRenderWidgetHost())
948 // properties inside. 1053 handlers_frame_host_->GetRenderWidgetHost()->GetRoutingID();
949 if (handlers_frame_host_ && handlers_frame_host_->GetRenderWidgetHost())
950 handlers_frame_host_->GetRenderWidgetHost()->GetRoutingID();
951 }
952 #endif 1054 #endif
953 handlers_frame_host_ = host; 1055 handlers_frame_host_ = host;
954 if (session()) 1056 if (session())
955 session()->SetRenderFrameHost(host); 1057 session()->SetRenderFrameHost(host);
956 } 1058 }
957 1059
958 void RenderFrameDevToolsAgentHost::DisconnectWebContents() { 1060 void RenderFrameDevToolsAgentHost::DisconnectWebContents() {
1061 if (IsBrowserSideNavigationEnabled()) {
1062 UpdateFrameHost(nullptr);
1063 frame_tree_node_ = nullptr;
1064 navigation_handles_.clear();
1065 WebContentsObserver::Observe(nullptr);
1066 return;
1067 }
959 if (pending_) 1068 if (pending_)
960 DiscardPending(); 1069 DiscardPending();
961 UpdateProtocolHandlers(nullptr); 1070 UpdateProtocolHandlers(nullptr);
962 if (session()) { 1071 if (session()) {
963 disconnected_cookie_ = current_->StateCookie(); 1072 disconnected_cookie_ = current_->StateCookie();
964 current_->Detach(session()->session_id()); 1073 current_->Detach(session()->session_id());
965 } 1074 }
966 current_.reset(); 1075 current_.reset();
967 frame_tree_node_ = nullptr; 1076 frame_tree_node_ = nullptr;
968 in_navigation_protocol_message_buffer_.clear();
969 navigating_handles_.clear();
970 pending_handle_ = nullptr;
971 WebContentsObserver::Observe(nullptr); 1077 WebContentsObserver::Observe(nullptr);
972 } 1078 }
973 1079
974 void RenderFrameDevToolsAgentHost::ConnectWebContents(WebContents* wc) { 1080 void RenderFrameDevToolsAgentHost::ConnectWebContents(WebContents* wc) {
1081 if (IsBrowserSideNavigationEnabled()) {
1082 RenderFrameHostImpl* host =
1083 static_cast<RenderFrameHostImpl*>(wc->GetMainFrame());
1084 DCHECK(host);
1085 frame_tree_node_ = host->frame_tree_node();
1086 WebContentsObserver::Observe(wc);
1087 UpdateFrameHost(host);
1088 return;
1089 }
1090
975 // CommitPending may destruct |this|. 1091 // CommitPending may destruct |this|.
976 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this); 1092 scoped_refptr<RenderFrameDevToolsAgentHost> protect(this);
977 1093
978 DCHECK(!current_); 1094 DCHECK(!current_);
979 DCHECK(!pending_); 1095 DCHECK(!pending_);
980 RenderFrameHostImpl* host = 1096 RenderFrameHostImpl* host =
981 static_cast<RenderFrameHostImpl*>(wc->GetMainFrame()); 1097 static_cast<RenderFrameHostImpl*>(wc->GetMainFrame());
982 DCHECK(host); 1098 DCHECK(host);
983 current_frame_crashed_ = false; 1099 current_frame_crashed_ = false;
984 current_.reset(new FrameHostHolder(this, host)); 1100 current_.reset(new FrameHostHolder(this, host));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return kTypePage; 1140 return kTypePage;
1025 } 1141 }
1026 1142
1027 std::string RenderFrameDevToolsAgentHost::GetTitle() { 1143 std::string RenderFrameDevToolsAgentHost::GetTitle() {
1028 DevToolsManager* manager = DevToolsManager::GetInstance(); 1144 DevToolsManager* manager = DevToolsManager::GetInstance();
1029 if (manager->delegate() && web_contents()) { 1145 if (manager->delegate() && web_contents()) {
1030 std::string title = manager->delegate()->GetTargetTitle(web_contents()); 1146 std::string title = manager->delegate()->GetTargetTitle(web_contents());
1031 if (!title.empty()) 1147 if (!title.empty())
1032 return title; 1148 return title;
1033 } 1149 }
1034 if (current_ && current_->host()->GetParent()) 1150 if (IsBrowserSideNavigationEnabled()) {
1035 return current_->host()->GetLastCommittedURL().spec(); 1151 if (IsChildFrame() && frame_host_)
1152 return frame_host_->GetLastCommittedURL().spec();
1153 } else {
1154 if (current_ && current_->host()->GetParent())
1155 return current_->host()->GetLastCommittedURL().spec();
1156 }
1036 if (web_contents()) 1157 if (web_contents())
1037 return base::UTF16ToUTF8(web_contents()->GetTitle()); 1158 return base::UTF16ToUTF8(web_contents()->GetTitle());
1038 return GetURL().spec(); 1159 return GetURL().spec();
1039 } 1160 }
1040 1161
1041 std::string RenderFrameDevToolsAgentHost::GetDescription() { 1162 std::string RenderFrameDevToolsAgentHost::GetDescription() {
1042 DevToolsManager* manager = DevToolsManager::GetInstance(); 1163 DevToolsManager* manager = DevToolsManager::GetInstance();
1043 if (manager->delegate() && web_contents()) 1164 if (manager->delegate() && web_contents())
1044 return manager->delegate()->GetTargetDescription(web_contents()); 1165 return manager->delegate()->GetTargetDescription(web_contents());
1045 return std::string(); 1166 return std::string();
1046 } 1167 }
1047 1168
1048 GURL RenderFrameDevToolsAgentHost::GetURL() { 1169 GURL RenderFrameDevToolsAgentHost::GetURL() {
1049 // Order is important here. 1170 // Order is important here.
1050 WebContents* web_contents = GetWebContents(); 1171 WebContents* web_contents = GetWebContents();
1051 if (web_contents && !IsChildFrame()) 1172 if (web_contents && !IsChildFrame())
1052 return web_contents->GetVisibleURL(); 1173 return web_contents->GetVisibleURL();
1053 if (pending_) 1174 if (IsBrowserSideNavigationEnabled()) {
1054 return pending_->host()->GetLastCommittedURL(); 1175 if (frame_host_)
1055 if (current_) 1176 return frame_host_->GetLastCommittedURL();
1056 return current_->host()->GetLastCommittedURL(); 1177 } else {
1178 if (pending_)
1179 return pending_->host()->GetLastCommittedURL();
1180 if (current_)
1181 return current_->host()->GetLastCommittedURL();
1182 }
1057 return GURL(); 1183 return GURL();
1058 } 1184 }
1059 1185
1060 GURL RenderFrameDevToolsAgentHost::GetFaviconURL() { 1186 GURL RenderFrameDevToolsAgentHost::GetFaviconURL() {
1061 WebContents* wc = web_contents(); 1187 WebContents* wc = web_contents();
1062 if (!wc) 1188 if (!wc)
1063 return GURL(); 1189 return GURL();
1064 NavigationEntry* entry = wc->GetController().GetLastCommittedEntry(); 1190 NavigationEntry* entry = wc->GetController().GetLastCommittedEntry();
1065 if (entry) 1191 if (entry)
1066 return entry->GetFavicon().url; 1192 return entry->GetFavicon().url;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 page->OnSynchronousSwapCompositorFrame(frame_metadata.Clone()); 1244 page->OnSynchronousSwapCompositorFrame(frame_metadata.Clone());
1119 for (auto* input : protocol::InputHandler::ForAgentHost(this)) 1245 for (auto* input : protocol::InputHandler::ForAgentHost(this))
1120 input->OnSwapCompositorFrame(frame_metadata); 1246 input->OnSwapCompositorFrame(frame_metadata);
1121 1247
1122 if (!frame_trace_recorder_) 1248 if (!frame_trace_recorder_)
1123 return; 1249 return;
1124 bool did_initiate_recording = false; 1250 bool did_initiate_recording = false;
1125 for (auto* tracing : protocol::TracingHandler::ForAgentHost(this)) 1251 for (auto* tracing : protocol::TracingHandler::ForAgentHost(this))
1126 did_initiate_recording |= tracing->did_initiate_recording(); 1252 did_initiate_recording |= tracing->did_initiate_recording();
1127 if (did_initiate_recording) { 1253 if (did_initiate_recording) {
1128 frame_trace_recorder_->OnSynchronousSwapCompositorFrame( 1254 if (IsBrowserSideNavigationEnabled()) {
1129 current_ ? current_->host() : nullptr, frame_metadata); 1255 frame_trace_recorder_->OnSynchronousSwapCompositorFrame(frame_host_,
1256 frame_metadata);
1257 } else {
1258 frame_trace_recorder_->OnSynchronousSwapCompositorFrame(
1259 current_ ? current_->host() : nullptr, frame_metadata);
1260 }
1130 } 1261 }
1131 } 1262 }
1132 1263
1133 void RenderFrameDevToolsAgentHost::OnDispatchOnInspectorFrontend( 1264 void RenderFrameDevToolsAgentHost::OnDispatchOnInspectorFrontend(
1134 RenderFrameHost* sender, 1265 RenderFrameHost* sender,
1135 const DevToolsMessageChunk& message) { 1266 const DevToolsMessageChunk& message) {
1136 bool success = true; 1267 bool success = true;
1137 if (current_ && current_->host() == sender) 1268 if (IsBrowserSideNavigationEnabled()) {
1138 success = current_->ProcessChunkedMessageFromAgent(message); 1269 if (sender == frame_host_)
1139 else if (pending_ && pending_->host() == sender) 1270 success = chunk_processor_.ProcessChunkedMessageFromAgent(message);
1140 success = pending_->ProcessChunkedMessageFromAgent(message); 1271 } else {
1272 if (current_ && current_->host() == sender)
1273 success = current_->ProcessChunkedMessageFromAgent(message);
1274 else if (pending_ && pending_->host() == sender)
1275 success = pending_->ProcessChunkedMessageFromAgent(message);
1276 }
1141 if (!success) { 1277 if (!success) {
1142 bad_message::ReceivedBadMessage( 1278 bad_message::ReceivedBadMessage(
1143 sender->GetProcess(), 1279 sender->GetProcess(),
1144 bad_message::RFH_INCONSISTENT_DEVTOOLS_MESSAGE); 1280 bad_message::RFH_INCONSISTENT_DEVTOOLS_MESSAGE);
1145 } 1281 }
1146 } 1282 }
1147 1283
1148 void RenderFrameDevToolsAgentHost::OnRequestNewWindow( 1284 void RenderFrameDevToolsAgentHost::OnRequestNewWindow(
1149 RenderFrameHost* sender, 1285 RenderFrameHost* sender,
1150 int new_routing_id) { 1286 int new_routing_id) {
1151 RenderFrameHostImpl* frame_host = RenderFrameHostImpl::FromID( 1287 RenderFrameHostImpl* frame_host = RenderFrameHostImpl::FromID(
1152 sender->GetProcess()->GetID(), new_routing_id); 1288 sender->GetProcess()->GetID(), new_routing_id);
1153 1289
1154 bool success = false; 1290 bool success = false;
1155 if (IsAttached() && sender->GetRoutingID() != new_routing_id && frame_host) { 1291 if (IsAttached() && sender->GetRoutingID() != new_routing_id && frame_host) {
1156 scoped_refptr<DevToolsAgentHost> agent = 1292 scoped_refptr<DevToolsAgentHost> agent =
1157 RenderFrameDevToolsAgentHost::GetOrCreateFor( 1293 RenderFrameDevToolsAgentHost::GetOrCreateFor(
1158 frame_host->frame_tree_node()); 1294 frame_host->frame_tree_node());
1159 success = static_cast<DevToolsAgentHostImpl*>(agent.get())->Inspect(); 1295 success = static_cast<DevToolsAgentHostImpl*>(agent.get())->Inspect();
1160 } 1296 }
1161 1297
1162 sender->Send(new DevToolsAgentMsg_RequestNewWindow_ACK( 1298 sender->Send(new DevToolsAgentMsg_RequestNewWindow_ACK(
1163 sender->GetRoutingID(), success)); 1299 sender->GetRoutingID(), success));
1164 } 1300 }
1165 1301
1166 bool RenderFrameDevToolsAgentHost::IsChildFrame() { 1302 bool RenderFrameDevToolsAgentHost::IsChildFrame() {
1167 return current_ && current_->host()->GetParent(); 1303 return frame_tree_node_ && frame_tree_node_->parent();
1168 } 1304 }
1169 1305
1170 } // namespace content 1306 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/render_frame_devtools_agent_host.h ('k') | content/browser/frame_host/navigation_request.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698