Home | History | Annotate | Download | only in renderer
      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 struct PasswordForm;
     22 
     23 // The RenderView stores an instance of this class in the "extra data" of each
     24 // WebDataSource (see RenderView::DidCreateDataSource).
     25 class CONTENT_EXPORT DocumentState
     26     : NON_EXPORTED_BASE(public WebKit::WebDataSource::ExtraData),
     27       public base::SupportsUserData {
     28  public:
     29   // The exact values of this enum are used in histograms, so new values must be
     30   // added to the end.
     31   enum LoadType {
     32     UNDEFINED_LOAD,            // Not yet initialized.
     33     RELOAD,                    // User pressed reload.
     34     HISTORY_LOAD,              // Back or forward.
     35     NORMAL_LOAD,               // User entered URL, or omnibox search.
     36     LINK_LOAD,                 // (deprecated) Included next 4 categories.
     37     LINK_LOAD_NORMAL,          // Commonly following of link.
     38     LINK_LOAD_RELOAD,          // JS/link directed reload.
     39     LINK_LOAD_CACHE_STALE_OK,  // back/forward or encoding change.
     40     LINK_LOAD_CACHE_ONLY,      // Allow stale data (avoid doing a re-post)
     41     kLoadTypeMax               // Bounding value for this enum.
     42   };
     43 
     44   DocumentState();
     45   virtual ~DocumentState();
     46 
     47   static DocumentState* FromDataSource(WebKit::WebDataSource* ds) {
     48     return static_cast<DocumentState*>(ds->extraData());
     49   }
     50 
     51   // The time that this navigation was requested.
     52   const base::Time& request_time() const {
     53     return request_time_;
     54   }
     55   void set_request_time(const base::Time& value) {
     56     DCHECK(start_load_time_.is_null());
     57     request_time_ = value;
     58   }
     59 
     60   // The time that the document load started.
     61   const base::Time& start_load_time() const {
     62     return start_load_time_;
     63   }
     64   void set_start_load_time(const base::Time& value) {
     65     // TODO(jar): This should not be set twice.
     66     // DCHECK(!start_load_time_.is_null());
     67     DCHECK(finish_document_load_time_.is_null());
     68     start_load_time_ = value;
     69   }
     70 
     71   // The time that the document load was committed.
     72   const base::Time& commit_load_time() const {
     73     return commit_load_time_;
     74   }
     75   void set_commit_load_time(const base::Time& value) {
     76     commit_load_time_ = value;
     77   }
     78 
     79   // The time that the document finished loading.
     80   const base::Time& finish_document_load_time() const {
     81     return finish_document_load_time_;
     82   }
     83   void set_finish_document_load_time(const base::Time& value) {
     84     // TODO(jar): Some unittests break the following DCHECK, and don't have
     85     // DCHECK(!start_load_time_.is_null());
     86     DCHECK(!value.is_null());
     87     // TODO(jar): Double setting does happen, but probably shouldn't.
     88     // DCHECK(finish_document_load_time_.is_null());
     89     // TODO(jar): We should guarantee this order :-(.
     90     // DCHECK(finish_load_time_.is_null());
     91     finish_document_load_time_ = value;
     92   }
     93 
     94   // The time that the document and all subresources finished loading.
     95   const base::Time& finish_load_time() const { return finish_load_time_; }
     96   void set_finish_load_time(const base::Time& value) {
     97     DCHECK(!value.is_null());
     98     DCHECK(finish_load_time_.is_null());
     99     // The following is not already set in all cases :-(
    100     // DCHECK(!finish_document_load_time_.is_null());
    101     finish_load_time_ = value;
    102   }
    103 
    104   // The time that painting first happened after a new navigation.
    105   const base::Time& first_paint_time() const { return first_paint_time_; }
    106   void set_first_paint_time(const base::Time& value) {
    107     first_paint_time_ = value;
    108   }
    109 
    110   // The time that painting first happened after the document loaded.
    111   const base::Time& first_paint_after_load_time() const {
    112     return first_paint_after_load_time_;
    113   }
    114   void set_first_paint_after_load_time(const base::Time& value) {
    115     first_paint_after_load_time_ = value;
    116   }
    117 
    118   // True iff the histograms for the associated frame have been dumped.
    119   bool load_histograms_recorded() const { return load_histograms_recorded_; }
    120   void set_load_histograms_recorded(bool value) {
    121     load_histograms_recorded_ = value;
    122   }
    123 
    124   bool web_timing_histograms_recorded() const {
    125     return web_timing_histograms_recorded_;
    126   }
    127   void set_web_timing_histograms_recorded(bool value) {
    128     web_timing_histograms_recorded_ = value;
    129   }
    130 
    131   // Indicator if SPDY was used as part of this page load.
    132   bool was_fetched_via_spdy() const { return was_fetched_via_spdy_; }
    133   void set_was_fetched_via_spdy(bool value) { was_fetched_via_spdy_ = value; }
    134 
    135   bool was_npn_negotiated() const { return was_npn_negotiated_; }
    136   void set_was_npn_negotiated(bool value) { was_npn_negotiated_ = value; }
    137 
    138   const std::string& npn_negotiated_protocol() const {
    139     return npn_negotiated_protocol_;
    140   }
    141   void set_npn_negotiated_protocol(const std::string& value) {
    142     npn_negotiated_protocol_ = value;
    143   }
    144 
    145   bool was_alternate_protocol_available() const {
    146     return was_alternate_protocol_available_;
    147   }
    148   void set_was_alternate_protocol_available(bool value) {
    149     was_alternate_protocol_available_ = value;
    150   }
    151 
    152   net::HttpResponseInfo::ConnectionInfo connection_info() const {
    153     return connection_info_;
    154   }
    155   void set_connection_info(
    156       net::HttpResponseInfo::ConnectionInfo connection_info) {
    157     connection_info_ = connection_info;
    158   }
    159 
    160   bool was_fetched_via_proxy() const { return was_fetched_via_proxy_; }
    161   void set_was_fetched_via_proxy(bool value) {
    162     was_fetched_via_proxy_ = value;
    163   }
    164 
    165   // If set, contains the PasswordForm that we believe triggered the current
    166   // navigation (there is some ambiguity in the case of javascript initiated
    167   // navigations). This information is used by the PasswordManager to determine
    168   // if the user should be prompted to save their password.
    169   //
    170   // Note that setting this field doesn't affect where the data is sent or what
    171   // origin we associate it with, only whether we prompt the user to save it.
    172   // That is, a false positive is a usability issue (e.g. may try to save a
    173   // mis-typed password) not a security issue.
    174   PasswordForm* password_form_data() const {
    175     return password_form_data_.get();
    176   }
    177   void set_password_form_data(scoped_ptr<PasswordForm> data);
    178 
    179   void set_was_prefetcher(bool value) { was_prefetcher_ = value; }
    180   bool was_prefetcher() const { return was_prefetcher_; }
    181 
    182   void set_was_referred_by_prefetcher(bool value) {
    183     was_referred_by_prefetcher_ = value;
    184   }
    185   bool was_referred_by_prefetcher() const {
    186     return was_referred_by_prefetcher_;
    187   }
    188 
    189   void set_was_after_preconnect_request(bool value) {
    190     was_after_preconnect_request_ = value;
    191   }
    192   bool was_after_preconnect_request() { return was_after_preconnect_request_; }
    193 
    194   // Record the nature of this load, for use when histogramming page load times.
    195   LoadType load_type() const { return load_type_; }
    196   void set_load_type(LoadType load_type) { load_type_ = load_type; }
    197 
    198   NavigationState* navigation_state() { return navigation_state_.get(); }
    199   void set_navigation_state(NavigationState* navigation_state);
    200 
    201   bool can_load_local_resources() const { return can_load_local_resources_; }
    202   void set_can_load_local_resources(bool can_load) {
    203     can_load_local_resources_ = can_load;
    204   }
    205 
    206  private:
    207   base::Time request_time_;
    208   base::Time start_load_time_;
    209   base::Time commit_load_time_;
    210   base::Time finish_document_load_time_;
    211   base::Time finish_load_time_;
    212   base::Time first_paint_time_;
    213   base::Time first_paint_after_load_time_;
    214   bool load_histograms_recorded_;
    215   bool web_timing_histograms_recorded_;
    216   bool was_fetched_via_spdy_;
    217   bool was_npn_negotiated_;
    218   std::string npn_negotiated_protocol_;
    219   bool was_alternate_protocol_available_;
    220   net::HttpResponseInfo::ConnectionInfo connection_info_;
    221   bool was_fetched_via_proxy_;
    222 
    223   scoped_ptr<PasswordForm> password_form_data_;
    224 
    225   // A prefetcher is a page that contains link rel=prefetch elements.
    226   bool was_prefetcher_;
    227   bool was_referred_by_prefetcher_;
    228   bool was_after_preconnect_request_;
    229 
    230   LoadType load_type_;
    231 
    232   scoped_ptr<NavigationState> navigation_state_;
    233 
    234   bool can_load_local_resources_;
    235 };
    236 
    237 #endif  // CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_
    238 
    239 }  // namespace content
    240