Chromium Code Reviews| 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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 pending_nav_params_.reset(new PendingNavigationParams( | 337 pending_nav_params_.reset(new PendingNavigationParams( |
| 338 global_request_id, cross_site_transferring_request.Pass(), | 338 global_request_id, cross_site_transferring_request.Pass(), |
| 339 transfer_url_chain, referrer, page_transition, | 339 transfer_url_chain, referrer, page_transition, |
| 340 pending_render_frame_host->GetRoutingID(), | 340 pending_render_frame_host->GetRoutingID(), |
| 341 should_replace_current_entry)); | 341 should_replace_current_entry)); |
| 342 | 342 |
| 343 // Run the unload handler of the current page. | 343 // Run the unload handler of the current page. |
| 344 SwapOutOldPage(); | 344 SwapOutOldPage(); |
| 345 } | 345 } |
| 346 | 346 |
| 347 // TODO(creis): Remove this in favor of SwappedOutFrame. | 347 void RenderFrameHostManager::SwappedOut( |
| 348 void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) { | |
| 349 // Make sure this is from our current RVH, and that we have a pending | |
| 350 // navigation from OnCrossSiteResponse. (There may be no pending navigation | |
| 351 // for data URLs that don't make network requests, for example.) If not, | |
| 352 // just return early and ignore. | |
| 353 if (render_view_host != render_frame_host_->render_view_host() || | |
| 354 !pending_nav_params_.get()) { | |
| 355 pending_nav_params_.reset(); | |
| 356 return; | |
| 357 } | |
| 358 | |
| 359 // Now that the unload handler has run, we need to either initiate the | |
| 360 // pending transfer (if there is one) or resume the paused response (if not). | |
| 361 // TODO(creis): The blank swapped out page is visible during this time, but | |
| 362 // we can shorten this by delivering the response directly, rather than | |
| 363 // forcing an identical request to be made. | |
| 364 if (pending_nav_params_->cross_site_transferring_request) { | |
| 365 // Treat the last URL in the chain as the destination and the remainder as | |
| 366 // the redirect chain. | |
| 367 CHECK(pending_nav_params_->transfer_url_chain.size()); | |
| 368 GURL transfer_url = pending_nav_params_->transfer_url_chain.back(); | |
| 369 pending_nav_params_->transfer_url_chain.pop_back(); | |
| 370 | |
| 371 // We use GetMainFrame here because this version of SwappedOut is only | |
| 372 // called for the main frame. We will remove it in favor of the frame | |
| 373 // specific version. | |
| 374 RenderFrameHostImpl* render_frame_host = | |
| 375 static_cast<RenderFrameHostImpl*>(render_view_host->GetMainFrame()); | |
| 376 | |
| 377 // We don't know whether the original request had |user_action| set to true. | |
| 378 // However, since we force the navigation to be in the current tab, it | |
| 379 // doesn't matter. | |
| 380 render_frame_host->frame_tree_node()->navigator()->RequestTransferURL( | |
| 381 render_frame_host, | |
| 382 transfer_url, | |
| 383 pending_nav_params_->transfer_url_chain, | |
| 384 pending_nav_params_->referrer, | |
| 385 pending_nav_params_->page_transition, | |
| 386 CURRENT_TAB, | |
| 387 pending_nav_params_->global_request_id, | |
| 388 pending_nav_params_->should_replace_current_entry, | |
| 389 true); | |
| 390 } else if (pending_render_frame_host_) { | |
| 391 RenderProcessHostImpl* pending_process = | |
| 392 static_cast<RenderProcessHostImpl*>( | |
| 393 pending_render_frame_host_->GetProcess()); | |
| 394 pending_process->ResumeDeferredNavigation( | |
| 395 pending_nav_params_->global_request_id); | |
| 396 } | |
| 397 pending_nav_params_.reset(); | |
| 398 } | |
| 399 | |
| 400 void RenderFrameHostManager::SwappedOutFrame( | |
| 401 RenderFrameHostImpl* render_frame_host) { | 348 RenderFrameHostImpl* render_frame_host) { |
| 402 // Make sure this is from our current RFH, and that we have a pending | 349 // Make sure this is from our current RFH, and that we have a pending |
| 403 // navigation from OnCrossSiteResponse. (There may be no pending navigation | 350 // navigation from OnCrossSiteResponse. (There may be no pending navigation |
| 404 // for data URLs that don't make network requests, for example.) If not, | 351 // for data URLs that don't make network requests, for example.) If not, |
| 405 // just return early and ignore. | 352 // just return early and ignore. |
| 406 if (render_frame_host != render_frame_host_ || !pending_nav_params_.get()) { | 353 if (render_frame_host != render_frame_host_ || !pending_nav_params_.get()) { |
| 407 pending_nav_params_.reset(); | 354 pending_nav_params_.reset(); |
| 408 return; | 355 return; |
| 409 } | 356 } |
| 410 | 357 |
| 411 // Sanity check that this is for the correct frame. | |
| 412 DCHECK_EQ(render_frame_host_->GetRoutingID(), | |
| 413 pending_nav_params_->render_frame_id); | |
| 414 DCHECK_EQ(render_frame_host_->GetProcess()->GetID(), | |
| 415 pending_nav_params_->global_request_id.child_id); | |
| 416 | |
| 417 // Now that the unload handler has run, we need to either initiate the | 358 // Now that the unload handler has run, we need to either initiate the |
| 418 // pending transfer (if there is one) or resume the paused response (if not). | 359 // pending transfer (if there is one) or resume the paused response (if not). |
| 419 // TODO(creis): The blank swapped out page is visible during this time, but | 360 // TODO(creis): The blank swapped out page is visible during this time, but |
| 420 // we can shorten this by delivering the response directly, rather than | 361 // we can shorten this by delivering the response directly, rather than |
| 421 // forcing an identical request to be made. | 362 // forcing an identical request to be made. |
| 422 if (pending_nav_params_->cross_site_transferring_request) { | 363 if (pending_nav_params_->cross_site_transferring_request) { |
| 364 // Sanity check that the params are for the correct frame and process. | |
|
Charlie Reis
2014/03/28 15:55:18
I needed to update these checks to handle the vari
| |
| 365 // These should match the RenderFrameHost that made the request. | |
| 366 // If it started as a cross-process navigation via OpenURL, this is the | |
| 367 // pending one. If it wasn't cross-process until the transfer, this is the | |
| 368 // current one. | |
| 369 int frame_id = pending_render_frame_host_ ? | |
|
nasko
2014/03/28 16:10:48
nit: render_frame_id?
Charlie Reis
2014/03/28 16:18:04
Done.
| |
| 370 pending_render_frame_host_->GetRoutingID() : | |
| 371 render_frame_host_->GetRoutingID(); | |
| 372 DCHECK_EQ(frame_id, pending_nav_params_->render_frame_id); | |
| 373 int process_id = pending_render_frame_host_ ? | |
| 374 pending_render_frame_host_->GetProcess()->GetID() : | |
| 375 render_frame_host_->GetProcess()->GetID(); | |
| 376 DCHECK_EQ(process_id, pending_nav_params_->global_request_id.child_id); | |
| 377 | |
| 423 // Treat the last URL in the chain as the destination and the remainder as | 378 // Treat the last URL in the chain as the destination and the remainder as |
| 424 // the redirect chain. | 379 // the redirect chain. |
| 425 CHECK(pending_nav_params_->transfer_url_chain.size()); | 380 CHECK(pending_nav_params_->transfer_url_chain.size()); |
| 426 GURL transfer_url = pending_nav_params_->transfer_url_chain.back(); | 381 GURL transfer_url = pending_nav_params_->transfer_url_chain.back(); |
| 427 pending_nav_params_->transfer_url_chain.pop_back(); | 382 pending_nav_params_->transfer_url_chain.pop_back(); |
| 428 | 383 |
| 429 // We don't know whether the original request had |user_action| set to true. | 384 // We don't know whether the original request had |user_action| set to true. |
| 430 // However, since we force the navigation to be in the current tab, it | 385 // However, since we force the navigation to be in the current tab, it |
| 431 // doesn't matter. | 386 // doesn't matter. |
| 432 render_frame_host_->frame_tree_node()->navigator()->RequestTransferURL( | 387 render_frame_host->frame_tree_node()->navigator()->RequestTransferURL( |
| 433 render_frame_host, | 388 render_frame_host, |
| 434 transfer_url, | 389 transfer_url, |
| 435 pending_nav_params_->transfer_url_chain, | 390 pending_nav_params_->transfer_url_chain, |
| 436 pending_nav_params_->referrer, | 391 pending_nav_params_->referrer, |
| 437 pending_nav_params_->page_transition, | 392 pending_nav_params_->page_transition, |
| 438 CURRENT_TAB, | 393 CURRENT_TAB, |
| 439 pending_nav_params_->global_request_id, | 394 pending_nav_params_->global_request_id, |
| 440 false, | 395 pending_nav_params_->should_replace_current_entry, |
| 441 true); | 396 true); |
| 442 } else if (pending_render_frame_host_) { | 397 } else if (pending_render_frame_host_) { |
| 443 RenderProcessHostImpl* pending_process = | 398 RenderProcessHostImpl* pending_process = |
| 444 static_cast<RenderProcessHostImpl*>( | 399 static_cast<RenderProcessHostImpl*>( |
| 445 pending_render_frame_host_->GetProcess()); | 400 pending_render_frame_host_->GetProcess()); |
| 446 pending_process->ResumeDeferredNavigation( | 401 pending_process->ResumeDeferredNavigation( |
| 447 pending_nav_params_->global_request_id); | 402 pending_nav_params_->global_request_id); |
| 448 } | 403 } |
| 449 pending_nav_params_.reset(); | 404 pending_nav_params_.reset(); |
| 450 } | 405 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 } | 477 } |
| 523 } | 478 } |
| 524 | 479 |
| 525 void RenderFrameHostManager::SwapOutOldPage() { | 480 void RenderFrameHostManager::SwapOutOldPage() { |
| 526 // Should only see this while we have a pending renderer or transfer. | 481 // Should only see this while we have a pending renderer or transfer. |
| 527 CHECK(cross_navigation_pending_ || pending_nav_params_.get()); | 482 CHECK(cross_navigation_pending_ || pending_nav_params_.get()); |
| 528 | 483 |
| 529 // Tell the renderer to suppress any further modal dialogs so that we can swap | 484 // Tell the renderer to suppress any further modal dialogs so that we can swap |
| 530 // it out. This must be done before canceling any current dialog, in case | 485 // it out. This must be done before canceling any current dialog, in case |
| 531 // there is a loop creating additional dialogs. | 486 // there is a loop creating additional dialogs. |
| 487 // TODO(creis): Handle modal dialogs in subframe processes. | |
| 532 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); | 488 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); |
| 533 | 489 |
| 534 // Now close any modal dialogs that would prevent us from swapping out. This | 490 // Now close any modal dialogs that would prevent us from swapping out. This |
| 535 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is | 491 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is |
| 536 // no longer on the stack when we send the SwapOut message. | 492 // no longer on the stack when we send the SwapOut message. |
| 537 delegate_->CancelModalDialogsForRenderManager(); | 493 delegate_->CancelModalDialogsForRenderManager(); |
| 538 | 494 |
| 539 // Tell the old renderer it is being swapped out. This will fire the unload | 495 if (!frame_tree_node_->IsMainFrame()) { |
| 540 // handler (without firing the beforeunload handler a second time). When the | |
| 541 // unload handler finishes and the navigation completes, we will send a | |
| 542 // message to the ResourceDispatcherHost, allowing the pending RVH's response | |
| 543 // to resume. | |
| 544 // Note: This must be done on the RFH or else we'll swap out the top-level | |
| 545 // page when subframes navigate. | |
| 546 if (frame_tree_node_->IsMainFrame()) { | |
| 547 render_frame_host_->render_view_host()->SwapOut(); | |
| 548 } else { | |
| 549 // The RenderFrameHost being swapped out becomes the proxy for this | 496 // The RenderFrameHost being swapped out becomes the proxy for this |
| 550 // frame in its parent's process. CrossProcessFrameConnector | 497 // frame in its parent's process. CrossProcessFrameConnector |
| 551 // initialization only needs to happen on an initial cross-process | 498 // initialization only needs to happen on an initial cross-process |
| 552 // navigation, when the RenderFrame leaves the same process as its parent. | 499 // navigation, when the RenderFrame leaves the same process as its parent. |
| 553 // The same CrossProcessFrameConnector is used for subsequent cross- | 500 // The same CrossProcessFrameConnector is used for subsequent cross- |
| 554 // process navigations, but it will be destroyed if the Frame is | 501 // process navigations, but it will be destroyed if the Frame is |
| 555 // navigated back to the same site instance as its parent. | 502 // navigated back to the same site instance as its parent. |
| 556 // TODO(kenrb): This will change when RenderFrameProxyHost is created. | 503 // TODO(kenrb): This will change when RenderFrameProxyHost is created. |
| 557 if (!cross_process_frame_connector_) { | 504 if (!cross_process_frame_connector_) { |
| 558 cross_process_frame_connector_ = | 505 cross_process_frame_connector_ = |
| 559 new CrossProcessFrameConnector(render_frame_host_.get()); | 506 new CrossProcessFrameConnector(render_frame_host_.get()); |
| 560 } | 507 } |
| 561 render_frame_host_->SwapOut(); | |
| 562 } | 508 } |
| 563 | 509 |
| 510 // Tell the old frame it is being swapped out. This will fire the unload | |
| 511 // handler in the background (without firing the beforeunload handler a second | |
| 512 // time). When the navigation completes, we will send a message to the | |
| 513 // ResourceDispatcherHost, allowing the pending RVH's response to resume. | |
| 514 render_frame_host_->SwapOut(); | |
| 515 | |
| 564 // ResourceDispatcherHost has told us to run the onunload handler, which | 516 // ResourceDispatcherHost has told us to run the onunload handler, which |
| 565 // means it is not a download or unsafe page, and we are going to perform the | 517 // means it is not a download or unsafe page, and we are going to perform the |
| 566 // navigation. Thus, we no longer need to remember that the RenderFrameHost | 518 // navigation. Thus, we no longer need to remember that the RenderFrameHost |
| 567 // is part of a pending cross-site request. | 519 // is part of a pending cross-site request. |
| 568 if (pending_render_frame_host_) { | 520 if (pending_render_frame_host_) { |
| 569 pending_render_frame_host_->render_view_host()-> | 521 pending_render_frame_host_->render_view_host()-> |
| 570 SetHasPendingCrossSiteRequest(false); | 522 SetHasPendingCrossSiteRequest(false); |
| 571 } | 523 } |
| 572 } | 524 } |
| 573 | 525 |
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1380 pending_render_frame_host->GetProcess()->RemovePendingView(); | 1332 pending_render_frame_host->GetProcess()->RemovePendingView(); |
| 1381 | 1333 |
| 1382 // The pending RFH may already be on the swapped out list if we started to | 1334 // The pending RFH may already be on the swapped out list if we started to |
| 1383 // swap it back in and then canceled. If so, make sure it gets swapped out | 1335 // swap it back in and then canceled. If so, make sure it gets swapped out |
| 1384 // again. If it's not on the swapped out list (e.g., aborting a pending | 1336 // again. If it's not on the swapped out list (e.g., aborting a pending |
| 1385 // load), then it's safe to shut down. | 1337 // load), then it's safe to shut down. |
| 1386 if (IsOnSwappedOutList(pending_render_frame_host)) { | 1338 if (IsOnSwappedOutList(pending_render_frame_host)) { |
| 1387 // Any currently suspended navigations are no longer needed. | 1339 // Any currently suspended navigations are no longer needed. |
| 1388 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); | 1340 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); |
| 1389 | 1341 |
| 1390 // TODO(creis): We need to swap out the RFH. | 1342 pending_render_frame_host->SwapOut(); |
| 1391 pending_render_frame_host->render_view_host()->SwapOut(); | |
| 1392 } else { | 1343 } else { |
| 1393 // We won't be coming back, so shut this one down. | 1344 // We won't be coming back, so shut this one down. |
| 1394 delete pending_render_frame_host; | 1345 delete pending_render_frame_host; |
| 1395 } | 1346 } |
| 1396 | 1347 |
| 1397 pending_web_ui_.reset(); | 1348 pending_web_ui_.reset(); |
| 1398 pending_and_current_web_ui_.reset(); | 1349 pending_and_current_web_ui_.reset(); |
| 1399 } | 1350 } |
| 1400 | 1351 |
| 1401 void RenderFrameHostManager::RenderViewDeleted(RenderViewHost* rvh) { | 1352 void RenderFrameHostManager::RenderViewDeleted(RenderViewHost* rvh) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1463 SiteInstance* instance) const { | 1414 SiteInstance* instance) const { |
| 1464 RenderFrameHostMap::const_iterator iter = | 1415 RenderFrameHostMap::const_iterator iter = |
| 1465 swapped_out_hosts_.find(instance->GetId()); | 1416 swapped_out_hosts_.find(instance->GetId()); |
| 1466 if (iter != swapped_out_hosts_.end()) | 1417 if (iter != swapped_out_hosts_.end()) |
| 1467 return iter->second; | 1418 return iter->second; |
| 1468 | 1419 |
| 1469 return NULL; | 1420 return NULL; |
| 1470 } | 1421 } |
| 1471 | 1422 |
| 1472 } // namespace content | 1423 } // namespace content |
| OLD | NEW |