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/navigation_controller_impl.h" | 5 #include "content/browser/frame_host/navigation_controller_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 } | 284 } |
285 void NavigationControllerImpl::ReloadOriginalRequestURL(bool check_for_repost) { | 285 void NavigationControllerImpl::ReloadOriginalRequestURL(bool check_for_repost) { |
286 ReloadInternal(check_for_repost, RELOAD_ORIGINAL_REQUEST_URL); | 286 ReloadInternal(check_for_repost, RELOAD_ORIGINAL_REQUEST_URL); |
287 } | 287 } |
288 | 288 |
289 void NavigationControllerImpl::ReloadInternal(bool check_for_repost, | 289 void NavigationControllerImpl::ReloadInternal(bool check_for_repost, |
290 ReloadType reload_type) { | 290 ReloadType reload_type) { |
291 if (transient_entry_index_ != -1) { | 291 if (transient_entry_index_ != -1) { |
292 // If an interstitial is showing, treat a reload as a navigation to the | 292 // If an interstitial is showing, treat a reload as a navigation to the |
293 // transient entry's URL. | 293 // transient entry's URL. |
294 NavigationEntryImpl* transient_entry = | 294 NavigationEntryImpl* transient_entry = GetTransientEntry(); |
295 NavigationEntryImpl::FromNavigationEntry(GetTransientEntry()); | |
296 if (!transient_entry) | 295 if (!transient_entry) |
297 return; | 296 return; |
298 LoadURL(transient_entry->GetURL(), | 297 LoadURL(transient_entry->GetURL(), |
299 Referrer(), | 298 Referrer(), |
300 ui::PAGE_TRANSITION_RELOAD, | 299 ui::PAGE_TRANSITION_RELOAD, |
301 transient_entry->extra_headers()); | 300 transient_entry->extra_headers()); |
302 return; | 301 return; |
303 } | 302 } |
304 | 303 |
305 NavigationEntryImpl* entry = NULL; | 304 NavigationEntryImpl* entry = NULL; |
306 int current_index = -1; | 305 int current_index = -1; |
307 | 306 |
308 // If we are reloading the initial navigation, just use the current | 307 // If we are reloading the initial navigation, just use the current |
309 // pending entry. Otherwise look up the current entry. | 308 // pending entry. Otherwise look up the current entry. |
310 if (IsInitialNavigation() && pending_entry_) { | 309 if (IsInitialNavigation() && pending_entry_) { |
311 entry = pending_entry_; | 310 entry = pending_entry_; |
312 // The pending entry might be in entries_ (e.g., after a Clone), so we | 311 // The pending entry might be in entries_ (e.g., after a Clone), so we |
313 // should also update the current_index. | 312 // should also update the current_index. |
314 current_index = pending_entry_index_; | 313 current_index = pending_entry_index_; |
315 } else { | 314 } else { |
316 DiscardNonCommittedEntriesInternal(); | 315 DiscardNonCommittedEntriesInternal(); |
317 current_index = GetCurrentEntryIndex(); | 316 current_index = GetCurrentEntryIndex(); |
318 if (current_index != -1) { | 317 if (current_index != -1) { |
319 entry = NavigationEntryImpl::FromNavigationEntry( | 318 entry = GetEntryAtIndex(current_index); |
320 GetEntryAtIndex(current_index)); | |
321 } | 319 } |
322 } | 320 } |
323 | 321 |
324 // If we are no where, then we can't reload. TODO(darin): We should add a | 322 // If we are no where, then we can't reload. TODO(darin): We should add a |
325 // CanReload method. | 323 // CanReload method. |
326 if (!entry) | 324 if (!entry) |
327 return; | 325 return; |
328 | 326 |
329 if (reload_type == NavigationControllerImpl::RELOAD_ORIGINAL_REQUEST_URL && | 327 if (reload_type == NavigationControllerImpl::RELOAD_ORIGINAL_REQUEST_URL && |
330 entry->GetOriginalRequestURL().is_valid() && !entry->GetHasPostData()) { | 328 entry->GetOriginalRequestURL().is_valid() && !entry->GetHasPostData()) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 | 424 |
427 void NavigationControllerImpl::SetPendingEntry(NavigationEntryImpl* entry) { | 425 void NavigationControllerImpl::SetPendingEntry(NavigationEntryImpl* entry) { |
428 DiscardNonCommittedEntriesInternal(); | 426 DiscardNonCommittedEntriesInternal(); |
429 pending_entry_ = entry; | 427 pending_entry_ = entry; |
430 NotificationService::current()->Notify( | 428 NotificationService::current()->Notify( |
431 NOTIFICATION_NAV_ENTRY_PENDING, | 429 NOTIFICATION_NAV_ENTRY_PENDING, |
432 Source<NavigationController>(this), | 430 Source<NavigationController>(this), |
433 Details<NavigationEntry>(entry)); | 431 Details<NavigationEntry>(entry)); |
434 } | 432 } |
435 | 433 |
436 NavigationEntry* NavigationControllerImpl::GetActiveEntry() const { | 434 NavigationEntryImpl* NavigationControllerImpl::GetActiveEntry() const { |
437 if (transient_entry_index_ != -1) | 435 if (transient_entry_index_ != -1) |
438 return entries_[transient_entry_index_].get(); | 436 return entries_[transient_entry_index_].get(); |
439 if (pending_entry_) | 437 if (pending_entry_) |
440 return pending_entry_; | 438 return pending_entry_; |
441 return GetLastCommittedEntry(); | 439 return GetLastCommittedEntry(); |
442 } | 440 } |
443 | 441 |
444 NavigationEntry* NavigationControllerImpl::GetVisibleEntry() const { | 442 NavigationEntryImpl* NavigationControllerImpl::GetVisibleEntry() const { |
445 if (transient_entry_index_ != -1) | 443 if (transient_entry_index_ != -1) |
446 return entries_[transient_entry_index_].get(); | 444 return entries_[transient_entry_index_].get(); |
447 // The pending entry is safe to return for new (non-history), browser- | 445 // The pending entry is safe to return for new (non-history), browser- |
448 // initiated navigations. Most renderer-initiated navigations should not | 446 // initiated navigations. Most renderer-initiated navigations should not |
449 // show the pending entry, to prevent URL spoof attacks. | 447 // show the pending entry, to prevent URL spoof attacks. |
450 // | 448 // |
451 // We make an exception for renderer-initiated navigations in new tabs, as | 449 // We make an exception for renderer-initiated navigations in new tabs, as |
452 // long as no other page has tried to access the initial empty document in | 450 // long as no other page has tried to access the initial empty document in |
453 // the new tab. If another page modifies this blank page, a URL spoof is | 451 // the new tab. If another page modifies this blank page, a URL spoof is |
454 // possible, so we must stop showing the pending entry. | 452 // possible, so we must stop showing the pending entry. |
(...skipping 20 matching lines...) Expand all Loading... |
475 } | 473 } |
476 | 474 |
477 int NavigationControllerImpl::GetCurrentEntryIndex() const { | 475 int NavigationControllerImpl::GetCurrentEntryIndex() const { |
478 if (transient_entry_index_ != -1) | 476 if (transient_entry_index_ != -1) |
479 return transient_entry_index_; | 477 return transient_entry_index_; |
480 if (pending_entry_index_ != -1) | 478 if (pending_entry_index_ != -1) |
481 return pending_entry_index_; | 479 return pending_entry_index_; |
482 return last_committed_entry_index_; | 480 return last_committed_entry_index_; |
483 } | 481 } |
484 | 482 |
485 NavigationEntry* NavigationControllerImpl::GetLastCommittedEntry() const { | 483 NavigationEntryImpl* NavigationControllerImpl::GetLastCommittedEntry() const { |
486 if (last_committed_entry_index_ == -1) | 484 if (last_committed_entry_index_ == -1) |
487 return NULL; | 485 return NULL; |
488 return entries_[last_committed_entry_index_].get(); | 486 return entries_[last_committed_entry_index_].get(); |
489 } | 487 } |
490 | 488 |
491 bool NavigationControllerImpl::CanViewSource() const { | 489 bool NavigationControllerImpl::CanViewSource() const { |
492 const std::string& mime_type = delegate_->GetContentsMimeType(); | 490 const std::string& mime_type = delegate_->GetContentsMimeType(); |
493 bool is_viewable_mime_type = net::IsSupportedNonImageMimeType(mime_type) && | 491 bool is_viewable_mime_type = net::IsSupportedNonImageMimeType(mime_type) && |
494 !net::IsSupportedMediaMimeType(mime_type); | 492 !net::IsSupportedMediaMimeType(mime_type); |
495 NavigationEntry* visible_entry = GetVisibleEntry(); | 493 NavigationEntry* visible_entry = GetVisibleEntry(); |
496 return visible_entry && !visible_entry->IsViewSourceMode() && | 494 return visible_entry && !visible_entry->IsViewSourceMode() && |
497 is_viewable_mime_type && !delegate_->GetInterstitialPage(); | 495 is_viewable_mime_type && !delegate_->GetInterstitialPage(); |
498 } | 496 } |
499 | 497 |
500 int NavigationControllerImpl::GetLastCommittedEntryIndex() const { | 498 int NavigationControllerImpl::GetLastCommittedEntryIndex() const { |
501 return last_committed_entry_index_; | 499 return last_committed_entry_index_; |
502 } | 500 } |
503 | 501 |
504 int NavigationControllerImpl::GetEntryCount() const { | 502 int NavigationControllerImpl::GetEntryCount() const { |
505 DCHECK(entries_.size() <= max_entry_count()); | 503 DCHECK(entries_.size() <= max_entry_count()); |
506 return static_cast<int>(entries_.size()); | 504 return static_cast<int>(entries_.size()); |
507 } | 505 } |
508 | 506 |
509 NavigationEntry* NavigationControllerImpl::GetEntryAtIndex( | 507 NavigationEntryImpl* NavigationControllerImpl::GetEntryAtIndex( |
510 int index) const { | 508 int index) const { |
511 return entries_.at(index).get(); | 509 return entries_.at(index).get(); |
512 } | 510 } |
513 | 511 |
514 NavigationEntry* NavigationControllerImpl::GetEntryAtOffset( | 512 NavigationEntryImpl* NavigationControllerImpl::GetEntryAtOffset( |
515 int offset) const { | 513 int offset) const { |
516 int index = GetIndexForOffset(offset); | 514 int index = GetIndexForOffset(offset); |
517 if (index < 0 || index >= GetEntryCount()) | 515 if (index < 0 || index >= GetEntryCount()) |
518 return NULL; | 516 return NULL; |
519 | 517 |
520 return entries_[index].get(); | 518 return entries_[index].get(); |
521 } | 519 } |
522 | 520 |
523 int NavigationControllerImpl::GetIndexForOffset(int offset) const { | 521 int NavigationControllerImpl::GetIndexForOffset(int offset) const { |
524 return GetCurrentEntryIndex() + offset; | 522 return GetCurrentEntryIndex() + offset; |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 break; | 765 break; |
768 default: | 766 default: |
769 NOTREACHED(); | 767 NOTREACHED(); |
770 break; | 768 break; |
771 }; | 769 }; |
772 | 770 |
773 LoadEntry(entry); | 771 LoadEntry(entry); |
774 } | 772 } |
775 | 773 |
776 bool NavigationControllerImpl::RendererDidNavigate( | 774 bool NavigationControllerImpl::RendererDidNavigate( |
777 RenderFrameHost* rfh, | 775 RenderFrameHostImpl* rfh, |
778 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 776 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
779 LoadCommittedDetails* details) { | 777 LoadCommittedDetails* details) { |
780 is_initial_navigation_ = false; | 778 is_initial_navigation_ = false; |
781 | 779 |
782 // Save the previous state before we clobber it. | 780 // Save the previous state before we clobber it. |
783 if (GetLastCommittedEntry()) { | 781 if (GetLastCommittedEntry()) { |
784 details->previous_url = GetLastCommittedEntry()->GetURL(); | 782 details->previous_url = GetLastCommittedEntry()->GetURL(); |
785 details->previous_entry_index = GetLastCommittedEntryIndex(); | 783 details->previous_entry_index = GetLastCommittedEntryIndex(); |
786 } else { | 784 } else { |
787 details->previous_url = GURL(); | 785 details->previous_url = GURL(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 DVLOG(1) << "Navigation finished at (smoothed) timestamp " | 850 DVLOG(1) << "Navigation finished at (smoothed) timestamp " |
853 << timestamp.ToInternalValue(); | 851 << timestamp.ToInternalValue(); |
854 | 852 |
855 // We should not have a pending entry anymore. Clear it again in case any | 853 // We should not have a pending entry anymore. Clear it again in case any |
856 // error cases above forgot to do so. | 854 // error cases above forgot to do so. |
857 DiscardNonCommittedEntriesInternal(); | 855 DiscardNonCommittedEntriesInternal(); |
858 | 856 |
859 // All committed entries should have nonempty content state so WebKit doesn't | 857 // All committed entries should have nonempty content state so WebKit doesn't |
860 // get confused when we go back to them (see the function for details). | 858 // get confused when we go back to them (see the function for details). |
861 DCHECK(params.page_state.IsValid()); | 859 DCHECK(params.page_state.IsValid()); |
862 NavigationEntryImpl* active_entry = | 860 NavigationEntryImpl* active_entry = GetLastCommittedEntry(); |
863 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); | |
864 active_entry->SetTimestamp(timestamp); | 861 active_entry->SetTimestamp(timestamp); |
865 active_entry->SetHttpStatusCode(params.http_status_code); | 862 active_entry->SetHttpStatusCode(params.http_status_code); |
866 active_entry->SetPageState(params.page_state); | 863 active_entry->SetPageState(params.page_state); |
867 active_entry->SetRedirectChain(params.redirects); | 864 active_entry->SetRedirectChain(params.redirects); |
868 | 865 |
869 // Use histogram to track memory impact of redirect chain because it's now | 866 // Use histogram to track memory impact of redirect chain because it's now |
870 // not cleared for committed entries. | 867 // not cleared for committed entries. |
871 size_t redirect_chain_size = 0; | 868 size_t redirect_chain_size = 0; |
872 for (size_t i = 0; i < params.redirects.size(); ++i) { | 869 for (size_t i = 0; i < params.redirects.size(); ++i) { |
873 redirect_chain_size += params.redirects[i].spec().length(); | 870 redirect_chain_size += params.redirects[i].spec().length(); |
874 } | 871 } |
875 UMA_HISTOGRAM_COUNTS("Navigation.RedirectChainSize", redirect_chain_size); | 872 UMA_HISTOGRAM_COUNTS("Navigation.RedirectChainSize", redirect_chain_size); |
876 | 873 |
877 // Once it is committed, we no longer need to track several pieces of state on | 874 // Once it is committed, we no longer need to track several pieces of state on |
878 // the entry. | 875 // the entry. |
879 active_entry->ResetForCommit(); | 876 active_entry->ResetForCommit(); |
880 | 877 |
881 // The active entry's SiteInstance should match our SiteInstance. | 878 // The active entry's SiteInstance should match our SiteInstance. |
882 // TODO(creis): This check won't pass for subframes until we create entries | 879 // TODO(creis): This check won't pass for subframes until we create entries |
883 // for subframe navigations. | 880 // for subframe navigations. |
884 if (ui::PageTransitionIsMainFrame(params.transition)) | 881 if (ui::PageTransitionIsMainFrame(params.transition)) |
885 CHECK(active_entry->site_instance() == rfh->GetSiteInstance()); | 882 CHECK(active_entry->site_instance() == rfh->GetSiteInstance()); |
886 | 883 |
887 // Remember the bindings the renderer process has at this point, so that | 884 // Remember the bindings the renderer process has at this point, so that |
888 // we do not grant this entry additional bindings if we come back to it. | 885 // we do not grant this entry additional bindings if we come back to it. |
889 active_entry->SetBindings( | 886 active_entry->SetBindings(rfh->GetEnabledBindings()); |
890 static_cast<RenderFrameHostImpl*>(rfh)->GetEnabledBindings()); | |
891 | 887 |
892 // Now prep the rest of the details for the notification and broadcast. | 888 // Now prep the rest of the details for the notification and broadcast. |
893 details->entry = active_entry; | 889 details->entry = active_entry; |
894 details->is_main_frame = | 890 details->is_main_frame = |
895 ui::PageTransitionIsMainFrame(params.transition); | 891 ui::PageTransitionIsMainFrame(params.transition); |
896 details->serialized_security_info = params.security_info; | 892 details->serialized_security_info = params.security_info; |
897 details->http_status_code = params.http_status_code; | 893 details->http_status_code = params.http_status_code; |
898 NotifyNavigationEntryCommitted(details); | 894 NotifyNavigationEntryCommitted(details); |
899 | 895 |
900 return true; | 896 return true; |
901 } | 897 } |
902 | 898 |
903 NavigationType NavigationControllerImpl::ClassifyNavigation( | 899 NavigationType NavigationControllerImpl::ClassifyNavigation( |
904 RenderFrameHost* rfh, | 900 RenderFrameHostImpl* rfh, |
905 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { | 901 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { |
906 if (params.page_id == -1) { | 902 if (params.page_id == -1) { |
907 // TODO(nasko, creis): An out-of-process child frame has no way of | 903 // TODO(nasko, creis): An out-of-process child frame has no way of |
908 // knowing the page_id of its parent, so it is passing back -1. The | 904 // knowing the page_id of its parent, so it is passing back -1. The |
909 // semantics here should be re-evaluated during session history refactor | 905 // semantics here should be re-evaluated during session history refactor |
910 // (see http://crbug.com/236848). For now, we assume this means the | 906 // (see http://crbug.com/236848). For now, we assume this means the |
911 // child frame loaded and proceed. Note that this may do the wrong thing | 907 // child frame loaded and proceed. Note that this may do the wrong thing |
912 // for cross-process AUTO_SUBFRAME navigations. | 908 // for cross-process AUTO_SUBFRAME navigations. |
913 if (rfh->IsCrossProcessSubframe()) | 909 if (rfh->IsCrossProcessSubframe()) |
914 return NAVIGATION_TYPE_NEW_SUBFRAME; | 910 return NAVIGATION_TYPE_NEW_SUBFRAME; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 temp.append("_"); | 987 temp.append("_"); |
992 if (entries_[i]->site_instance()) | 988 if (entries_[i]->site_instance()) |
993 temp.append(base::IntToString(entries_[i]->site_instance()->GetId())); | 989 temp.append(base::IntToString(entries_[i]->site_instance()->GetId())); |
994 else | 990 else |
995 temp.append("N"); | 991 temp.append("N"); |
996 if (entries_[i]->site_instance() != rfh->GetSiteInstance()) | 992 if (entries_[i]->site_instance() != rfh->GetSiteInstance()) |
997 temp.append("x"); | 993 temp.append("x"); |
998 temp.append(","); | 994 temp.append(","); |
999 } | 995 } |
1000 GURL url(temp); | 996 GURL url(temp); |
1001 static_cast<RenderFrameHostImpl*>(rfh)->render_view_host()->Send( | 997 rfh->render_view_host()->Send(new ViewMsg_TempCrashWithData(url)); |
1002 new ViewMsg_TempCrashWithData(url)); | |
1003 return NAVIGATION_TYPE_NAV_IGNORE; | 998 return NAVIGATION_TYPE_NAV_IGNORE; |
1004 } | 999 } |
1005 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get(); | 1000 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get(); |
1006 | 1001 |
1007 if (!ui::PageTransitionIsMainFrame(params.transition)) { | 1002 if (!ui::PageTransitionIsMainFrame(params.transition)) { |
1008 // All manual subframes would get new IDs and were handled above, so we | 1003 // All manual subframes would get new IDs and were handled above, so we |
1009 // know this is auto. Since the current page was found in the navigation | 1004 // know this is auto. Since the current page was found in the navigation |
1010 // entry list, we're guaranteed to have a last committed entry. | 1005 // entry list, we're guaranteed to have a last committed entry. |
1011 DCHECK(GetLastCommittedEntry()); | 1006 DCHECK(GetLastCommittedEntry()); |
1012 return NAVIGATION_TYPE_AUTO_SUBFRAME; | 1007 return NAVIGATION_TYPE_AUTO_SUBFRAME; |
(...skipping 24 matching lines...) Expand all Loading... |
1037 params.was_within_same_page, rfh)) { | 1032 params.was_within_same_page, rfh)) { |
1038 return NAVIGATION_TYPE_IN_PAGE; | 1033 return NAVIGATION_TYPE_IN_PAGE; |
1039 } | 1034 } |
1040 | 1035 |
1041 // Since we weeded out "new" navigations above, we know this is an existing | 1036 // Since we weeded out "new" navigations above, we know this is an existing |
1042 // (back/forward) navigation. | 1037 // (back/forward) navigation. |
1043 return NAVIGATION_TYPE_EXISTING_PAGE; | 1038 return NAVIGATION_TYPE_EXISTING_PAGE; |
1044 } | 1039 } |
1045 | 1040 |
1046 void NavigationControllerImpl::RendererDidNavigateToNewPage( | 1041 void NavigationControllerImpl::RendererDidNavigateToNewPage( |
1047 RenderFrameHost* rfh, | 1042 RenderFrameHostImpl* rfh, |
1048 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 1043 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
1049 bool replace_entry) { | 1044 bool replace_entry) { |
1050 NavigationEntryImpl* new_entry; | 1045 NavigationEntryImpl* new_entry; |
1051 bool update_virtual_url; | 1046 bool update_virtual_url; |
1052 // Only make a copy of the pending entry if it is appropriate for the new page | 1047 // Only make a copy of the pending entry if it is appropriate for the new page |
1053 // that was just loaded. We verify this at a coarse grain by checking that | 1048 // that was just loaded. We verify this at a coarse grain by checking that |
1054 // the SiteInstance hasn't been assigned to something else. | 1049 // the SiteInstance hasn't been assigned to something else. |
1055 if (pending_entry_ && | 1050 if (pending_entry_ && |
1056 (!pending_entry_->site_instance() || | 1051 (!pending_entry_->site_instance() || |
1057 pending_entry_->site_instance() == rfh->GetSiteInstance())) { | 1052 pending_entry_->site_instance() == rfh->GetSiteInstance())) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 if (params.history_list_was_cleared) { | 1105 if (params.history_list_was_cleared) { |
1111 DiscardNonCommittedEntriesInternal(); | 1106 DiscardNonCommittedEntriesInternal(); |
1112 entries_.clear(); | 1107 entries_.clear(); |
1113 last_committed_entry_index_ = -1; | 1108 last_committed_entry_index_ = -1; |
1114 } | 1109 } |
1115 | 1110 |
1116 InsertOrReplaceEntry(new_entry, replace_entry); | 1111 InsertOrReplaceEntry(new_entry, replace_entry); |
1117 } | 1112 } |
1118 | 1113 |
1119 void NavigationControllerImpl::RendererDidNavigateToExistingPage( | 1114 void NavigationControllerImpl::RendererDidNavigateToExistingPage( |
1120 RenderFrameHost* rfh, | 1115 RenderFrameHostImpl* rfh, |
1121 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1116 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
1122 // We should only get here for main frame navigations. | 1117 // We should only get here for main frame navigations. |
1123 DCHECK(ui::PageTransitionIsMainFrame(params.transition)); | 1118 DCHECK(ui::PageTransitionIsMainFrame(params.transition)); |
1124 | 1119 |
1125 // This is a back/forward navigation. The existing page for the ID is | 1120 // This is a back/forward navigation. The existing page for the ID is |
1126 // guaranteed to exist by ClassifyNavigation, and we just need to update it | 1121 // guaranteed to exist by ClassifyNavigation, and we just need to update it |
1127 // with new information from the renderer. | 1122 // with new information from the renderer. |
1128 int entry_index = GetEntryIndexWithPageID(rfh->GetSiteInstance(), | 1123 int entry_index = GetEntryIndexWithPageID(rfh->GetSiteInstance(), |
1129 params.page_id); | 1124 params.page_id); |
1130 DCHECK(entry_index >= 0 && | 1125 DCHECK(entry_index >= 0 && |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 // actually change any other state, just kill the pointer. | 1160 // actually change any other state, just kill the pointer. |
1166 DiscardNonCommittedEntriesInternal(); | 1161 DiscardNonCommittedEntriesInternal(); |
1167 | 1162 |
1168 // If a transient entry was removed, the indices might have changed, so we | 1163 // If a transient entry was removed, the indices might have changed, so we |
1169 // have to query the entry index again. | 1164 // have to query the entry index again. |
1170 last_committed_entry_index_ = | 1165 last_committed_entry_index_ = |
1171 GetEntryIndexWithPageID(rfh->GetSiteInstance(), params.page_id); | 1166 GetEntryIndexWithPageID(rfh->GetSiteInstance(), params.page_id); |
1172 } | 1167 } |
1173 | 1168 |
1174 void NavigationControllerImpl::RendererDidNavigateToSamePage( | 1169 void NavigationControllerImpl::RendererDidNavigateToSamePage( |
1175 RenderFrameHost* rfh, | 1170 RenderFrameHostImpl* rfh, |
1176 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1171 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
1177 // This mode implies we have a pending entry that's the same as an existing | 1172 // This mode implies we have a pending entry that's the same as an existing |
1178 // entry for this page ID. This entry is guaranteed to exist by | 1173 // entry for this page ID. This entry is guaranteed to exist by |
1179 // ClassifyNavigation. All we need to do is update the existing entry. | 1174 // ClassifyNavigation. All we need to do is update the existing entry. |
1180 NavigationEntryImpl* existing_entry = GetEntryWithPageID( | 1175 NavigationEntryImpl* existing_entry = GetEntryWithPageID( |
1181 rfh->GetSiteInstance(), params.page_id); | 1176 rfh->GetSiteInstance(), params.page_id); |
1182 | 1177 |
1183 // We assign the entry's unique ID to be that of the new one. Since this is | 1178 // We assign the entry's unique ID to be that of the new one. Since this is |
1184 // always the result of a user action, we want to dismiss infobars, etc. like | 1179 // always the result of a user action, we want to dismiss infobars, etc. like |
1185 // a regular user-initiated navigation. | 1180 // a regular user-initiated navigation. |
1186 existing_entry->set_unique_id(pending_entry_->GetUniqueID()); | 1181 existing_entry->set_unique_id(pending_entry_->GetUniqueID()); |
1187 | 1182 |
1188 // The URL may have changed due to redirects. | 1183 // The URL may have changed due to redirects. |
1189 existing_entry->set_page_type(params.url_is_unreachable ? PAGE_TYPE_ERROR | 1184 existing_entry->set_page_type(params.url_is_unreachable ? PAGE_TYPE_ERROR |
1190 : PAGE_TYPE_NORMAL); | 1185 : PAGE_TYPE_NORMAL); |
1191 if (existing_entry->update_virtual_url_with_url()) | 1186 if (existing_entry->update_virtual_url_with_url()) |
1192 UpdateVirtualURLToURL(existing_entry, params.url); | 1187 UpdateVirtualURLToURL(existing_entry, params.url); |
1193 existing_entry->SetURL(params.url); | 1188 existing_entry->SetURL(params.url); |
1194 existing_entry->SetReferrer(params.referrer); | 1189 existing_entry->SetReferrer(params.referrer); |
1195 | 1190 |
1196 // The page may have been requested with a different HTTP method. | 1191 // The page may have been requested with a different HTTP method. |
1197 existing_entry->SetHasPostData(params.is_post); | 1192 existing_entry->SetHasPostData(params.is_post); |
1198 existing_entry->SetPostID(params.post_id); | 1193 existing_entry->SetPostID(params.post_id); |
1199 | 1194 |
1200 DiscardNonCommittedEntries(); | 1195 DiscardNonCommittedEntries(); |
1201 } | 1196 } |
1202 | 1197 |
1203 void NavigationControllerImpl::RendererDidNavigateInPage( | 1198 void NavigationControllerImpl::RendererDidNavigateInPage( |
1204 RenderFrameHost* rfh, | 1199 RenderFrameHostImpl* rfh, |
1205 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 1200 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
1206 bool* did_replace_entry) { | 1201 bool* did_replace_entry) { |
1207 DCHECK(ui::PageTransitionIsMainFrame(params.transition)) << | 1202 DCHECK(ui::PageTransitionIsMainFrame(params.transition)) << |
1208 "WebKit should only tell us about in-page navs for the main frame."; | 1203 "WebKit should only tell us about in-page navs for the main frame."; |
1209 // We're guaranteed to have an entry for this one. | 1204 // We're guaranteed to have an entry for this one. |
1210 NavigationEntryImpl* existing_entry = GetEntryWithPageID( | 1205 NavigationEntryImpl* existing_entry = GetEntryWithPageID( |
1211 rfh->GetSiteInstance(), params.page_id); | 1206 rfh->GetSiteInstance(), params.page_id); |
1212 | 1207 |
1213 // Reference fragment navigation. We're guaranteed to have the last_committed | 1208 // Reference fragment navigation. We're guaranteed to have the last_committed |
1214 // entry and it will be the same page as the new navigation (minus the | 1209 // entry and it will be the same page as the new navigation (minus the |
(...skipping 13 matching lines...) Expand all Loading... |
1228 | 1223 |
1229 DiscardNonCommittedEntriesInternal(); | 1224 DiscardNonCommittedEntriesInternal(); |
1230 | 1225 |
1231 // If a transient entry was removed, the indices might have changed, so we | 1226 // If a transient entry was removed, the indices might have changed, so we |
1232 // have to query the entry index again. | 1227 // have to query the entry index again. |
1233 last_committed_entry_index_ = | 1228 last_committed_entry_index_ = |
1234 GetEntryIndexWithPageID(rfh->GetSiteInstance(), params.page_id); | 1229 GetEntryIndexWithPageID(rfh->GetSiteInstance(), params.page_id); |
1235 } | 1230 } |
1236 | 1231 |
1237 void NavigationControllerImpl::RendererDidNavigateNewSubframe( | 1232 void NavigationControllerImpl::RendererDidNavigateNewSubframe( |
1238 RenderFrameHost* rfh, | 1233 RenderFrameHostImpl* rfh, |
1239 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1234 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
1240 if (!ui::PageTransitionCoreTypeIs(params.transition, | 1235 if (!ui::PageTransitionCoreTypeIs(params.transition, |
1241 ui::PAGE_TRANSITION_MANUAL_SUBFRAME)) { | 1236 ui::PAGE_TRANSITION_MANUAL_SUBFRAME)) { |
1242 // There was a comment here that said, "This is not user-initiated. Ignore." | 1237 // There was a comment here that said, "This is not user-initiated. Ignore." |
1243 // But this makes no sense; non-user-initiated navigations should be | 1238 // But this makes no sense; non-user-initiated navigations should be |
1244 // determined to be of type NAVIGATION_TYPE_AUTO_SUBFRAME and sent to | 1239 // determined to be of type NAVIGATION_TYPE_AUTO_SUBFRAME and sent to |
1245 // RendererDidNavigateAutoSubframe below. | 1240 // RendererDidNavigateAutoSubframe below. |
1246 // | 1241 // |
1247 // This if clause dates back to https://codereview.chromium.org/115919 and | 1242 // This if clause dates back to https://codereview.chromium.org/115919 and |
1248 // the handling of immediate redirects. TODO(avi): Is this still valid? I'm | 1243 // the handling of immediate redirects. TODO(avi): Is this still valid? I'm |
1249 // pretty sure that's there's nothing left of that code and that we should | 1244 // pretty sure that's there's nothing left of that code and that we should |
1250 // take this out. | 1245 // take this out. |
1251 // | 1246 // |
1252 // Except for cross-process iframes; this doesn't work yet for them. | 1247 // Except for cross-process iframes; this doesn't work yet for them. |
1253 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 1248 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
1254 switches::kSitePerProcess)) { | 1249 switches::kSitePerProcess)) { |
1255 NOTREACHED(); | 1250 NOTREACHED(); |
1256 } | 1251 } |
1257 | 1252 |
1258 DiscardNonCommittedEntriesInternal(); | 1253 DiscardNonCommittedEntriesInternal(); |
1259 return; | 1254 return; |
1260 } | 1255 } |
1261 | 1256 |
1262 // Manual subframe navigations just get the current entry cloned so the user | 1257 // Manual subframe navigations just get the current entry cloned so the user |
1263 // can go back or forward to it. The actual subframe information will be | 1258 // can go back or forward to it. The actual subframe information will be |
1264 // stored in the page state for each of those entries. This happens out of | 1259 // stored in the page state for each of those entries. This happens out of |
1265 // band with the actual navigations. | 1260 // band with the actual navigations. |
1266 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 1261 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
1267 << "that a last committed entry exists."; | 1262 << "that a last committed entry exists."; |
1268 NavigationEntryImpl* new_entry = new NavigationEntryImpl( | 1263 NavigationEntryImpl* new_entry = |
1269 *NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry())); | 1264 new NavigationEntryImpl(*GetLastCommittedEntry()); |
1270 new_entry->SetPageID(params.page_id); | 1265 new_entry->SetPageID(params.page_id); |
1271 InsertOrReplaceEntry(new_entry, false); | 1266 InsertOrReplaceEntry(new_entry, false); |
1272 } | 1267 } |
1273 | 1268 |
1274 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe( | 1269 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe( |
1275 RenderFrameHost* rfh, | 1270 RenderFrameHostImpl* rfh, |
1276 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1271 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
1277 DCHECK(ui::PageTransitionCoreTypeIs(params.transition, | 1272 DCHECK(ui::PageTransitionCoreTypeIs(params.transition, |
1278 ui::PAGE_TRANSITION_AUTO_SUBFRAME)); | 1273 ui::PAGE_TRANSITION_AUTO_SUBFRAME)); |
1279 | 1274 |
1280 // We're guaranteed to have a previously committed entry, and we now need to | 1275 // We're guaranteed to have a previously committed entry, and we now need to |
1281 // handle navigation inside of a subframe in it without creating a new entry. | 1276 // handle navigation inside of a subframe in it without creating a new entry. |
1282 DCHECK(GetLastCommittedEntry()); | 1277 DCHECK(GetLastCommittedEntry()); |
1283 | 1278 |
1284 // Handle the case where we're navigating back/forward to a previous subframe | 1279 // Handle the case where we're navigating back/forward to a previous subframe |
1285 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the | 1280 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 | 1385 |
1391 // Adjust indices such that the last entry and pending are at the end now. | 1386 // Adjust indices such that the last entry and pending are at the end now. |
1392 last_committed_entry_index_ = GetEntryCount() - 1; | 1387 last_committed_entry_index_ = GetEntryCount() - 1; |
1393 | 1388 |
1394 delegate_->SetHistoryOffsetAndLength(last_committed_entry_index_, | 1389 delegate_->SetHistoryOffsetAndLength(last_committed_entry_index_, |
1395 GetEntryCount()); | 1390 GetEntryCount()); |
1396 | 1391 |
1397 // Copy the max page id map from the old tab to the new tab. This ensures that | 1392 // Copy the max page id map from the old tab to the new tab. This ensures that |
1398 // new and existing navigations in the tab's current SiteInstances are | 1393 // new and existing navigations in the tab's current SiteInstances are |
1399 // identified properly. | 1394 // identified properly. |
1400 NavigationEntryImpl* last_committed = | 1395 NavigationEntryImpl* last_committed = GetLastCommittedEntry(); |
1401 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); | |
1402 int32 site_max_page_id = | 1396 int32 site_max_page_id = |
1403 delegate_->GetMaxPageIDForSiteInstance(last_committed->site_instance()); | 1397 delegate_->GetMaxPageIDForSiteInstance(last_committed->site_instance()); |
1404 delegate_->CopyMaxPageIDsFrom(source->delegate()->GetWebContents()); | 1398 delegate_->CopyMaxPageIDsFrom(source->delegate()->GetWebContents()); |
1405 delegate_->UpdateMaxPageIDForSiteInstance(last_committed->site_instance(), | 1399 delegate_->UpdateMaxPageIDForSiteInstance(last_committed->site_instance(), |
1406 site_max_page_id); | 1400 site_max_page_id); |
1407 max_restored_page_id_ = source->max_restored_page_id_; | 1401 max_restored_page_id_ = source->max_restored_page_id_; |
1408 } | 1402 } |
1409 | 1403 |
1410 bool NavigationControllerImpl::CanPruneAllButLastCommitted() { | 1404 bool NavigationControllerImpl::CanPruneAllButLastCommitted() { |
1411 // If there is no last committed entry, we cannot prune. Even if there is a | 1405 // If there is no last committed entry, we cannot prune. Even if there is a |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 bool transient = transient_entry_index_ != -1; | 1549 bool transient = transient_entry_index_ != -1; |
1556 DiscardNonCommittedEntriesInternal(); | 1550 DiscardNonCommittedEntriesInternal(); |
1557 | 1551 |
1558 // If there was a transient entry, invalidate everything so the new active | 1552 // If there was a transient entry, invalidate everything so the new active |
1559 // entry state is shown. | 1553 // entry state is shown. |
1560 if (transient) { | 1554 if (transient) { |
1561 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL); | 1555 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_ALL); |
1562 } | 1556 } |
1563 } | 1557 } |
1564 | 1558 |
1565 NavigationEntry* NavigationControllerImpl::GetPendingEntry() const { | 1559 NavigationEntryImpl* NavigationControllerImpl::GetPendingEntry() const { |
1566 return pending_entry_; | 1560 return pending_entry_; |
1567 } | 1561 } |
1568 | 1562 |
1569 int NavigationControllerImpl::GetPendingEntryIndex() const { | 1563 int NavigationControllerImpl::GetPendingEntryIndex() const { |
1570 return pending_entry_index_; | 1564 return pending_entry_index_; |
1571 } | 1565 } |
1572 | 1566 |
1573 void NavigationControllerImpl::InsertOrReplaceEntry(NavigationEntryImpl* entry, | 1567 void NavigationControllerImpl::InsertOrReplaceEntry(NavigationEntryImpl* entry, |
1574 bool replace) { | 1568 bool replace) { |
1575 DCHECK(entry->GetTransitionType() != ui::PAGE_TRANSITION_AUTO_SUBFRAME); | 1569 DCHECK(entry->GetTransitionType() != ui::PAGE_TRANSITION_AUTO_SUBFRAME); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1779 int NavigationControllerImpl::GetEntryIndexWithPageID( | 1773 int NavigationControllerImpl::GetEntryIndexWithPageID( |
1780 SiteInstance* instance, int32 page_id) const { | 1774 SiteInstance* instance, int32 page_id) const { |
1781 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) { | 1775 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) { |
1782 if ((entries_[i]->site_instance() == instance) && | 1776 if ((entries_[i]->site_instance() == instance) && |
1783 (entries_[i]->GetPageID() == page_id)) | 1777 (entries_[i]->GetPageID() == page_id)) |
1784 return i; | 1778 return i; |
1785 } | 1779 } |
1786 return -1; | 1780 return -1; |
1787 } | 1781 } |
1788 | 1782 |
1789 NavigationEntry* NavigationControllerImpl::GetTransientEntry() const { | 1783 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const { |
1790 if (transient_entry_index_ == -1) | 1784 if (transient_entry_index_ == -1) |
1791 return NULL; | 1785 return NULL; |
1792 return entries_[transient_entry_index_].get(); | 1786 return entries_[transient_entry_index_].get(); |
1793 } | 1787 } |
1794 | 1788 |
1795 void NavigationControllerImpl::SetTransientEntry(NavigationEntry* entry) { | 1789 void NavigationControllerImpl::SetTransientEntry(NavigationEntry* entry) { |
1796 // Discard any current transient entry, we can only have one at a time. | 1790 // Discard any current transient entry, we can only have one at a time. |
1797 int index = 0; | 1791 int index = 0; |
1798 if (last_committed_entry_index_ != -1) | 1792 if (last_committed_entry_index_ != -1) |
1799 index = last_committed_entry_index_ + 1; | 1793 index = last_committed_entry_index_ + 1; |
(...skipping 20 matching lines...) Expand all Loading... |
1820 } | 1814 } |
1821 } | 1815 } |
1822 } | 1816 } |
1823 | 1817 |
1824 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 1818 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
1825 const base::Callback<base::Time()>& get_timestamp_callback) { | 1819 const base::Callback<base::Time()>& get_timestamp_callback) { |
1826 get_timestamp_callback_ = get_timestamp_callback; | 1820 get_timestamp_callback_ = get_timestamp_callback; |
1827 } | 1821 } |
1828 | 1822 |
1829 } // namespace content | 1823 } // namespace content |
OLD | NEW |