summaryrefslogtreecommitdiffstats
path: root/content/public/renderer/document_state.h
blob: c7829d60ec308395075fdefa6a3e32c11a03e291 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// 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;
struct PasswordForm;

// 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 WebKit::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(WebKit::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;
  }

  // If set, contains the PasswordForm that we believe triggered the current
  // navigation (there is some ambiguity in the case of javascript initiated
  // navigations). This information is used by the PasswordManager to determine
  // if the user should be prompted to save their password.
  //
  // Note that setting this field doesn't affect where the data is sent or what
  // origin we associate it with, only whether we prompt the user to save it.
  // That is, a false positive is a usability issue (e.g. may try to save a
  // mis-typed password) not a security issue.
  PasswordForm* password_form_data() const {
    return password_form_data_.get();
  }
  void set_password_form_data(scoped_ptr<PasswordForm> data);

  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_;
  }

  // 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_;

  scoped_ptr<PasswordForm> password_form_data_;

  // A prefetcher is a page that contains link rel=prefetch elements.
  bool was_prefetcher_;
  bool was_referred_by_prefetcher_;

  LoadType load_type_;

  scoped_ptr<NavigationState> navigation_state_;

  bool can_load_local_resources_;
};

#endif  // CONTENT_PUBLIC_RENDERER_DOCUMENT_STATE_H_

}  // namespace content