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 |