| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |