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 this is for the correct frame. | |
Charlie Reis
2014/03/24 22:17:49
This is borrowed from https://codereview.chromium.
| |
365 DCHECK_EQ(render_frame_host_->GetRoutingID(), | |
366 pending_nav_params_->render_frame_id); | |
367 DCHECK_EQ(render_frame_host_->GetProcess()->GetID(), | |
368 pending_nav_params_->global_request_id.child_id); | |
369 | |
423 // Treat the last URL in the chain as the destination and the remainder as | 370 // Treat the last URL in the chain as the destination and the remainder as |
424 // the redirect chain. | 371 // the redirect chain. |
425 CHECK(pending_nav_params_->transfer_url_chain.size()); | 372 CHECK(pending_nav_params_->transfer_url_chain.size()); |
426 GURL transfer_url = pending_nav_params_->transfer_url_chain.back(); | 373 GURL transfer_url = pending_nav_params_->transfer_url_chain.back(); |
427 pending_nav_params_->transfer_url_chain.pop_back(); | 374 pending_nav_params_->transfer_url_chain.pop_back(); |
428 | 375 |
429 // We don't know whether the original request had |user_action| set to true. | 376 // 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 | 377 // However, since we force the navigation to be in the current tab, it |
431 // doesn't matter. | 378 // doesn't matter. |
432 render_frame_host_->frame_tree_node()->navigator()->RequestTransferURL( | 379 render_frame_host->frame_tree_node()->navigator()->RequestTransferURL( |
433 render_frame_host, | 380 render_frame_host, |
434 transfer_url, | 381 transfer_url, |
435 pending_nav_params_->transfer_url_chain, | 382 pending_nav_params_->transfer_url_chain, |
436 pending_nav_params_->referrer, | 383 pending_nav_params_->referrer, |
437 pending_nav_params_->page_transition, | 384 pending_nav_params_->page_transition, |
438 CURRENT_TAB, | 385 CURRENT_TAB, |
439 pending_nav_params_->global_request_id, | 386 pending_nav_params_->global_request_id, |
440 false, | 387 pending_nav_params_->should_replace_current_entry, |
441 true); | 388 true); |
442 } else if (pending_render_frame_host_) { | 389 } else if (pending_render_frame_host_) { |
443 RenderProcessHostImpl* pending_process = | 390 RenderProcessHostImpl* pending_process = |
444 static_cast<RenderProcessHostImpl*>( | 391 static_cast<RenderProcessHostImpl*>( |
445 pending_render_frame_host_->GetProcess()); | 392 pending_render_frame_host_->GetProcess()); |
446 pending_process->ResumeDeferredNavigation( | 393 pending_process->ResumeDeferredNavigation( |
447 pending_nav_params_->global_request_id); | 394 pending_nav_params_->global_request_id); |
448 } | 395 } |
449 pending_nav_params_.reset(); | 396 pending_nav_params_.reset(); |
450 } | 397 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
519 } | 466 } |
520 } | 467 } |
521 | 468 |
522 void RenderFrameHostManager::SwapOutOldPage() { | 469 void RenderFrameHostManager::SwapOutOldPage() { |
523 // Should only see this while we have a pending renderer or transfer. | 470 // Should only see this while we have a pending renderer or transfer. |
524 CHECK(cross_navigation_pending_ || pending_nav_params_.get()); | 471 CHECK(cross_navigation_pending_ || pending_nav_params_.get()); |
525 | 472 |
526 // Tell the renderer to suppress any further modal dialogs so that we can swap | 473 // Tell the renderer to suppress any further modal dialogs so that we can swap |
527 // it out. This must be done before canceling any current dialog, in case | 474 // it out. This must be done before canceling any current dialog, in case |
528 // there is a loop creating additional dialogs. | 475 // there is a loop creating additional dialogs. |
476 // TODO(creis): Handle modal dialogs in subframe processes. | |
529 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); | 477 render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut(); |
530 | 478 |
531 // Now close any modal dialogs that would prevent us from swapping out. This | 479 // Now close any modal dialogs that would prevent us from swapping out. This |
532 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is | 480 // must be done separately from SwapOut, so that the PageGroupLoadDeferrer is |
533 // no longer on the stack when we send the SwapOut message. | 481 // no longer on the stack when we send the SwapOut message. |
534 delegate_->CancelModalDialogsForRenderManager(); | 482 delegate_->CancelModalDialogsForRenderManager(); |
535 | 483 |
536 // Tell the old renderer it is being swapped out. This will fire the unload | 484 if (!frame_tree_node_->IsMainFrame()) { |
537 // handler (without firing the beforeunload handler a second time). When the | |
538 // unload handler finishes and the navigation completes, we will send a | |
539 // message to the ResourceDispatcherHost, allowing the pending RVH's response | |
540 // to resume. | |
541 // Note: This must be done on the RFH or else we'll swap out the top-level | |
542 // page when subframes navigate. | |
543 if (frame_tree_node_->IsMainFrame()) { | |
544 render_frame_host_->render_view_host()->SwapOut(); | |
545 } else { | |
546 // The RenderFrameHost being swapped out becomes the proxy for this | 485 // The RenderFrameHost being swapped out becomes the proxy for this |
547 // frame in its parent's process. CrossProcessFrameConnector | 486 // frame in its parent's process. CrossProcessFrameConnector |
548 // initialization only needs to happen on an initial cross-process | 487 // initialization only needs to happen on an initial cross-process |
549 // navigation, when the RenderFrame leaves the same process as its parent. | 488 // navigation, when the RenderFrame leaves the same process as its parent. |
550 // The same CrossProcessFrameConnector is used for subsequent cross- | 489 // The same CrossProcessFrameConnector is used for subsequent cross- |
551 // process navigations, but it will be destroyed if the Frame is | 490 // process navigations, but it will be destroyed if the Frame is |
552 // navigated back to the same site instance as its parent. | 491 // navigated back to the same site instance as its parent. |
553 // TODO(kenrb): This will change when RenderFrameProxyHost is created. | 492 // TODO(kenrb): This will change when RenderFrameProxyHost is created. |
554 if (!cross_process_frame_connector_) { | 493 if (!cross_process_frame_connector_) { |
555 cross_process_frame_connector_ = | 494 cross_process_frame_connector_ = |
556 new CrossProcessFrameConnector(render_frame_host_.get()); | 495 new CrossProcessFrameConnector(render_frame_host_.get()); |
557 } | 496 } |
558 render_frame_host_->SwapOut(); | |
559 } | 497 } |
560 | 498 |
499 // Tell the old frame it is being swapped out. This will fire the unload | |
500 // handler in the background (without firing the beforeunload handler a second | |
501 // time). When the navigation completes, we will send a message to the | |
502 // ResourceDispatcherHost, allowing the pending RVH's response to resume. | |
503 render_frame_host_->SwapOut(); | |
504 | |
561 // ResourceDispatcherHost has told us to run the onunload handler, which | 505 // ResourceDispatcherHost has told us to run the onunload handler, which |
562 // means it is not a download or unsafe page, and we are going to perform the | 506 // means it is not a download or unsafe page, and we are going to perform the |
563 // navigation. Thus, we no longer need to remember that the RenderFrameHost | 507 // navigation. Thus, we no longer need to remember that the RenderFrameHost |
564 // is part of a pending cross-site request. | 508 // is part of a pending cross-site request. |
565 if (pending_render_frame_host_) { | 509 if (pending_render_frame_host_) { |
566 pending_render_frame_host_->render_view_host()-> | 510 pending_render_frame_host_->render_view_host()-> |
567 SetHasPendingCrossSiteRequest(false); | 511 SetHasPendingCrossSiteRequest(false); |
568 } | 512 } |
569 } | 513 } |
570 | 514 |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1380 pending_render_frame_host->GetProcess()->RemovePendingView(); | 1324 pending_render_frame_host->GetProcess()->RemovePendingView(); |
1381 | 1325 |
1382 // The pending RFH may already be on the swapped out list if we started to | 1326 // 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 | 1327 // 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 | 1328 // again. If it's not on the swapped out list (e.g., aborting a pending |
1385 // load), then it's safe to shut down. | 1329 // load), then it's safe to shut down. |
1386 if (IsOnSwappedOutList(pending_render_frame_host)) { | 1330 if (IsOnSwappedOutList(pending_render_frame_host)) { |
1387 // Any currently suspended navigations are no longer needed. | 1331 // Any currently suspended navigations are no longer needed. |
1388 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); | 1332 pending_render_frame_host->render_view_host()->CancelSuspendedNavigations(); |
1389 | 1333 |
1390 // TODO(creis): We need to swap out the RFH. | 1334 pending_render_frame_host->SwapOut(); |
1391 pending_render_frame_host->render_view_host()->SwapOut(); | |
1392 } else { | 1335 } else { |
1393 // We won't be coming back, so shut this one down. | 1336 // We won't be coming back, so shut this one down. |
1394 delete pending_render_frame_host; | 1337 delete pending_render_frame_host; |
1395 } | 1338 } |
1396 | 1339 |
1397 pending_web_ui_.reset(); | 1340 pending_web_ui_.reset(); |
1398 pending_and_current_web_ui_.reset(); | 1341 pending_and_current_web_ui_.reset(); |
1399 } | 1342 } |
1400 | 1343 |
1401 void RenderFrameHostManager::RenderViewDeleted(RenderViewHost* rvh) { | 1344 void RenderFrameHostManager::RenderViewDeleted(RenderViewHost* rvh) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1463 SiteInstance* instance) const { | 1406 SiteInstance* instance) const { |
1464 RenderFrameHostMap::const_iterator iter = | 1407 RenderFrameHostMap::const_iterator iter = |
1465 swapped_out_hosts_.find(instance->GetId()); | 1408 swapped_out_hosts_.find(instance->GetId()); |
1466 if (iter != swapped_out_hosts_.end()) | 1409 if (iter != swapped_out_hosts_.end()) |
1467 return iter->second; | 1410 return iter->second; |
1468 | 1411 |
1469 return NULL; | 1412 return NULL; |
1470 } | 1413 } |
1471 | 1414 |
1472 } // namespace content | 1415 } // namespace content |
OLD | NEW |