Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: content/browser/frame_host/navigation_controller_impl.cc

Issue 1002803002: Classify navigations without page id in parallel to the existing classifier. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: unit tests Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 // If we are doing a cross-site reload, we need to replace the existing 794 // If we are doing a cross-site reload, we need to replace the existing
795 // navigation entry, not add another entry to the history. This has the side 795 // navigation entry, not add another entry to the history. This has the side
796 // effect of removing forward browsing history, if such existed. 796 // effect of removing forward browsing history, if such existed.
797 // Or if we are doing a cross-site redirect navigation, 797 // Or if we are doing a cross-site redirect navigation,
798 // we will do a similar thing. 798 // we will do a similar thing.
799 details->did_replace_entry = 799 details->did_replace_entry =
800 pending_entry_ && pending_entry_->should_replace_entry(); 800 pending_entry_ && pending_entry_->should_replace_entry();
801 801
802 // Do navigation-type specific actions. These will make and commit an entry. 802 // Do navigation-type specific actions. These will make and commit an entry.
803 details->type = ClassifyNavigation(rfh, params); 803 details->type = ClassifyNavigation(rfh, params);
804 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
805 switches::kSitePerProcess)) {
806 // For site-per-process, both ClassifyNavigation methods get it wrong (see
807 // http://crbug.com/464014) so don't worry about a mismatch if that's the
808 // case.
809 auto nt = [](NavigationType type) {
810 switch(type) {
811 case NAVIGATION_TYPE_UNKNOWN:
812 return "UNKNOWN";
813 case NAVIGATION_TYPE_NEW_PAGE:
814 return "NEW_PAGE";
815 case NAVIGATION_TYPE_EXISTING_PAGE:
816 return "EXISTING_PAGE";
817 case NAVIGATION_TYPE_SAME_PAGE:
818 return "SAME_PAGE";
819 case NAVIGATION_TYPE_IN_PAGE:
820 return "IN_PAGE";
821 case NAVIGATION_TYPE_NEW_SUBFRAME:
822 return "NEW_SUBFRAME";
823 case NAVIGATION_TYPE_AUTO_SUBFRAME:
824 return "AUTO_SUBFRAME";
825 case NAVIGATION_TYPE_NAV_IGNORE:
826 return "NAV_IGNORE";
827 default:
828 return "<invalid>";
829 }
830 };
831 NavigationType new_type = ClassifyNavigationWithoutPageID(rfh, params);
832 if (details->type != new_type) {
833 LOG(FATAL) << "old classify is " << nt(details->type)
834 << ", new classify is " << nt(new_type);
835 }
836 // Detailed logging above is temporary; will ship with vvvv below.
837 // DCHECK_EQ(details->type, ClassifyNavigationWithoutPageID(rfh, params));
838 }
804 839
805 // is_in_page must be computed before the entry gets committed. 840 // is_in_page must be computed before the entry gets committed.
806 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(), 841 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(),
807 params.url, params.was_within_same_page, rfh); 842 params.url, params.was_within_same_page, rfh);
808 843
809 switch (details->type) { 844 switch (details->type) {
810 case NAVIGATION_TYPE_NEW_PAGE: 845 case NAVIGATION_TYPE_NEW_PAGE:
811 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); 846 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry);
812 break; 847 break;
813 case NAVIGATION_TYPE_EXISTING_PAGE: 848 case NAVIGATION_TYPE_EXISTING_PAGE:
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 details->serialized_security_info = params.security_info; 927 details->serialized_security_info = params.security_info;
893 details->http_status_code = params.http_status_code; 928 details->http_status_code = params.http_status_code;
894 NotifyNavigationEntryCommitted(details); 929 NotifyNavigationEntryCommitted(details);
895 930
896 return true; 931 return true;
897 } 932 }
898 933
899 NavigationType NavigationControllerImpl::ClassifyNavigation( 934 NavigationType NavigationControllerImpl::ClassifyNavigation(
900 RenderFrameHostImpl* rfh, 935 RenderFrameHostImpl* rfh,
901 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { 936 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const {
937 LOG(ERROR) << "NavigationControllerImpl::ClassifyNavigation";
902 if (params.page_id == -1) { 938 if (params.page_id == -1) {
903 // TODO(nasko, creis): An out-of-process child frame has no way of 939 // TODO(nasko, creis): An out-of-process child frame has no way of knowing
904 // knowing the page_id of its parent, so it is passing back -1. The 940 // the page_id of its parent, so it is passing back -1. The semantics here
905 // semantics here should be re-evaluated during session history refactor 941 // should be re-evaluated during session history refactor (see
906 // (see http://crbug.com/236848). For now, we assume this means the 942 // http://crbug.com/236848 and in particular http://crbug.com/464014). For
907 // child frame loaded and proceed. Note that this may do the wrong thing 943 // now, we assume this means the child frame loaded and proceed. Note that
908 // for cross-process AUTO_SUBFRAME navigations. 944 // this may do the wrong thing for cross-process AUTO_SUBFRAME navigations.
909 if (rfh->IsCrossProcessSubframe()) 945 if (rfh->IsCrossProcessSubframe())
910 return NAVIGATION_TYPE_NEW_SUBFRAME; 946 return NAVIGATION_TYPE_NEW_SUBFRAME;
911 947
912 // The renderer generates the page IDs, and so if it gives us the invalid 948 // The renderer generates the page IDs, and so if it gives us the invalid
913 // page ID (-1) we know it didn't actually navigate. This happens in a few 949 // page ID (-1) we know it didn't actually navigate. This happens in a few
914 // cases: 950 // cases:
915 // 951 //
916 // - If a page makes a popup navigated to about blank, and then writes 952 // - If a page makes a popup navigated to about blank, and then writes
917 // stuff like a subframe navigated to a real page. We'll get the commit 953 // stuff like a subframe navigated to a real page. We'll get the commit
918 // for the subframe, but there won't be any commit for the outer page. 954 // for the subframe, but there won't be any commit for the outer page.
919 // 955 //
920 // - We were also getting these for failed loads (for example, bug 21849). 956 // - We were also getting these for failed loads (for example, bug 21849).
921 // The guess is that we get a "load commit" for the alternate error page, 957 // The guess is that we get a "load commit" for the alternate error page,
922 // but that doesn't affect the page ID, so we get the "old" one, which 958 // but that doesn't affect the page ID, so we get the "old" one, which
923 // could be invalid. This can also happen for a cross-site transition 959 // could be invalid. This can also happen for a cross-site transition
924 // that causes us to swap processes. Then the error page load will be in 960 // that causes us to swap processes. Then the error page load will be in
925 // a new process with no page IDs ever assigned (and hence a -1 value), 961 // a new process with no page IDs ever assigned (and hence a -1 value),
926 // yet the navigation controller still might have previous pages in its 962 // yet the navigation controller still might have previous pages in its
927 // list. 963 // list.
928 // 964 //
929 // In these cases, there's nothing we can do with them, so ignore. 965 // In these cases, there's nothing we can do with them, so ignore.
966 LOG(ERROR) << " > page id is -1; ignoring";
930 return NAVIGATION_TYPE_NAV_IGNORE; 967 return NAVIGATION_TYPE_NAV_IGNORE;
931 } 968 }
932 969
933 if (params.page_id > delegate_->GetMaxPageIDForSiteInstance( 970 if (params.page_id > delegate_->GetMaxPageIDForSiteInstance(
934 rfh->GetSiteInstance())) { 971 rfh->GetSiteInstance())) {
972 LOG(ERROR) << "larger page id (" << params.page_id << ") than we've seen bef ore (" << delegate_->GetMaxPageIDForSiteInstance(rfh->GetSiteInstance()) << ")";
935 // Greater page IDs than we've ever seen before are new pages. We may or may 973 // Greater page IDs than we've ever seen before are new pages. We may or may
936 // not have a pending entry for the page, and this may or may not be the 974 // not have a pending entry for the page, and this may or may not be the
937 // main frame. 975 // main frame.
938 if (ui::PageTransitionIsMainFrame(params.transition)) 976 if (ui::PageTransitionIsMainFrame(params.transition))
939 return NAVIGATION_TYPE_NEW_PAGE; 977 return NAVIGATION_TYPE_NEW_PAGE;
940 978
941 // When this is a new subframe navigation, we should have a committed page 979 // When this is a new subframe navigation, we should have a committed page
942 // for which it's a suframe in. This may not be the case when an iframe is 980 // for which it's a suframe in. This may not be the case when an iframe is
943 // navigated on a popup navigated to about:blank (the iframe would be 981 // navigated on a popup navigated to about:blank (the iframe would be
944 // written into the popup by script on the main page). For these cases, 982 // written into the popup by script on the main page). For these cases,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 temp.append("x"); 1031 temp.append("x");
994 temp.append(","); 1032 temp.append(",");
995 } 1033 }
996 GURL url(temp); 1034 GURL url(temp);
997 rfh->render_view_host()->Send(new ViewMsg_TempCrashWithData(url)); 1035 rfh->render_view_host()->Send(new ViewMsg_TempCrashWithData(url));
998 return NAVIGATION_TYPE_NAV_IGNORE; 1036 return NAVIGATION_TYPE_NAV_IGNORE;
999 } 1037 }
1000 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get(); 1038 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get();
1001 1039
1002 if (!ui::PageTransitionIsMainFrame(params.transition)) { 1040 if (!ui::PageTransitionIsMainFrame(params.transition)) {
1041 LOG(ERROR) << " > subframe transition; so it's auto";
1003 // All manual subframes would get new IDs and were handled above, so we 1042 // All manual subframes would get new IDs and were handled above, so we
1004 // know this is auto. Since the current page was found in the navigation 1043 // know this is auto. Since the current page was found in the navigation
1005 // entry list, we're guaranteed to have a last committed entry. 1044 // entry list, we're guaranteed to have a last committed entry.
1006 DCHECK(GetLastCommittedEntry()); 1045 DCHECK(GetLastCommittedEntry());
1007 return NAVIGATION_TYPE_AUTO_SUBFRAME; 1046 return NAVIGATION_TYPE_AUTO_SUBFRAME;
1008 } 1047 }
1009 1048
1010 // Anything below here we know is a main frame navigation. 1049 // Anything below here we know is a main frame navigation.
1011 if (pending_entry_ && 1050 if (pending_entry_ &&
1012 !pending_entry_->is_renderer_initiated() && 1051 !pending_entry_->is_renderer_initiated() &&
1013 existing_entry != pending_entry_ && 1052 existing_entry != pending_entry_ &&
1014 pending_entry_->GetPageID() == -1 && 1053 pending_entry_->GetPageID() == -1 &&
1015 existing_entry == GetLastCommittedEntry()) { 1054 existing_entry == GetLastCommittedEntry()) {
1055 LOG(ERROR) << " > same page";
1016 // In this case, we have a pending entry for a URL but WebCore didn't do a 1056 // In this case, we have a pending entry for a URL but WebCore didn't do a
1017 // new navigation. This happens when you press enter in the URL bar to 1057 // new navigation. This happens when you press enter in the URL bar to
1018 // reload. We will create a pending entry, but WebKit will convert it to 1058 // reload. We will create a pending entry, but WebKit will convert it to
1019 // a reload since it's the same page and not create a new entry for it 1059 // a reload since it's the same page and not create a new entry for it
1020 // (the user doesn't want to have a new back/forward entry when they do 1060 // (the user doesn't want to have a new back/forward entry when they do
1021 // this). If this matches the last committed entry, we want to just ignore 1061 // this). If this matches the last committed entry, we want to just ignore
1022 // the pending entry and go back to where we were (the "existing entry"). 1062 // the pending entry and go back to where we were (the "existing entry").
1023 return NAVIGATION_TYPE_SAME_PAGE; 1063 return NAVIGATION_TYPE_SAME_PAGE;
1024 } 1064 }
1025 1065
1026 // Any toplevel navigations with the same base (minus the reference fragment) 1066 // Any toplevel navigations with the same base (minus the reference fragment)
1027 // are in-page navigations. We weeded out subframe navigations above. Most of 1067 // are in-page navigations. We weeded out subframe navigations above. Most of
1028 // the time this doesn't matter since WebKit doesn't tell us about subframe 1068 // the time this doesn't matter since WebKit doesn't tell us about subframe
1029 // navigations that don't actually navigate, but it can happen when there is 1069 // navigations that don't actually navigate, but it can happen when there is
1030 // an encoding override (it always sends a navigation request). 1070 // an encoding override (it always sends a navigation request).
1031 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url, 1071 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url,
1032 params.was_within_same_page, rfh)) { 1072 params.was_within_same_page, rfh)) {
1073 LOG(ERROR) << " > in page";
1074 return NAVIGATION_TYPE_IN_PAGE;
1075 }
1076
1077 // Since we weeded out "new" navigations above, we know this is an existing
1078 // (back/forward) navigation.
1079 LOG(ERROR) << " > existing page";
1080 return NAVIGATION_TYPE_EXISTING_PAGE;
1081 }
1082
1083 NavigationType NavigationControllerImpl::ClassifyNavigationWithoutPageID(
1084 RenderFrameHostImpl* rfh,
1085 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const {
1086 LOG(ERROR) << "NavigationControllerImpl::ClassifyNavigationWithoutPageID"
1087 << " nav_entry_id " << params.nav_entry_id;
1088 if (params.did_create_new_entry) {
1089 // A new entry. We may or may not have a pending entry for the page, and
1090 // this may or may not be the main frame.
1091 if (!rfh->GetParent()) {
1092 // TODO(avi): Everyone does ui::PageTransitionIsMainFrame to determine
1093 // main-frame-ness. I can get that consumers of page transitions would
1094 // want to do that, but for code inside RenderFrameHost and NavController?
1095 // Please.
1096 return NAVIGATION_TYPE_NEW_PAGE;
1097 }
1098
1099 // When this is a new subframe navigation, we should have a committed page
1100 // in which it's a subframe. This may not be the case when an iframe is
1101 // navigated on a popup navigated to about:blank (the iframe would be
1102 // written into the popup by script on the main page). For these cases,
1103 // there isn't any navigation stuff we can do, so just ignore it.
1104 if (!GetLastCommittedEntry())
1105 return NAVIGATION_TYPE_NAV_IGNORE;
1106
1107 // Valid subframe navigation.
1108 return NAVIGATION_TYPE_NEW_SUBFRAME;
1109 }
1110
1111 // We only clear the session history when navigating to a new page.
1112 DCHECK(!params.history_list_was_cleared);
1113
1114 if (rfh->GetParent()) {
1115 // All manual subframes would be WebStandardCommit and handled above, so we
1116 // know this is auto.
1117 DCHECK(GetLastCommittedEntry());
1118 return NAVIGATION_TYPE_AUTO_SUBFRAME;
1119 }
1120
1121 if (params.nav_entry_id == 0) {
1122 // Just like above in the did_create_new_entry case, it's possible to
1123 // scribble onto an uncommitted page. Again, there isn't any navigation
1124 // stuff that we can do, so ignore it here as well.
1125 if (!GetLastCommittedEntry())
1126 return NAVIGATION_TYPE_NAV_IGNORE;
1127
1128 // This is a renderer-initiated navigation, but didn't create a new page.
1129 if (params.was_within_same_page) {
1130 // This is history.replaceState(), which is renderer-initiated yet within
1131 // the same page.
1132 return NAVIGATION_TYPE_IN_PAGE;
1133 } else {
1134 // This is history.reload() and client-side redirection.
1135 return NAVIGATION_TYPE_EXISTING_PAGE;
1136 }
1137 }
1138
1139 if (pending_entry_ && pending_entry_index_ == -1 &&
1140 pending_entry_->GetUniqueID() == params.nav_entry_id) {
1141 // In this case, we have a pending entry for a load of a new URL but Blink
1142 // didn't do a new navigation (params.did_create_new_entry). This happens
1143 // when you press enter in the URL bar to reload. We will create a pending
1144 // entry, but Blink will convert it to a reload since it's the same page and
1145 // not create a new entry for it (the user doesn't want to have a new
1146 // back/forward entry when they do this). Therefore we want to just ignore
1147 // the pending entry and go back to where we were (the "existing entry").
1148 return NAVIGATION_TYPE_SAME_PAGE;
1149 }
1150
1151 // Now we know that the notification is for an existing page. Find that entry.
1152 int existing_entry_index = GetEntryIndexWithUniqueID(params.nav_entry_id);
1153 if (existing_entry_index == -1) {
1154 // The page was not found. It could have been pruned because of the limit on
1155 // back/forward entries (not likely since we'll usually tell it to navigate
1156 // to such entries). It could also mean that the renderer is smoking crack.
1157 NOTREACHED() << "Could not find nav entry with id " << params.nav_entry_id;
1158 return NAVIGATION_TYPE_NAV_IGNORE;
1159 }
1160
1161 // Any top-level navigations with the same base (minus the reference fragment)
1162 // are in-page navigations. (We weeded out subframe navigations above.) Most
1163 // of the time this doesn't matter since Blink doesn't tell us about subframe
1164 // navigations that don't actually navigate, but it can happen when there is
1165 // an encoding override (it always sends a navigation request).
1166 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get();
1167 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url,
1168 params.was_within_same_page, rfh)) {
1033 return NAVIGATION_TYPE_IN_PAGE; 1169 return NAVIGATION_TYPE_IN_PAGE;
1034 } 1170 }
1035 1171
1036 // Since we weeded out "new" navigations above, we know this is an existing 1172 // Since we weeded out "new" navigations above, we know this is an existing
1037 // (back/forward) navigation. 1173 // (back/forward) navigation.
1038 return NAVIGATION_TYPE_EXISTING_PAGE; 1174 return NAVIGATION_TYPE_EXISTING_PAGE;
1039 } 1175 }
1040 1176
1041 void NavigationControllerImpl::RendererDidNavigateToNewPage( 1177 void NavigationControllerImpl::RendererDidNavigateToNewPage(
1042 RenderFrameHostImpl* rfh, 1178 RenderFrameHostImpl* rfh,
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 NavigationEntryImpl* NavigationControllerImpl::GetPendingEntry() const { 1694 NavigationEntryImpl* NavigationControllerImpl::GetPendingEntry() const {
1559 return pending_entry_; 1695 return pending_entry_;
1560 } 1696 }
1561 1697
1562 int NavigationControllerImpl::GetPendingEntryIndex() const { 1698 int NavigationControllerImpl::GetPendingEntryIndex() const {
1563 return pending_entry_index_; 1699 return pending_entry_index_;
1564 } 1700 }
1565 1701
1566 void NavigationControllerImpl::InsertOrReplaceEntry(NavigationEntryImpl* entry, 1702 void NavigationControllerImpl::InsertOrReplaceEntry(NavigationEntryImpl* entry,
1567 bool replace) { 1703 bool replace) {
1704 LOG(ERROR) << "NavigationControllerImpl::InsertOrReplaceEntry";
1568 DCHECK(entry->GetTransitionType() != ui::PAGE_TRANSITION_AUTO_SUBFRAME); 1705 DCHECK(entry->GetTransitionType() != ui::PAGE_TRANSITION_AUTO_SUBFRAME);
1569 1706
1570 // Copy the pending entry's unique ID to the committed entry. 1707 // Copy the pending entry's unique ID to the committed entry.
1571 // I don't know if pending_entry_index_ can be other than -1 here. 1708 // I don't know if pending_entry_index_ can be other than -1 here.
1572 const NavigationEntryImpl* const pending_entry = 1709 const NavigationEntryImpl* const pending_entry =
1573 (pending_entry_index_ == -1) ? 1710 (pending_entry_index_ == -1) ?
1574 pending_entry_ : entries_[pending_entry_index_].get(); 1711 pending_entry_ : entries_[pending_entry_index_].get();
1575 if (pending_entry) 1712 if (pending_entry)
1576 entry->set_unique_id(pending_entry->GetUniqueID()); 1713 entry->set_unique_id(pending_entry->GetUniqueID());
1577 1714
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 int NavigationControllerImpl::GetEntryIndexWithPageID( 1909 int NavigationControllerImpl::GetEntryIndexWithPageID(
1773 SiteInstance* instance, int32 page_id) const { 1910 SiteInstance* instance, int32 page_id) const {
1774 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) { 1911 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) {
1775 if ((entries_[i]->site_instance() == instance) && 1912 if ((entries_[i]->site_instance() == instance) &&
1776 (entries_[i]->GetPageID() == page_id)) 1913 (entries_[i]->GetPageID() == page_id))
1777 return i; 1914 return i;
1778 } 1915 }
1779 return -1; 1916 return -1;
1780 } 1917 }
1781 1918
1919 int NavigationControllerImpl::GetEntryIndexWithUniqueID(
1920 int nav_entry_id) const {
1921 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) {
1922 if (entries_[i]->GetUniqueID() == nav_entry_id)
1923 return i;
1924 }
1925 return -1;
1926 }
1927
1782 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const { 1928 NavigationEntryImpl* NavigationControllerImpl::GetTransientEntry() const {
1783 if (transient_entry_index_ == -1) 1929 if (transient_entry_index_ == -1)
1784 return NULL; 1930 return NULL;
1785 return entries_[transient_entry_index_].get(); 1931 return entries_[transient_entry_index_].get();
1786 } 1932 }
1787 1933
1788 void NavigationControllerImpl::SetTransientEntry(NavigationEntry* entry) { 1934 void NavigationControllerImpl::SetTransientEntry(NavigationEntry* entry) {
1789 // Discard any current transient entry, we can only have one at a time. 1935 // Discard any current transient entry, we can only have one at a time.
1790 int index = 0; 1936 int index = 0;
1791 if (last_committed_entry_index_ != -1) 1937 if (last_committed_entry_index_ != -1)
(...skipping 23 matching lines...) Expand all
1815 } 1961 }
1816 } 1962 }
1817 } 1963 }
1818 1964
1819 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 1965 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
1820 const base::Callback<base::Time()>& get_timestamp_callback) { 1966 const base::Callback<base::Time()>& get_timestamp_callback) {
1821 get_timestamp_callback_ = get_timestamp_callback; 1967 get_timestamp_callback_ = get_timestamp_callback;
1822 } 1968 }
1823 1969
1824 } // namespace content 1970 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698