| 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/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_number_conversions.h" // Temporary | 10 #include "base/strings/string_number_conversions.h" // Temporary |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 break; | 729 break; |
| 730 default: | 730 default: |
| 731 NOTREACHED(); | 731 NOTREACHED(); |
| 732 break; | 732 break; |
| 733 }; | 733 }; |
| 734 | 734 |
| 735 LoadEntry(entry); | 735 LoadEntry(entry); |
| 736 } | 736 } |
| 737 | 737 |
| 738 bool NavigationControllerImpl::RendererDidNavigate( | 738 bool NavigationControllerImpl::RendererDidNavigate( |
| 739 RenderViewHost* rvh, | 739 RenderFrameHost* rfh, |
| 740 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 740 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 741 LoadCommittedDetails* details) { | 741 LoadCommittedDetails* details) { |
| 742 is_initial_navigation_ = false; | 742 is_initial_navigation_ = false; |
| 743 | 743 |
| 744 // Save the previous state before we clobber it. | 744 // Save the previous state before we clobber it. |
| 745 if (GetLastCommittedEntry()) { | 745 if (GetLastCommittedEntry()) { |
| 746 details->previous_url = GetLastCommittedEntry()->GetURL(); | 746 details->previous_url = GetLastCommittedEntry()->GetURL(); |
| 747 details->previous_entry_index = GetLastCommittedEntryIndex(); | 747 details->previous_entry_index = GetLastCommittedEntryIndex(); |
| 748 } else { | 748 } else { |
| 749 details->previous_url = GURL(); | 749 details->previous_url = GURL(); |
| 750 details->previous_entry_index = -1; | 750 details->previous_entry_index = -1; |
| 751 } | 751 } |
| 752 | 752 |
| 753 // If we have a pending entry at this point, it should have a SiteInstance. | 753 // If we have a pending entry at this point, it should have a SiteInstance. |
| 754 // Restored entries start out with a null SiteInstance, but we should have | 754 // Restored entries start out with a null SiteInstance, but we should have |
| 755 // assigned one in NavigateToPendingEntry. | 755 // assigned one in NavigateToPendingEntry. |
| 756 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance()); | 756 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance()); |
| 757 | 757 |
| 758 // If we are doing a cross-site reload, we need to replace the existing | 758 // If we are doing a cross-site reload, we need to replace the existing |
| 759 // navigation entry, not add another entry to the history. This has the side | 759 // navigation entry, not add another entry to the history. This has the side |
| 760 // effect of removing forward browsing history, if such existed. | 760 // effect of removing forward browsing history, if such existed. |
| 761 // Or if we are doing a cross-site redirect navigation, | 761 // Or if we are doing a cross-site redirect navigation, |
| 762 // we will do a similar thing. | 762 // we will do a similar thing. |
| 763 details->did_replace_entry = | 763 details->did_replace_entry = |
| 764 pending_entry_ && pending_entry_->should_replace_entry(); | 764 pending_entry_ && pending_entry_->should_replace_entry(); |
| 765 | 765 |
| 766 // Do navigation-type specific actions. These will make and commit an entry. | 766 // Do navigation-type specific actions. These will make and commit an entry. |
| 767 details->type = ClassifyNavigation(rvh, params); | 767 details->type = ClassifyNavigation(rfh, params); |
| 768 | 768 |
| 769 // is_in_page must be computed before the entry gets committed. | 769 // is_in_page must be computed before the entry gets committed. |
| 770 details->is_in_page = IsURLInPageNavigation( | 770 details->is_in_page = IsURLInPageNavigation( |
| 771 params.url, params.was_within_same_page, details->type); | 771 params.url, params.was_within_same_page, details->type); |
| 772 | 772 |
| 773 switch (details->type) { | 773 switch (details->type) { |
| 774 case NAVIGATION_TYPE_NEW_PAGE: | 774 case NAVIGATION_TYPE_NEW_PAGE: |
| 775 RendererDidNavigateToNewPage(rvh, params, details->did_replace_entry); | 775 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); |
| 776 break; | 776 break; |
| 777 case NAVIGATION_TYPE_EXISTING_PAGE: | 777 case NAVIGATION_TYPE_EXISTING_PAGE: |
| 778 RendererDidNavigateToExistingPage(rvh, params); | 778 RendererDidNavigateToExistingPage(rfh, params); |
| 779 break; | 779 break; |
| 780 case NAVIGATION_TYPE_SAME_PAGE: | 780 case NAVIGATION_TYPE_SAME_PAGE: |
| 781 RendererDidNavigateToSamePage(rvh, params); | 781 RendererDidNavigateToSamePage(rfh, params); |
| 782 break; | 782 break; |
| 783 case NAVIGATION_TYPE_IN_PAGE: | 783 case NAVIGATION_TYPE_IN_PAGE: |
| 784 RendererDidNavigateInPage(rvh, params, &details->did_replace_entry); | 784 RendererDidNavigateInPage(rfh, params, &details->did_replace_entry); |
| 785 break; | 785 break; |
| 786 case NAVIGATION_TYPE_NEW_SUBFRAME: | 786 case NAVIGATION_TYPE_NEW_SUBFRAME: |
| 787 RendererDidNavigateNewSubframe(rvh, params); | 787 RendererDidNavigateNewSubframe(rfh, params); |
| 788 break; | 788 break; |
| 789 case NAVIGATION_TYPE_AUTO_SUBFRAME: | 789 case NAVIGATION_TYPE_AUTO_SUBFRAME: |
| 790 if (!RendererDidNavigateAutoSubframe(rvh, params)) | 790 if (!RendererDidNavigateAutoSubframe(rfh, params)) |
| 791 return false; | 791 return false; |
| 792 break; | 792 break; |
| 793 case NAVIGATION_TYPE_NAV_IGNORE: | 793 case NAVIGATION_TYPE_NAV_IGNORE: |
| 794 // If a pending navigation was in progress, this canceled it. We should | 794 // If a pending navigation was in progress, this canceled it. We should |
| 795 // discard it and make sure it is removed from the URL bar. After that, | 795 // discard it and make sure it is removed from the URL bar. After that, |
| 796 // there is nothing we can do with this navigation, so we just return to | 796 // there is nothing we can do with this navigation, so we just return to |
| 797 // the caller that nothing has happened. | 797 // the caller that nothing has happened. |
| 798 if (pending_entry_) { | 798 if (pending_entry_) { |
| 799 DiscardNonCommittedEntries(); | 799 DiscardNonCommittedEntries(); |
| 800 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); | 800 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 828 active_entry->SetPageState(params.page_state); | 828 active_entry->SetPageState(params.page_state); |
| 829 | 829 |
| 830 // Once it is committed, we no longer need to track several pieces of state on | 830 // Once it is committed, we no longer need to track several pieces of state on |
| 831 // the entry. | 831 // the entry. |
| 832 active_entry->ResetForCommit(); | 832 active_entry->ResetForCommit(); |
| 833 | 833 |
| 834 // The active entry's SiteInstance should match our SiteInstance. | 834 // The active entry's SiteInstance should match our SiteInstance. |
| 835 // TODO(creis): This check won't pass for subframes until we create entries | 835 // TODO(creis): This check won't pass for subframes until we create entries |
| 836 // for subframe navigations. | 836 // for subframe navigations. |
| 837 if (PageTransitionIsMainFrame(params.transition)) | 837 if (PageTransitionIsMainFrame(params.transition)) |
| 838 CHECK(active_entry->site_instance() == rvh->GetSiteInstance()); | 838 CHECK(active_entry->site_instance() == rfh->GetSiteInstance()); |
| 839 | 839 |
| 840 // Remember the bindings the renderer process has at this point, so that | 840 // Remember the bindings the renderer process has at this point, so that |
| 841 // we do not grant this entry additional bindings if we come back to it. | 841 // we do not grant this entry additional bindings if we come back to it. |
| 842 active_entry->SetBindings(rvh->GetEnabledBindings()); | 842 active_entry->SetBindings( |
| 843 static_cast<RenderFrameHostImpl*>(rfh)->GetEnabledBindings()); |
| 843 | 844 |
| 844 // Now prep the rest of the details for the notification and broadcast. | 845 // Now prep the rest of the details for the notification and broadcast. |
| 845 details->entry = active_entry; | 846 details->entry = active_entry; |
| 846 details->is_main_frame = | 847 details->is_main_frame = |
| 847 PageTransitionIsMainFrame(params.transition); | 848 PageTransitionIsMainFrame(params.transition); |
| 848 details->serialized_security_info = params.security_info; | 849 details->serialized_security_info = params.security_info; |
| 849 details->http_status_code = params.http_status_code; | 850 details->http_status_code = params.http_status_code; |
| 850 NotifyNavigationEntryCommitted(details); | 851 NotifyNavigationEntryCommitted(details); |
| 851 | 852 |
| 852 return true; | 853 return true; |
| 853 } | 854 } |
| 854 | 855 |
| 855 NavigationType NavigationControllerImpl::ClassifyNavigation( | 856 NavigationType NavigationControllerImpl::ClassifyNavigation( |
| 856 RenderViewHost* rvh, | 857 RenderFrameHost* rfh, |
| 857 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { | 858 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { |
| 858 if (params.page_id == -1) { | 859 if (params.page_id == -1) { |
| 859 // The renderer generates the page IDs, and so if it gives us the invalid | 860 // The renderer generates the page IDs, and so if it gives us the invalid |
| 860 // page ID (-1) we know it didn't actually navigate. This happens in a few | 861 // page ID (-1) we know it didn't actually navigate. This happens in a few |
| 861 // cases: | 862 // cases: |
| 862 // | 863 // |
| 863 // - If a page makes a popup navigated to about blank, and then writes | 864 // - If a page makes a popup navigated to about blank, and then writes |
| 864 // stuff like a subframe navigated to a real page. We'll get the commit | 865 // stuff like a subframe navigated to a real page. We'll get the commit |
| 865 // for the subframe, but there won't be any commit for the outer page. | 866 // for the subframe, but there won't be any commit for the outer page. |
| 866 // | 867 // |
| 867 // - We were also getting these for failed loads (for example, bug 21849). | 868 // - We were also getting these for failed loads (for example, bug 21849). |
| 868 // The guess is that we get a "load commit" for the alternate error page, | 869 // The guess is that we get a "load commit" for the alternate error page, |
| 869 // but that doesn't affect the page ID, so we get the "old" one, which | 870 // but that doesn't affect the page ID, so we get the "old" one, which |
| 870 // could be invalid. This can also happen for a cross-site transition | 871 // could be invalid. This can also happen for a cross-site transition |
| 871 // that causes us to swap processes. Then the error page load will be in | 872 // that causes us to swap processes. Then the error page load will be in |
| 872 // a new process with no page IDs ever assigned (and hence a -1 value), | 873 // a new process with no page IDs ever assigned (and hence a -1 value), |
| 873 // yet the navigation controller still might have previous pages in its | 874 // yet the navigation controller still might have previous pages in its |
| 874 // list. | 875 // list. |
| 875 // | 876 // |
| 876 // In these cases, there's nothing we can do with them, so ignore. | 877 // In these cases, there's nothing we can do with them, so ignore. |
| 877 return NAVIGATION_TYPE_NAV_IGNORE; | 878 return NAVIGATION_TYPE_NAV_IGNORE; |
| 878 } | 879 } |
| 879 | 880 |
| 880 if (params.page_id > delegate_->GetMaxPageIDForSiteInstance( | 881 if (params.page_id > delegate_->GetMaxPageIDForSiteInstance( |
| 881 rvh->GetSiteInstance())) { | 882 rfh->GetSiteInstance())) { |
| 882 // Greater page IDs than we've ever seen before are new pages. We may or may | 883 // Greater page IDs than we've ever seen before are new pages. We may or may |
| 883 // not have a pending entry for the page, and this may or may not be the | 884 // not have a pending entry for the page, and this may or may not be the |
| 884 // main frame. | 885 // main frame. |
| 885 if (PageTransitionIsMainFrame(params.transition)) | 886 if (PageTransitionIsMainFrame(params.transition)) |
| 886 return NAVIGATION_TYPE_NEW_PAGE; | 887 return NAVIGATION_TYPE_NEW_PAGE; |
| 887 | 888 |
| 888 // When this is a new subframe navigation, we should have a committed page | 889 // When this is a new subframe navigation, we should have a committed page |
| 889 // for which it's a suframe in. This may not be the case when an iframe is | 890 // for which it's a suframe in. This may not be the case when an iframe is |
| 890 // navigated on a popup navigated to about:blank (the iframe would be | 891 // navigated on a popup navigated to about:blank (the iframe would be |
| 891 // written into the popup by script on the main page). For these cases, | 892 // written into the popup by script on the main page). For these cases, |
| 892 // there isn't any navigation stuff we can do, so just ignore it. | 893 // there isn't any navigation stuff we can do, so just ignore it. |
| 893 if (!GetLastCommittedEntry()) | 894 if (!GetLastCommittedEntry()) |
| 894 return NAVIGATION_TYPE_NAV_IGNORE; | 895 return NAVIGATION_TYPE_NAV_IGNORE; |
| 895 | 896 |
| 896 // Valid subframe navigation. | 897 // Valid subframe navigation. |
| 897 return NAVIGATION_TYPE_NEW_SUBFRAME; | 898 return NAVIGATION_TYPE_NEW_SUBFRAME; |
| 898 } | 899 } |
| 899 | 900 |
| 900 // We only clear the session history when navigating to a new page. | 901 // We only clear the session history when navigating to a new page. |
| 901 DCHECK(!params.history_list_was_cleared); | 902 DCHECK(!params.history_list_was_cleared); |
| 902 | 903 |
| 903 // Now we know that the notification is for an existing page. Find that entry. | 904 // Now we know that the notification is for an existing page. Find that entry. |
| 904 int existing_entry_index = GetEntryIndexWithPageID( | 905 int existing_entry_index = GetEntryIndexWithPageID( |
| 905 rvh->GetSiteInstance(), | 906 rfh->GetSiteInstance(), |
| 906 params.page_id); | 907 params.page_id); |
| 907 if (existing_entry_index == -1) { | 908 if (existing_entry_index == -1) { |
| 908 // The page was not found. It could have been pruned because of the limit on | 909 // The page was not found. It could have been pruned because of the limit on |
| 909 // back/forward entries (not likely since we'll usually tell it to navigate | 910 // back/forward entries (not likely since we'll usually tell it to navigate |
| 910 // to such entries). It could also mean that the renderer is smoking crack. | 911 // to such entries). It could also mean that the renderer is smoking crack. |
| 911 NOTREACHED(); | 912 NOTREACHED(); |
| 912 | 913 |
| 913 // Because the unknown entry has committed, we risk showing the wrong URL in | 914 // Because the unknown entry has committed, we risk showing the wrong URL in |
| 914 // release builds. Instead, we'll kill the renderer process to be safe. | 915 // release builds. Instead, we'll kill the renderer process to be safe. |
| 915 LOG(ERROR) << "terminating renderer for bad navigation: " << params.url; | 916 LOG(ERROR) << "terminating renderer for bad navigation: " << params.url; |
| 916 RecordAction(base::UserMetricsAction("BadMessageTerminate_NC")); | 917 RecordAction(base::UserMetricsAction("BadMessageTerminate_NC")); |
| 917 | 918 |
| 918 // Temporary code so we can get more information. Format: | 919 // Temporary code so we can get more information. Format: |
| 919 // http://url/foo.html#page1#max3#frame1#ids:2_Nx,1_1x,3_2 | 920 // http://url/foo.html#page1#max3#frame1#ids:2_Nx,1_1x,3_2 |
| 920 std::string temp = params.url.spec(); | 921 std::string temp = params.url.spec(); |
| 921 temp.append("#page"); | 922 temp.append("#page"); |
| 922 temp.append(base::IntToString(params.page_id)); | 923 temp.append(base::IntToString(params.page_id)); |
| 923 temp.append("#max"); | 924 temp.append("#max"); |
| 924 temp.append(base::IntToString(delegate_->GetMaxPageID())); | 925 temp.append(base::IntToString(delegate_->GetMaxPageID())); |
| 925 temp.append("#frame"); | 926 temp.append("#frame"); |
| 926 temp.append(base::IntToString(params.frame_id)); | 927 temp.append(base::IntToString(rfh->GetRoutingID())); |
| 927 temp.append("#ids"); | 928 temp.append("#ids"); |
| 928 for (int i = 0; i < static_cast<int>(entries_.size()); ++i) { | 929 for (int i = 0; i < static_cast<int>(entries_.size()); ++i) { |
| 929 // Append entry metadata (e.g., 3_7x): | 930 // Append entry metadata (e.g., 3_7x): |
| 930 // 3: page_id | 931 // 3: page_id |
| 931 // 7: SiteInstance ID, or N for null | 932 // 7: SiteInstance ID, or N for null |
| 932 // x: appended if not from the current SiteInstance | 933 // x: appended if not from the current SiteInstance |
| 933 temp.append(base::IntToString(entries_[i]->GetPageID())); | 934 temp.append(base::IntToString(entries_[i]->GetPageID())); |
| 934 temp.append("_"); | 935 temp.append("_"); |
| 935 if (entries_[i]->site_instance()) | 936 if (entries_[i]->site_instance()) |
| 936 temp.append(base::IntToString(entries_[i]->site_instance()->GetId())); | 937 temp.append(base::IntToString(entries_[i]->site_instance()->GetId())); |
| 937 else | 938 else |
| 938 temp.append("N"); | 939 temp.append("N"); |
| 939 if (entries_[i]->site_instance() != rvh->GetSiteInstance()) | 940 if (entries_[i]->site_instance() != rfh->GetSiteInstance()) |
| 940 temp.append("x"); | 941 temp.append("x"); |
| 941 temp.append(","); | 942 temp.append(","); |
| 942 } | 943 } |
| 943 GURL url(temp); | 944 GURL url(temp); |
| 944 static_cast<RenderViewHostImpl*>(rvh)->Send( | 945 static_cast<RenderFrameHostImpl*>(rfh)->render_view_host()->Send( |
| 945 new ViewMsg_TempCrashWithData(url)); | 946 new ViewMsg_TempCrashWithData(url)); |
| 946 return NAVIGATION_TYPE_NAV_IGNORE; | 947 return NAVIGATION_TYPE_NAV_IGNORE; |
| 947 } | 948 } |
| 948 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get(); | 949 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get(); |
| 949 | 950 |
| 950 if (!PageTransitionIsMainFrame(params.transition)) { | 951 if (!PageTransitionIsMainFrame(params.transition)) { |
| 951 // All manual subframes would get new IDs and were handled above, so we | 952 // All manual subframes would get new IDs and were handled above, so we |
| 952 // know this is auto. Since the current page was found in the navigation | 953 // know this is auto. Since the current page was found in the navigation |
| 953 // entry list, we're guaranteed to have a last committed entry. | 954 // entry list, we're guaranteed to have a last committed entry. |
| 954 DCHECK(GetLastCommittedEntry()); | 955 DCHECK(GetLastCommittedEntry()); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 981 NAVIGATION_TYPE_UNKNOWN)) { | 982 NAVIGATION_TYPE_UNKNOWN)) { |
| 982 return NAVIGATION_TYPE_IN_PAGE; | 983 return NAVIGATION_TYPE_IN_PAGE; |
| 983 } | 984 } |
| 984 | 985 |
| 985 // Since we weeded out "new" navigations above, we know this is an existing | 986 // Since we weeded out "new" navigations above, we know this is an existing |
| 986 // (back/forward) navigation. | 987 // (back/forward) navigation. |
| 987 return NAVIGATION_TYPE_EXISTING_PAGE; | 988 return NAVIGATION_TYPE_EXISTING_PAGE; |
| 988 } | 989 } |
| 989 | 990 |
| 990 void NavigationControllerImpl::RendererDidNavigateToNewPage( | 991 void NavigationControllerImpl::RendererDidNavigateToNewPage( |
| 991 RenderViewHost* rvh, | 992 RenderFrameHost* rfh, |
| 992 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 993 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 993 bool replace_entry) { | 994 bool replace_entry) { |
| 994 NavigationEntryImpl* new_entry; | 995 NavigationEntryImpl* new_entry; |
| 995 bool update_virtual_url; | 996 bool update_virtual_url; |
| 996 // Only make a copy of the pending entry if it is appropriate for the new page | 997 // Only make a copy of the pending entry if it is appropriate for the new page |
| 997 // that was just loaded. We verify this at a coarse grain by checking that | 998 // that was just loaded. We verify this at a coarse grain by checking that |
| 998 // the SiteInstance hasn't been assigned to something else. | 999 // the SiteInstance hasn't been assigned to something else. |
| 999 if (pending_entry_ && | 1000 if (pending_entry_ && |
| 1000 (!pending_entry_->site_instance() || | 1001 (!pending_entry_->site_instance() || |
| 1001 pending_entry_->site_instance() == rvh->GetSiteInstance())) { | 1002 pending_entry_->site_instance() == rfh->GetSiteInstance())) { |
| 1002 new_entry = new NavigationEntryImpl(*pending_entry_); | 1003 new_entry = new NavigationEntryImpl(*pending_entry_); |
| 1003 | 1004 |
| 1004 // Don't use the page type from the pending entry. Some interstitial page | 1005 // Don't use the page type from the pending entry. Some interstitial page |
| 1005 // may have set the type to interstitial. Once we commit, however, the page | 1006 // may have set the type to interstitial. Once we commit, however, the page |
| 1006 // type must always be normal. | 1007 // type must always be normal. |
| 1007 new_entry->set_page_type(PAGE_TYPE_NORMAL); | 1008 new_entry->set_page_type(PAGE_TYPE_NORMAL); |
| 1008 update_virtual_url = new_entry->update_virtual_url_with_url(); | 1009 update_virtual_url = new_entry->update_virtual_url_with_url(); |
| 1009 } else { | 1010 } else { |
| 1010 new_entry = new NavigationEntryImpl; | 1011 new_entry = new NavigationEntryImpl; |
| 1011 | 1012 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1025 update_virtual_url = needs_update; | 1026 update_virtual_url = needs_update; |
| 1026 } | 1027 } |
| 1027 | 1028 |
| 1028 new_entry->SetURL(params.url); | 1029 new_entry->SetURL(params.url); |
| 1029 if (update_virtual_url) | 1030 if (update_virtual_url) |
| 1030 UpdateVirtualURLToURL(new_entry, params.url); | 1031 UpdateVirtualURLToURL(new_entry, params.url); |
| 1031 new_entry->SetReferrer(params.referrer); | 1032 new_entry->SetReferrer(params.referrer); |
| 1032 new_entry->SetPageID(params.page_id); | 1033 new_entry->SetPageID(params.page_id); |
| 1033 new_entry->SetTransitionType(params.transition); | 1034 new_entry->SetTransitionType(params.transition); |
| 1034 new_entry->set_site_instance( | 1035 new_entry->set_site_instance( |
| 1035 static_cast<SiteInstanceImpl*>(rvh->GetSiteInstance())); | 1036 static_cast<SiteInstanceImpl*>(rfh->GetSiteInstance())); |
| 1036 new_entry->SetHasPostData(params.is_post); | 1037 new_entry->SetHasPostData(params.is_post); |
| 1037 new_entry->SetPostID(params.post_id); | 1038 new_entry->SetPostID(params.post_id); |
| 1038 new_entry->SetOriginalRequestURL(params.original_request_url); | 1039 new_entry->SetOriginalRequestURL(params.original_request_url); |
| 1039 new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent); | 1040 new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent); |
| 1040 | 1041 |
| 1041 DCHECK(!params.history_list_was_cleared || !replace_entry); | 1042 DCHECK(!params.history_list_was_cleared || !replace_entry); |
| 1042 // The browser requested to clear the session history when it initiated the | 1043 // The browser requested to clear the session history when it initiated the |
| 1043 // navigation. Now we know that the renderer has updated its state accordingly | 1044 // navigation. Now we know that the renderer has updated its state accordingly |
| 1044 // and it is safe to also clear the browser side history. | 1045 // and it is safe to also clear the browser side history. |
| 1045 if (params.history_list_was_cleared) { | 1046 if (params.history_list_was_cleared) { |
| 1046 DiscardNonCommittedEntriesInternal(); | 1047 DiscardNonCommittedEntriesInternal(); |
| 1047 entries_.clear(); | 1048 entries_.clear(); |
| 1048 last_committed_entry_index_ = -1; | 1049 last_committed_entry_index_ = -1; |
| 1049 } | 1050 } |
| 1050 | 1051 |
| 1051 InsertOrReplaceEntry(new_entry, replace_entry); | 1052 InsertOrReplaceEntry(new_entry, replace_entry); |
| 1052 } | 1053 } |
| 1053 | 1054 |
| 1054 void NavigationControllerImpl::RendererDidNavigateToExistingPage( | 1055 void NavigationControllerImpl::RendererDidNavigateToExistingPage( |
| 1055 RenderViewHost* rvh, | 1056 RenderFrameHost* rfh, |
| 1056 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1057 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1057 // We should only get here for main frame navigations. | 1058 // We should only get here for main frame navigations. |
| 1058 DCHECK(PageTransitionIsMainFrame(params.transition)); | 1059 DCHECK(PageTransitionIsMainFrame(params.transition)); |
| 1059 | 1060 |
| 1060 // This is a back/forward navigation. The existing page for the ID is | 1061 // This is a back/forward navigation. The existing page for the ID is |
| 1061 // guaranteed to exist by ClassifyNavigation, and we just need to update it | 1062 // guaranteed to exist by ClassifyNavigation, and we just need to update it |
| 1062 // with new information from the renderer. | 1063 // with new information from the renderer. |
| 1063 int entry_index = GetEntryIndexWithPageID(rvh->GetSiteInstance(), | 1064 int entry_index = GetEntryIndexWithPageID(rfh->GetSiteInstance(), |
| 1064 params.page_id); | 1065 params.page_id); |
| 1065 DCHECK(entry_index >= 0 && | 1066 DCHECK(entry_index >= 0 && |
| 1066 entry_index < static_cast<int>(entries_.size())); | 1067 entry_index < static_cast<int>(entries_.size())); |
| 1067 NavigationEntryImpl* entry = entries_[entry_index].get(); | 1068 NavigationEntryImpl* entry = entries_[entry_index].get(); |
| 1068 | 1069 |
| 1069 // The URL may have changed due to redirects. | 1070 // The URL may have changed due to redirects. |
| 1070 entry->SetURL(params.url); | 1071 entry->SetURL(params.url); |
| 1071 entry->SetReferrer(params.referrer); | 1072 entry->SetReferrer(params.referrer); |
| 1072 if (entry->update_virtual_url_with_url()) | 1073 if (entry->update_virtual_url_with_url()) |
| 1073 UpdateVirtualURLToURL(entry, params.url); | 1074 UpdateVirtualURLToURL(entry, params.url); |
| 1074 | 1075 |
| 1075 // The redirected to page should not inherit the favicon from the previous | 1076 // The redirected to page should not inherit the favicon from the previous |
| 1076 // page. | 1077 // page. |
| 1077 if (PageTransitionIsRedirect(params.transition)) | 1078 if (PageTransitionIsRedirect(params.transition)) |
| 1078 entry->GetFavicon() = FaviconStatus(); | 1079 entry->GetFavicon() = FaviconStatus(); |
| 1079 | 1080 |
| 1080 // The site instance will normally be the same except during session restore, | 1081 // The site instance will normally be the same except during session restore, |
| 1081 // when no site instance will be assigned. | 1082 // when no site instance will be assigned. |
| 1082 DCHECK(entry->site_instance() == NULL || | 1083 DCHECK(entry->site_instance() == NULL || |
| 1083 entry->site_instance() == rvh->GetSiteInstance()); | 1084 entry->site_instance() == rfh->GetSiteInstance()); |
| 1084 entry->set_site_instance( | 1085 entry->set_site_instance( |
| 1085 static_cast<SiteInstanceImpl*>(rvh->GetSiteInstance())); | 1086 static_cast<SiteInstanceImpl*>(rfh->GetSiteInstance())); |
| 1086 | 1087 |
| 1087 entry->SetHasPostData(params.is_post); | 1088 entry->SetHasPostData(params.is_post); |
| 1088 entry->SetPostID(params.post_id); | 1089 entry->SetPostID(params.post_id); |
| 1089 | 1090 |
| 1090 // The entry we found in the list might be pending if the user hit | 1091 // The entry we found in the list might be pending if the user hit |
| 1091 // back/forward/reload. This load should commit it (since it's already in the | 1092 // back/forward/reload. This load should commit it (since it's already in the |
| 1092 // list, we can just discard the pending pointer). We should also discard the | 1093 // list, we can just discard the pending pointer). We should also discard the |
| 1093 // pending entry if it corresponds to a different navigation, since that one | 1094 // pending entry if it corresponds to a different navigation, since that one |
| 1094 // is now likely canceled. If it is not canceled, we will treat it as a new | 1095 // is now likely canceled. If it is not canceled, we will treat it as a new |
| 1095 // navigation when it arrives, which is also ok. | 1096 // navigation when it arrives, which is also ok. |
| 1096 // | 1097 // |
| 1097 // Note that we need to use the "internal" version since we don't want to | 1098 // Note that we need to use the "internal" version since we don't want to |
| 1098 // actually change any other state, just kill the pointer. | 1099 // actually change any other state, just kill the pointer. |
| 1099 DiscardNonCommittedEntriesInternal(); | 1100 DiscardNonCommittedEntriesInternal(); |
| 1100 | 1101 |
| 1101 // If a transient entry was removed, the indices might have changed, so we | 1102 // If a transient entry was removed, the indices might have changed, so we |
| 1102 // have to query the entry index again. | 1103 // have to query the entry index again. |
| 1103 last_committed_entry_index_ = | 1104 last_committed_entry_index_ = |
| 1104 GetEntryIndexWithPageID(rvh->GetSiteInstance(), params.page_id); | 1105 GetEntryIndexWithPageID(rfh->GetSiteInstance(), params.page_id); |
| 1105 } | 1106 } |
| 1106 | 1107 |
| 1107 void NavigationControllerImpl::RendererDidNavigateToSamePage( | 1108 void NavigationControllerImpl::RendererDidNavigateToSamePage( |
| 1108 RenderViewHost* rvh, | 1109 RenderFrameHost* rfh, |
| 1109 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1110 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1110 // This mode implies we have a pending entry that's the same as an existing | 1111 // This mode implies we have a pending entry that's the same as an existing |
| 1111 // entry for this page ID. This entry is guaranteed to exist by | 1112 // entry for this page ID. This entry is guaranteed to exist by |
| 1112 // ClassifyNavigation. All we need to do is update the existing entry. | 1113 // ClassifyNavigation. All we need to do is update the existing entry. |
| 1113 NavigationEntryImpl* existing_entry = GetEntryWithPageID( | 1114 NavigationEntryImpl* existing_entry = GetEntryWithPageID( |
| 1114 rvh->GetSiteInstance(), params.page_id); | 1115 rfh->GetSiteInstance(), params.page_id); |
| 1115 | 1116 |
| 1116 // We assign the entry's unique ID to be that of the new one. Since this is | 1117 // We assign the entry's unique ID to be that of the new one. Since this is |
| 1117 // always the result of a user action, we want to dismiss infobars, etc. like | 1118 // always the result of a user action, we want to dismiss infobars, etc. like |
| 1118 // a regular user-initiated navigation. | 1119 // a regular user-initiated navigation. |
| 1119 existing_entry->set_unique_id(pending_entry_->GetUniqueID()); | 1120 existing_entry->set_unique_id(pending_entry_->GetUniqueID()); |
| 1120 | 1121 |
| 1121 // The URL may have changed due to redirects. | 1122 // The URL may have changed due to redirects. |
| 1122 if (existing_entry->update_virtual_url_with_url()) | 1123 if (existing_entry->update_virtual_url_with_url()) |
| 1123 UpdateVirtualURLToURL(existing_entry, params.url); | 1124 UpdateVirtualURLToURL(existing_entry, params.url); |
| 1124 existing_entry->SetURL(params.url); | 1125 existing_entry->SetURL(params.url); |
| 1125 existing_entry->SetReferrer(params.referrer); | 1126 existing_entry->SetReferrer(params.referrer); |
| 1126 | 1127 |
| 1127 // The page may have been requested with a different HTTP method. | 1128 // The page may have been requested with a different HTTP method. |
| 1128 existing_entry->SetHasPostData(params.is_post); | 1129 existing_entry->SetHasPostData(params.is_post); |
| 1129 existing_entry->SetPostID(params.post_id); | 1130 existing_entry->SetPostID(params.post_id); |
| 1130 | 1131 |
| 1131 DiscardNonCommittedEntries(); | 1132 DiscardNonCommittedEntries(); |
| 1132 } | 1133 } |
| 1133 | 1134 |
| 1134 void NavigationControllerImpl::RendererDidNavigateInPage( | 1135 void NavigationControllerImpl::RendererDidNavigateInPage( |
| 1135 RenderViewHost* rvh, | 1136 RenderFrameHost* rfh, |
| 1136 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 1137 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 1137 bool* did_replace_entry) { | 1138 bool* did_replace_entry) { |
| 1138 DCHECK(PageTransitionIsMainFrame(params.transition)) << | 1139 DCHECK(PageTransitionIsMainFrame(params.transition)) << |
| 1139 "WebKit should only tell us about in-page navs for the main frame."; | 1140 "WebKit should only tell us about in-page navs for the main frame."; |
| 1140 // We're guaranteed to have an entry for this one. | 1141 // We're guaranteed to have an entry for this one. |
| 1141 NavigationEntryImpl* existing_entry = GetEntryWithPageID( | 1142 NavigationEntryImpl* existing_entry = GetEntryWithPageID( |
| 1142 rvh->GetSiteInstance(), params.page_id); | 1143 rfh->GetSiteInstance(), params.page_id); |
| 1143 | 1144 |
| 1144 // Reference fragment navigation. We're guaranteed to have the last_committed | 1145 // Reference fragment navigation. We're guaranteed to have the last_committed |
| 1145 // entry and it will be the same page as the new navigation (minus the | 1146 // entry and it will be the same page as the new navigation (minus the |
| 1146 // reference fragments, of course). We'll update the URL of the existing | 1147 // reference fragments, of course). We'll update the URL of the existing |
| 1147 // entry without pruning the forward history. | 1148 // entry without pruning the forward history. |
| 1148 existing_entry->SetURL(params.url); | 1149 existing_entry->SetURL(params.url); |
| 1149 if (existing_entry->update_virtual_url_with_url()) | 1150 if (existing_entry->update_virtual_url_with_url()) |
| 1150 UpdateVirtualURLToURL(existing_entry, params.url); | 1151 UpdateVirtualURLToURL(existing_entry, params.url); |
| 1151 | 1152 |
| 1152 // This replaces the existing entry since the page ID didn't change. | 1153 // This replaces the existing entry since the page ID didn't change. |
| 1153 *did_replace_entry = true; | 1154 *did_replace_entry = true; |
| 1154 | 1155 |
| 1155 DiscardNonCommittedEntriesInternal(); | 1156 DiscardNonCommittedEntriesInternal(); |
| 1156 | 1157 |
| 1157 // If a transient entry was removed, the indices might have changed, so we | 1158 // If a transient entry was removed, the indices might have changed, so we |
| 1158 // have to query the entry index again. | 1159 // have to query the entry index again. |
| 1159 last_committed_entry_index_ = | 1160 last_committed_entry_index_ = |
| 1160 GetEntryIndexWithPageID(rvh->GetSiteInstance(), params.page_id); | 1161 GetEntryIndexWithPageID(rfh->GetSiteInstance(), params.page_id); |
| 1161 } | 1162 } |
| 1162 | 1163 |
| 1163 void NavigationControllerImpl::RendererDidNavigateNewSubframe( | 1164 void NavigationControllerImpl::RendererDidNavigateNewSubframe( |
| 1164 RenderViewHost* rvh, | 1165 RenderFrameHost* rfh, |
| 1165 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1166 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1166 if (PageTransitionCoreTypeIs(params.transition, | 1167 if (PageTransitionCoreTypeIs(params.transition, |
| 1167 PAGE_TRANSITION_AUTO_SUBFRAME)) { | 1168 PAGE_TRANSITION_AUTO_SUBFRAME)) { |
| 1168 // This is not user-initiated. Ignore. | 1169 // This is not user-initiated. Ignore. |
| 1169 DiscardNonCommittedEntriesInternal(); | 1170 DiscardNonCommittedEntriesInternal(); |
| 1170 return; | 1171 return; |
| 1171 } | 1172 } |
| 1172 | 1173 |
| 1173 // Manual subframe navigations just get the current entry cloned so the user | 1174 // Manual subframe navigations just get the current entry cloned so the user |
| 1174 // can go back or forward to it. The actual subframe information will be | 1175 // can go back or forward to it. The actual subframe information will be |
| 1175 // stored in the page state for each of those entries. This happens out of | 1176 // stored in the page state for each of those entries. This happens out of |
| 1176 // band with the actual navigations. | 1177 // band with the actual navigations. |
| 1177 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 1178 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
| 1178 << "that a last committed entry exists."; | 1179 << "that a last committed entry exists."; |
| 1179 NavigationEntryImpl* new_entry = new NavigationEntryImpl( | 1180 NavigationEntryImpl* new_entry = new NavigationEntryImpl( |
| 1180 *NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry())); | 1181 *NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry())); |
| 1181 new_entry->SetPageID(params.page_id); | 1182 new_entry->SetPageID(params.page_id); |
| 1182 InsertOrReplaceEntry(new_entry, false); | 1183 InsertOrReplaceEntry(new_entry, false); |
| 1183 } | 1184 } |
| 1184 | 1185 |
| 1185 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe( | 1186 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe( |
| 1186 RenderViewHost* rvh, | 1187 RenderFrameHost* rfh, |
| 1187 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1188 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1188 // We're guaranteed to have a previously committed entry, and we now need to | 1189 // We're guaranteed to have a previously committed entry, and we now need to |
| 1189 // handle navigation inside of a subframe in it without creating a new entry. | 1190 // handle navigation inside of a subframe in it without creating a new entry. |
| 1190 DCHECK(GetLastCommittedEntry()); | 1191 DCHECK(GetLastCommittedEntry()); |
| 1191 | 1192 |
| 1192 // Handle the case where we're navigating back/forward to a previous subframe | 1193 // Handle the case where we're navigating back/forward to a previous subframe |
| 1193 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the | 1194 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the |
| 1194 // header file. In case "1." this will be a NOP. | 1195 // header file. In case "1." this will be a NOP. |
| 1195 int entry_index = GetEntryIndexWithPageID( | 1196 int entry_index = GetEntryIndexWithPageID( |
| 1196 rvh->GetSiteInstance(), | 1197 rfh->GetSiteInstance(), |
| 1197 params.page_id); | 1198 params.page_id); |
| 1198 if (entry_index < 0 || | 1199 if (entry_index < 0 || |
| 1199 entry_index >= static_cast<int>(entries_.size())) { | 1200 entry_index >= static_cast<int>(entries_.size())) { |
| 1200 NOTREACHED(); | 1201 NOTREACHED(); |
| 1201 return false; | 1202 return false; |
| 1202 } | 1203 } |
| 1203 | 1204 |
| 1204 // Update the current navigation entry in case we're going back/forward. | 1205 // Update the current navigation entry in case we're going back/forward. |
| 1205 if (entry_index != last_committed_entry_index_) { | 1206 if (entry_index != last_committed_entry_index_) { |
| 1206 last_committed_entry_index_ = entry_index; | 1207 last_committed_entry_index_ = entry_index; |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1723 } | 1724 } |
| 1724 } | 1725 } |
| 1725 } | 1726 } |
| 1726 | 1727 |
| 1727 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 1728 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
| 1728 const base::Callback<base::Time()>& get_timestamp_callback) { | 1729 const base::Callback<base::Time()>& get_timestamp_callback) { |
| 1729 get_timestamp_callback_ = get_timestamp_callback; | 1730 get_timestamp_callback_ = get_timestamp_callback; |
| 1730 } | 1731 } |
| 1731 | 1732 |
| 1732 } // namespace content | 1733 } // namespace content |
| OLD | NEW |