// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_ #define CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_ #include <string> #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/supports_user_data.h" #include "base/time/time.h" #include "content/common/content_export.h" #include "net/http/http_response_info.h" #include "third_party/WebKit/public/web/WebDataSource.h" namespace content { class NavigationState; // The RenderView stores an instance of this class in the "extra data" of each // WebDataSource (see RenderView::DidCreateDataSource). class CONTENT_EXPORT DocumentState : NON_EXPORTED_BASE(public blink::WebDataSource::ExtraData), public base::SupportsUserData { public: // The exact values of this enum are used in histograms, so new values must be // added to the end. enum LoadType { UNDEFINED_LOAD, // Not yet initialized. RELOAD, // User pressed reload. HISTORY_LOAD, // Back or forward. NORMAL_LOAD, // User entered URL, or omnibox search. LINK_LOAD, // (deprecated) Included next 4 categories. LINK_LOAD_NORMAL, // Commonly following of link. LINK_LOAD_RELOAD, // JS/link directed reload. LINK_LOAD_CACHE_STALE_OK, // back/forward or encoding change. LINK_LOAD_CACHE_ONLY, // Allow stale data (avoid doing a re-post) kLoadTypeMax // Bounding value for this enum. }; DocumentState(); virtual ~DocumentState(); static DocumentState* FromDataSource(blink::WebDataSource* ds) { return static_cast<DocumentState*>(ds->extraData()); } // The time that this navigation was requested. const base::Time& request_time() const { return request_time_; } void set_request_time(const base::Time& value) { DCHECK(start_load_time_.is_null()); request_time_ = value; } // The time that the document load started. const base::Time& start_load_time() const { return start_load_time_; } void set_start_load_time(const base::Time& value) { // TODO(jar): This should not be set twice. // DCHECK(!start_load_time_.is_null()); DCHECK(finish_document_load_time_.is_null()); start_load_time_ = value; } // The time that the document load was committed. const base::Time& commit_load_time() const { return commit_load_time_; } void set_commit_load_time(const base::Time& value) { commit_load_time_ = value; } // The time that the document finished loading. const base::Time& finish_document_load_time() const { return finish_document_load_time_; } void set_finish_document_load_time(const base::Time& value) { // TODO(jar): Some unittests break the following DCHECK, and don't have // DCHECK(!start_load_time_.is_null()); DCHECK(!value.is_null()); // TODO(jar): Double setting does happen, but probably shouldn't. // DCHECK(finish_document_load_time_.is_null()); // TODO(jar): We should guarantee this order :-(. // DCHECK(finish_load_time_.is_null()); finish_document_load_time_ = value; } // The time that the document and all subresources finished loading. const base::Time& finish_load_time() const { return finish_load_time_; } void set_finish_load_time(const base::Time& value) { DCHECK(!value.is_null()); DCHECK(finish_load_time_.is_null()); // The following is not already set in all cases :-( // DCHECK(!finish_document_load_time_.is_null()); finish_load_time_ = value; } // The time that painting first happened after a new navigation. const base::Time& first_paint_time() const { return first_paint_time_; } void set_first_paint_time(const base::Time& value) { first_paint_time_ = value; } // The time that painting first happened after the document loaded. const base::Time& first_paint_after_load_time() const { return first_paint_after_load_time_; } void set_first_paint_after_load_time(const base::Time& value) { first_paint_after_load_time_ = value; } // True iff the histograms for the associated frame have been dumped. bool load_histograms_recorded() const { return load_histograms_recorded_; } void set_load_histograms_recorded(bool value) { load_histograms_recorded_ = value; } bool web_timing_histograms_recorded() const { return web_timing_histograms_recorded_; } void set_web_timing_histograms_recorded(bool value) { web_timing_histograms_recorded_ = value; } // Indicator if SPDY was used as part of this page load. bool was_fetched_via_spdy() const { return was_fetched_via_spdy_; } void set_was_fetched_via_spdy(bool value) { was_fetched_via_spdy_ = value; } bool was_npn_negotiated() const { return was_npn_negotiated_; } void set_was_npn_negotiated(bool value) { was_npn_negotiated_ = value; } const std::string& npn_negotiated_protocol() const { return npn_negotiated_protocol_; } void set_npn_negotiated_protocol(const std::string& value) { npn_negotiated_protocol_ = value; } bool was_alternate_protocol_available() const { return was_alternate_protocol_available_; } void set_was_alternate_protocol_available(bool value) { was_alternate_protocol_available_ = value; } net::HttpResponseInfo::ConnectionInfo connection_info() const { return connection_info_; } void set_connection_info( net::HttpResponseInfo::ConnectionInfo connection_info) { connection_info_ = connection_info; } bool was_fetched_via_proxy() const { return was_fetched_via_proxy_; } void set_was_fetched_via_proxy(bool value) { was_fetched_via_proxy_ = value; } void set_was_prefetcher(bool value) { was_prefetcher_ = value; } bool was_prefetcher() const { return was_prefetcher_; } void set_was_referred_by_prefetcher(bool value) { was_referred_by_prefetcher_ = value; } bool was_referred_by_prefetcher() const { return was_referred_by_prefetcher_; } void set_was_after_preconnect_request(bool value) { was_after_preconnect_request_ = value; } bool was_after_preconnect_request() { return was_after_preconnect_request_; } // Record the nature of this load, for use when histogramming page load times. LoadType load_type() const { return load_type_; } void set_load_type(LoadType load_type) { load_type_ = load_type; } NavigationState* navigation_state() { return navigation_state_.get(); } void set_navigation_state(NavigationState* navigation_state); bool can_load_local_resources() const { return can_load_local_resources_; } void set_can_load_local_resources(bool can_load) { can_load_local_resources_ = can_load; } private: base::Time request_time_; base::Time start_load_time_; base::Time commit_load_time_; base::Time finish_document_load_time_; base::Time finish_load_time_; base::Time first_paint_time_; base::Time first_paint_after_load_time_; bool load_histograms_recorded_; bool web_timing_histograms_recorded_; bool was_fetched_via_spdy_; bool was_npn_negotiated_; std::string npn_negotiated_protocol_; bool was_alternate_protocol_available_; net::HttpResponseInfo::ConnectionInfo connection_info_; bool was_fetched_via_proxy_; // A prefetcher is a page that contains link rel=prefetch elements. bool was_prefetcher_; bool was_referred_by_prefetcher_; bool was_after_preconnect_request_; LoadType load_type_; scoped_ptr<NavigationState> navigation_state_; bool can_load_local_resources_; }; #endif // CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_ } // namespace content