document_state.h revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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
18namespace content {
19
20class NavigationState;
21struct PasswordForm;
22
23// The RenderView stores an instance of this class in the "extra data" of each
24// WebDataSource (see RenderView::DidCreateDataSource).
25class 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