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