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

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 457003002: [site isolation] cross-site transfers should track the RenderFrameHost, not the View (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Self-review fixes Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/frame_host/render_frame_host_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 // the pending_nav_params_ state will already be cleaned up.) 266 // the pending_nav_params_ state will already be cleaned up.)
267 current_host()->OnSwappedOut(true); 267 current_host()->OnSwappedOut(true);
268 } else if (render_frame_host_->render_view_host()-> 268 } else if (render_frame_host_->render_view_host()->
269 is_waiting_for_beforeunload_ack()) { 269 is_waiting_for_beforeunload_ack()) {
270 // Haven't gotten around to starting the request, because we're still 270 // Haven't gotten around to starting the request, because we're still
271 // waiting for the beforeunload handler to finish. We'll pretend that it 271 // waiting for the beforeunload handler to finish. We'll pretend that it
272 // did finish, to let the navigation proceed. Note that there's a danger 272 // did finish, to let the navigation proceed. Note that there's a danger
273 // that the beforeunload handler will later finish and possibly return 273 // that the beforeunload handler will later finish and possibly return
274 // false (meaning the navigation should not proceed), but we'll ignore it 274 // false (meaning the navigation should not proceed), but we'll ignore it
275 // in this case because it took too long. 275 // in this case because it took too long.
276 if (pending_render_frame_host_->render_view_host()-> 276 if (pending_render_frame_host_->are_navigations_suspended()) {
277 are_navigations_suspended()) { 277 pending_render_frame_host_->SetNavigationsSuspended(
278 pending_render_frame_host_->render_view_host()->SetNavigationsSuspended(
279 false, base::TimeTicks::Now()); 278 false, base::TimeTicks::Now());
280 } 279 }
281 } 280 }
282 return false; 281 return false;
283 } 282 }
284 283
285 void RenderFrameHostManager::OnBeforeUnloadACK( 284 void RenderFrameHostManager::OnBeforeUnloadACK(
286 bool for_cross_site_transition, 285 bool for_cross_site_transition,
287 bool proceed, 286 bool proceed,
288 const base::TimeTicks& proceed_time) { 287 const base::TimeTicks& proceed_time) {
289 if (for_cross_site_transition) { 288 if (for_cross_site_transition) {
290 // Ignore if we're not in a cross-site navigation. 289 // Ignore if we're not in a cross-site navigation.
291 if (!cross_navigation_pending_) 290 if (!cross_navigation_pending_)
292 return; 291 return;
293 292
294 if (proceed) { 293 if (proceed) {
295 // Ok to unload the current page, so proceed with the cross-site 294 // Ok to unload the current page, so proceed with the cross-site
296 // navigation. Note that if navigations are not currently suspended, it 295 // navigation. Note that if navigations are not currently suspended, it
297 // might be because the renderer was deemed unresponsive and this call was 296 // might be because the renderer was deemed unresponsive and this call was
298 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it 297 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it
299 // is ok to do nothing here. 298 // is ok to do nothing here.
300 if (pending_render_frame_host_ && 299 if (pending_render_frame_host_ &&
301 pending_render_frame_host_->render_view_host()-> 300 pending_render_frame_host_->are_navigations_suspended()) {
302 are_navigations_suspended()) { 301 pending_render_frame_host_->SetNavigationsSuspended(false,
303 pending_render_frame_host_->render_view_host()-> 302 proceed_time);
304 SetNavigationsSuspended(false, proceed_time);
305 } 303 }
306 } else { 304 } else {
307 // Current page says to cancel. 305 // Current page says to cancel.
308 CancelPending(); 306 CancelPending();
309 cross_navigation_pending_ = false; 307 cross_navigation_pending_ = false;
310 } 308 }
311 } else { 309 } else {
312 // Non-cross site transition means closing the entire tab. 310 // Non-cross site transition means closing the entire tab.
313 bool proceed_to_fire_unload; 311 bool proceed_to_fire_unload;
314 delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time, 312 delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 CommitPending(); 449 CommitPending();
452 return; 450 return;
453 } 451 }
454 452
455 if (render_frame_host == pending_render_frame_host_) { 453 if (render_frame_host == pending_render_frame_host_) {
456 // The pending cross-site navigation completed, so show the renderer. 454 // The pending cross-site navigation completed, so show the renderer.
457 // If it committed without sending network requests (e.g., data URLs), 455 // If it committed without sending network requests (e.g., data URLs),
458 // then we still need to swap out the old RFH first and run its unload 456 // then we still need to swap out the old RFH first and run its unload
459 // handler, only if it hasn't happened yet. OK for that to happen in the 457 // handler, only if it hasn't happened yet. OK for that to happen in the
460 // background. 458 // background.
461 if (pending_render_frame_host_->render_view_host()-> 459 if (pending_render_frame_host_->HasPendingCrossSiteRequest() &&
462 HasPendingCrossSiteRequest() &&
463 pending_render_frame_host_->render_view_host()->rvh_state() == 460 pending_render_frame_host_->render_view_host()->rvh_state() ==
464 RenderViewHostImpl::STATE_DEFAULT) { 461 RenderViewHostImpl::STATE_DEFAULT) {
465 SwapOutOldPage(); 462 SwapOutOldPage();
466 } 463 }
467 464
468 CommitPending(); 465 CommitPending();
469 cross_navigation_pending_ = false; 466 cross_navigation_pending_ = false;
470 } else if (render_frame_host == render_frame_host_) { 467 } else if (render_frame_host == render_frame_host_) {
471 // A navigation in the original page has taken place. Cancel the pending 468 // A navigation in the original page has taken place. Cancel the pending
472 // one. 469 // one.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 // handler in the background (without firing the beforeunload handler a second 539 // handler in the background (without firing the beforeunload handler a second
543 // time). When the navigation completes, we will send a message to the 540 // time). When the navigation completes, we will send a message to the
544 // ResourceDispatcherHost, allowing the pending RVH's response to resume. 541 // ResourceDispatcherHost, allowing the pending RVH's response to resume.
545 render_frame_host_->SwapOut(proxy); 542 render_frame_host_->SwapOut(proxy);
546 543
547 // ResourceDispatcherHost has told us to run the onunload handler, which 544 // ResourceDispatcherHost has told us to run the onunload handler, which
548 // means it is not a download or unsafe page, and we are going to perform the 545 // means it is not a download or unsafe page, and we are going to perform the
549 // navigation. Thus, we no longer need to remember that the RenderFrameHost 546 // navigation. Thus, we no longer need to remember that the RenderFrameHost
550 // is part of a pending cross-site request. 547 // is part of a pending cross-site request.
551 if (pending_render_frame_host_) { 548 if (pending_render_frame_host_) {
552 pending_render_frame_host_->render_view_host()-> 549 pending_render_frame_host_->SetHasPendingCrossSiteRequest(false);
553 SetHasPendingCrossSiteRequest(false);
554 } 550 }
555 } 551 }
556 552
557 void RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance( 553 void RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance(
558 int32 site_instance_id, 554 int32 site_instance_id,
559 RenderFrameHostImpl* rfh) { 555 RenderFrameHostImpl* rfh) {
560 RFHPendingDeleteMap::iterator iter = 556 RFHPendingDeleteMap::iterator iter =
561 pending_delete_hosts_.find(site_instance_id); 557 pending_delete_hosts_.find(site_instance_id);
562 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh) 558 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh)
563 pending_delete_hosts_.erase(site_instance_id); 559 pending_delete_hosts_.erase(site_instance_id);
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 } 1398 }
1403 } 1399 }
1404 // Otherwise, it's safe to treat this as a pending cross-site transition. 1400 // Otherwise, it's safe to treat this as a pending cross-site transition.
1405 1401
1406 // We need to wait until the beforeunload handler has run, unless we are 1402 // We need to wait until the beforeunload handler has run, unless we are
1407 // transferring an existing request (in which case it has already run). 1403 // transferring an existing request (in which case it has already run).
1408 // Suspend the new render view (i.e., don't let it send the cross-site 1404 // Suspend the new render view (i.e., don't let it send the cross-site
1409 // Navigate message) until we hear back from the old renderer's 1405 // Navigate message) until we hear back from the old renderer's
1410 // beforeunload handler. If the handler returns false, we'll have to 1406 // beforeunload handler. If the handler returns false, we'll have to
1411 // cancel the request. 1407 // cancel the request.
1412 DCHECK(!pending_render_frame_host_->render_view_host()-> 1408 DCHECK(!pending_render_frame_host_->are_navigations_suspended());
1413 are_navigations_suspended());
1414 bool is_transfer = 1409 bool is_transfer =
1415 entry.transferred_global_request_id() != GlobalRequestID(); 1410 entry.transferred_global_request_id() != GlobalRequestID();
1416 if (is_transfer) { 1411 if (is_transfer) {
1417 // We don't need to stop the old renderer or run beforeunload/unload 1412 // We don't need to stop the old renderer or run beforeunload/unload
1418 // handlers, because those have already been done. 1413 // handlers, because those have already been done.
1419 DCHECK(pending_nav_params_->global_request_id == 1414 DCHECK(pending_nav_params_->global_request_id ==
1420 entry.transferred_global_request_id()); 1415 entry.transferred_global_request_id());
1421 } else { 1416 } else {
1422 // Also make sure the old render view stops, in case a load is in 1417 // Also make sure the old render view stops, in case a load is in
1423 // progress. (We don't want to do this for transfers, since it will 1418 // progress. (We don't want to do this for transfers, since it will
1424 // interrupt the transfer with an unexpected DidStopLoading.) 1419 // interrupt the transfer with an unexpected DidStopLoading.)
1425 render_frame_host_->render_view_host()->Send(new ViewMsg_Stop( 1420 render_frame_host_->render_view_host()->Send(new ViewMsg_Stop(
1426 render_frame_host_->render_view_host()->GetRoutingID())); 1421 render_frame_host_->render_view_host()->GetRoutingID()));
1427 1422
1428 pending_render_frame_host_->render_view_host()->SetNavigationsSuspended( 1423 pending_render_frame_host_->SetNavigationsSuspended(true,
1429 true, base::TimeTicks()); 1424 base::TimeTicks());
1430 1425
1431 // Tell the CrossSiteRequestManager that this RVH has a pending cross-site 1426 // Tell the CrossSiteRequestManager that this RFH has a pending cross-site
1432 // request, so that ResourceDispatcherHost will know to tell us to run the 1427 // request, so that ResourceDispatcherHost will know to tell us to run the
1433 // old page's unload handler before it sends the response. 1428 // old page's unload handler before it sends the response.
1434 // TODO(creis): This needs to be on the RFH. 1429 pending_render_frame_host_->SetHasPendingCrossSiteRequest(true);
1435 pending_render_frame_host_->render_view_host()->
1436 SetHasPendingCrossSiteRequest(true);
1437 } 1430 }
1438 1431
1439 // We now have a pending RFH. 1432 // We now have a pending RFH.
1440 DCHECK(!cross_navigation_pending_); 1433 DCHECK(!cross_navigation_pending_);
1441 cross_navigation_pending_ = true; 1434 cross_navigation_pending_ = true;
1442 1435
1443 // Unless we are transferring an existing request, we should now 1436 // Unless we are transferring an existing request, we should now
1444 // tell the old render view to run its beforeunload handler, since it 1437 // tell the old render view to run its beforeunload handler, since it
1445 // doesn't otherwise know that the cross-site request is happening. This 1438 // doesn't otherwise know that the cross-site request is happening. This
1446 // will trigger a call to OnBeforeUnloadACK with the reply. 1439 // will trigger a call to OnBeforeUnloadACK with the reply.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 1494
1502 // We no longer need to prevent the process from exiting. 1495 // We no longer need to prevent the process from exiting.
1503 pending_render_frame_host->GetProcess()->RemovePendingView(); 1496 pending_render_frame_host->GetProcess()->RemovePendingView();
1504 1497
1505 // If the SiteInstance for the pending RFH is being used by others, don't 1498 // If the SiteInstance for the pending RFH is being used by others, don't
1506 // delete the RFH, just swap it out and it can be reused at a later point. 1499 // delete the RFH, just swap it out and it can be reused at a later point.
1507 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>( 1500 SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>(
1508 pending_render_frame_host->GetSiteInstance()); 1501 pending_render_frame_host->GetSiteInstance());
1509 if (site_instance->active_view_count() > 1) { 1502 if (site_instance->active_view_count() > 1) {
1510 // Any currently suspended navigations are no longer needed. 1503 // Any currently suspended navigations are no longer needed.
1511 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); 1504 pending_render_frame_host->CancelSuspendedNavigations();
1512 1505
1513 RenderFrameProxyHost* proxy = 1506 RenderFrameProxyHost* proxy =
1514 new RenderFrameProxyHost(site_instance, frame_tree_node_); 1507 new RenderFrameProxyHost(site_instance, frame_tree_node_);
1515 proxy_hosts_[site_instance->GetId()] = proxy; 1508 proxy_hosts_[site_instance->GetId()] = proxy;
1516 pending_render_frame_host->SwapOut(proxy); 1509 pending_render_frame_host->SwapOut(proxy);
1517 if (frame_tree_node_->IsMainFrame()) 1510 if (frame_tree_node_->IsMainFrame())
1518 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass()); 1511 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass());
1519 } else { 1512 } else {
1520 // We won't be coming back, so delete this one. 1513 // We won't be coming back, so delete this one.
1521 pending_render_frame_host.reset(); 1514 pending_render_frame_host.reset();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 1590 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1598 SiteInstance* instance) { 1591 SiteInstance* instance) {
1599 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1592 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1600 if (iter != proxy_hosts_.end()) { 1593 if (iter != proxy_hosts_.end()) {
1601 delete iter->second; 1594 delete iter->second;
1602 proxy_hosts_.erase(iter); 1595 proxy_hosts_.erase(iter);
1603 } 1596 }
1604 } 1597 }
1605 1598
1606 } // namespace content 1599 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_impl.cc ('k') | content/browser/frame_host/render_frame_host_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698