1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_ 6 #define CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_ 7 8 #include <string> 9 10 #include "base/logging.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/supports_user_data.h" 13 #include "base/time/time.h" 14 #include "content/common/content_export.h" 15 #include "net/http/http_response_info.h" 16 #include "third_party/WebKit/public/web/WebDataSource.h" 17 18 namespace content { 19 20 class NavigationState; 21 22 // The RenderView stores an instance of this class in the "extra data" of each 23 // WebDataSource (see RenderView::DidCreateDataSource). 24 class CONTENT_EXPORT DocumentState NON_EXPORTED_BASE(public blink::WebDataSource::ExtraData)25 : NON_EXPORTED_BASE(public blink::WebDataSource::ExtraData), 26 public base::SupportsUserData { 27 public: 28 // The exact values of this enum are used in histograms, so new values must be 29 // added to the end. 30 enum LoadType { 31 UNDEFINED_LOAD, // Not yet initialized. 32 RELOAD, // User pressed reload. 33 HISTORY_LOAD, // Back or forward. 34 NORMAL_LOAD, // User entered URL, or omnibox search. 35 LINK_LOAD, // (deprecated) Included next 4 categories. 36 LINK_LOAD_NORMAL, // Commonly following of link. 37 LINK_LOAD_RELOAD, // JS/link directed reload. 38 LINK_LOAD_CACHE_STALE_OK, // back/forward or encoding change. 39 LINK_LOAD_CACHE_ONLY, // Allow stale data (avoid doing a re-post) 40 kLoadTypeMax // Bounding value for this enum. 41 }; 42 43 DocumentState(); 44 virtual ~DocumentState(); 45 46 static DocumentState* FromDataSource(blink::WebDataSource* ds) { 47 return static_cast<DocumentState*>(ds->extraData()); 48 } 49 50 // The time that this navigation was requested. 51 const base::Time& request_time() const { 52 return request_time_; 53 } 54 void set_request_time(const base::Time& value) { 55 DCHECK(start_load_time_.is_null()); 56 request_time_ = value; 57 } 58 59 // The time that the document load started. 60 const base::Time& start_load_time() const { 61 return start_load_time_; 62 } 63 void set_start_load_time(const base::Time& value) { 64 // TODO(jar): This should not be set twice. 65 // DCHECK(!start_load_time_.is_null()); 66 DCHECK(finish_document_load_time_.is_null()); 67 start_load_time_ = value; 68 } 69 70 // The time that the document load was committed. 71 const base::Time& commit_load_time() const { 72 return commit_load_time_; 73 } 74 void set_commit_load_time(const base::Time& value) { 75 commit_load_time_ = value; 76 } 77 78 // The time that the document finished loading. 79 const base::Time& finish_document_load_time() const { 80 return finish_document_load_time_; 81 } 82 void set_finish_document_load_time(const base::Time& value) { 83 // TODO(jar): Some unittests break the following DCHECK, and don't have 84 // DCHECK(!start_load_time_.is_null()); 85 DCHECK(!value.is_null()); 86 // TODO(jar): Double setting does happen, but probably shouldn't. 87 // DCHECK(finish_document_load_time_.is_null()); 88 // TODO(jar): We should guarantee this order :-(. 89 // DCHECK(finish_load_time_.is_null()); 90 finish_document_load_time_ = value; 91 } 92 93 // The time that the document and all subresources finished loading. 94 const base::Time& finish_load_time() const { return finish_load_time_; } 95 void set_finish_load_time(const base::Time& value) { 96 DCHECK(!value.is_null()); 97 DCHECK(finish_load_time_.is_null()); 98 // The following is not already set in all cases :-( 99 // DCHECK(!finish_document_load_time_.is_null()); 100 finish_load_time_ = value; 101 } 102 103 // The time that painting first happened after a new navigation. 104 const base::Time& first_paint_time() const { return first_paint_time_; } 105 void set_first_paint_time(const base::Time& value) { 106 first_paint_time_ = value; 107 } 108 109 // The time that painting first happened after the document loaded. 110 const base::Time& first_paint_after_load_time() const { 111 return first_paint_after_load_time_; 112 } 113 void set_first_paint_after_load_time(const base::Time& value) { 114 first_paint_after_load_time_ = value; 115 } 116 117 // True iff the histograms for the associated frame have been dumped. 118 bool load_histograms_recorded() const { return load_histograms_recorded_; } 119 void set_load_histograms_recorded(bool value) { 120 load_histograms_recorded_ = value; 121 } 122 123 bool web_timing_histograms_recorded() const { 124 return web_timing_histograms_recorded_; 125 } 126 void set_web_timing_histograms_recorded(bool value) { 127 web_timing_histograms_recorded_ = value; 128 } 129 130 // Indicator if SPDY was used as part of this page load. 131 bool was_fetched_via_spdy() const { return was_fetched_via_spdy_; } 132 void set_was_fetched_via_spdy(bool value) { was_fetched_via_spdy_ = value; } 133 134 bool was_npn_negotiated() const { return was_npn_negotiated_; } 135 void set_was_npn_negotiated(bool value) { was_npn_negotiated_ = value; } 136 137 const std::string& npn_negotiated_protocol() const { 138 return npn_negotiated_protocol_; 139 } 140 void set_npn_negotiated_protocol(const std::string& value) { 141 npn_negotiated_protocol_ = value; 142 } 143 144 bool was_alternate_protocol_available() const { 145 return was_alternate_protocol_available_; 146 } 147 void set_was_alternate_protocol_available(bool value) { 148 was_alternate_protocol_available_ = value; 149 } 150 151 net::HttpResponseInfo::ConnectionInfo connection_info() const { 152 return connection_info_; 153 } 154 void set_connection_info( 155 net::HttpResponseInfo::ConnectionInfo connection_info) { 156 connection_info_ = connection_info; 157 } 158 159 bool was_fetched_via_proxy() const { return was_fetched_via_proxy_; } 160 void set_was_fetched_via_proxy(bool value) { 161 was_fetched_via_proxy_ = value; 162 } 163 164 void set_was_prefetcher(bool value) { was_prefetcher_ = value; } 165 bool was_prefetcher() const { return was_prefetcher_; } 166 167 void set_was_referred_by_prefetcher(bool value) { 168 was_referred_by_prefetcher_ = value; 169 } 170 bool was_referred_by_prefetcher() const { 171 return was_referred_by_prefetcher_; 172 } 173 174 void set_was_after_preconnect_request(bool value) { 175 was_after_preconnect_request_ = value; 176 } 177 bool was_after_preconnect_request() { return was_after_preconnect_request_; } 178 179 // Record the nature of this load, for use when histogramming page load times. 180 LoadType load_type() const { return load_type_; } 181 void set_load_type(LoadType load_type) { load_type_ = load_type; } 182 183 NavigationState* navigation_state() { return navigation_state_.get(); } 184 void set_navigation_state(NavigationState* navigation_state); 185 186 bool can_load_local_resources() const { return can_load_local_resources_; } 187 void set_can_load_local_resources(bool can_load) { 188 can_load_local_resources_ = can_load; 189 } 190 191 private: 192 base::Time request_time_; 193 base::Time start_load_time_; 194 base::Time commit_load_time_; 195 base::Time finish_document_load_time_; 196 base::Time finish_load_time_; 197 base::Time first_paint_time_; 198 base::Time first_paint_after_load_time_; 199 bool load_histograms_recorded_; 200 bool web_timing_histograms_recorded_; 201 bool was_fetched_via_spdy_; 202 bool was_npn_negotiated_; 203 std::string npn_negotiated_protocol_; 204 bool was_alternate_protocol_available_; 205 net::HttpResponseInfo::ConnectionInfo connection_info_; 206 bool was_fetched_via_proxy_; 207 208 // A prefetcher is a page that contains link rel=prefetch elements. 209 bool was_prefetcher_; 210 bool was_referred_by_prefetcher_; 211 bool was_after_preconnect_request_; 212 213 LoadType load_type_; 214 215 scoped_ptr<NavigationState> navigation_state_; 216 217 bool can_load_local_resources_; 218 }; 219 220 #endif // CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_ 221 222 } // namespace content 223