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 CHROME_BROWSER_PRERENDER_PRERENDER_HISTOGRAMS_H_
6#define CHROME_BROWSER_PRERENDER_PRERENDER_HISTOGRAMS_H_
7
8#include <string>
9
10#include "base/time/time.h"
11#include "chrome/browser/prerender/prerender_contents.h"
12#include "chrome/browser/prerender/prerender_events.h"
13#include "chrome/browser/prerender/prerender_final_status.h"
14#include "chrome/browser/prerender/prerender_local_predictor.h"
15#include "chrome/browser/prerender/prerender_origin.h"
16#include "url/gurl.h"
17
18namespace prerender {
19
20// Navigation type for histograms.
21enum NavigationType {
22  // A normal completed navigation.
23  NAVIGATION_TYPE_NORMAL,
24  // A completed navigation or swap that began as a prerender.
25  NAVIGATION_TYPE_PRERENDERED,
26  // A normal completed navigation in the control group or with a control
27  // prerender that would have been prerendered.
28  NAVIGATION_TYPE_WOULD_HAVE_BEEN_PRERENDERED,
29  NAVIGATION_TYPE_MAX,
30};
31
32// PrerenderHistograms is responsible for recording all prerender specific
33// histograms for PrerenderManager.  It keeps track of the type of prerender
34// currently underway (based on the PrerenderOrigin of the most recent
35// prerenders, and any experiments detected).
36// PrerenderHistograms does not necessarily record all histograms related to
37// prerendering, only the ones in the context of PrerenderManager.
38class PrerenderHistograms {
39 public:
40  // Owned by a PrerenderManager object for the lifetime of the
41  // PrerenderManager.
42  PrerenderHistograms();
43
44  // Records the perceived page load time for a page - effectively the time from
45  // when the user navigates to a page to when it finishes loading.  The actual
46  // load may have started prior to navigation due to prerender hints.
47  void RecordPerceivedPageLoadTime(Origin origin,
48                                   base::TimeDelta perceived_page_load_time,
49                                   NavigationType navigation_type,
50                                   const GURL& url);
51
52  // Records, in a histogram, the percentage of the page load time that had
53  // elapsed by the time it is swapped in.  Values outside of [0, 1.0] are
54  // invalid and ignored.
55  void RecordPercentLoadDoneAtSwapin(Origin origin, double fraction) const;
56
57  // Records the actual pageload time of a prerender that has not been swapped
58  // in yet, but finished loading.
59  void RecordPageLoadTimeNotSwappedIn(Origin origin,
60                                      base::TimeDelta page_load_time,
61                                      const GURL& url) const;
62
63  // Records the time from when a page starts prerendering to when the user
64  // navigates to it. This must be called on the UI thread.
65  void RecordTimeUntilUsed(Origin origin,
66                           base::TimeDelta time_until_used) const;
67
68  // Records the time from when a prerender is abandoned to when the user
69  // navigates to it. This must be called on the UI thread.
70  void RecordAbandonTimeUntilUsed(Origin origin,
71                                  base::TimeDelta time_until_used) const;
72
73  // Record a PerSessionCount data point.
74  void RecordPerSessionCount(Origin origin, int count) const;
75
76  // Record time between two prerender requests.
77  void RecordTimeBetweenPrerenderRequests(Origin origin,
78                                          base::TimeDelta time) const;
79
80  // Record a final status of a prerendered page in a histogram.
81  void RecordFinalStatus(Origin origin,
82                         uint8 experiment_id,
83                         PrerenderContents::MatchCompleteStatus mc_status,
84                         FinalStatus final_status) const;
85
86  // To be called when a new prerender is added.
87  void RecordPrerender(Origin origin, const GURL& url);
88
89  // To be called when a new prerender is started.
90  void RecordPrerenderStarted(Origin origin) const;
91
92  // To be called when we know how many prerenders are running after starting
93  // a prerender.
94  void RecordConcurrency(size_t prerender_count) const;
95
96  // Called when we swap in a prerender.
97  void RecordUsedPrerender(Origin origin) const;
98
99  // Record the time since a page was recently visited.
100  void RecordTimeSinceLastRecentVisit(Origin origin,
101                                      base::TimeDelta time) const;
102
103  // Records a prerender event.
104  void RecordEvent(Origin origin, uint8 experiment_id, PrerenderEvent event)
105      const;
106
107  // Record a prerender cookie status bitmap. Must be in the range
108  // [0, PrerenderContents::kNumCookieStatuses).
109  void RecordCookieStatus(Origin origin,
110                          uint8 experiment_id,
111                          int cookie_status) const;
112
113  // Record a prerender cookie send type. Must be in the range
114  // [0, PrerenderContents::kNumCookieSendTypes).
115  void RecordCookieSendType(Origin origin,
116                            uint8 experiment_id,
117                            int cookie_send_type) const;
118
119  void RecordPrerenderPageVisitedStatus(Origin origin,
120                                        uint8 experiment_id,
121                                        bool visited_before) const;
122
123  // Record the bytes in the prerender, whether it was used or not, and the
124  // total number of bytes fetched for this profile since the last call to
125  // RecordBytes.
126  void RecordNetworkBytes(Origin origin,
127                          bool used,
128                          int64 prerender_bytes,
129                          int64 profile_bytes);
130
131 private:
132  base::TimeTicks GetCurrentTimeTicks() const;
133
134  // Returns the time elapsed since the last prerender happened.
135  base::TimeDelta GetTimeSinceLastPrerender() const;
136
137  // Returns whether the PrerenderManager is currently within the prerender
138  // window - effectively, up to 30 seconds after a prerender tag has been
139  // observed.
140  bool WithinWindow() const;
141
142  // Returns the current experiment.
143  uint8 GetCurrentExperimentId() const;
144
145  // Returns whether or not there is currently an origin/experiment wash.
146  bool IsOriginExperimentWash() const;
147
148  // An integer indicating a Prerendering Experiment being currently conducted.
149  // (The last experiment ID seen).
150  uint8 last_experiment_id_;
151
152  // Origin of the last prerender seen.
153  Origin last_origin_;
154
155  // A boolean indicating that we have recently encountered a combination of
156  // different experiments and origins, making an attribution of PPLT's to
157  // experiments / origins impossible.
158  bool origin_experiment_wash_;
159
160  // The time when we last saw a prerender request coming from a renderer.
161  // This is used to record perceived PLT's for a certain amount of time
162  // from the point that we last saw a <link rel=prerender> tag.
163  base::TimeTicks last_prerender_seen_time_;
164
165  // Indicates whether we have recorded page load events after the most
166  // recent prerender.  These must be initialized to true, so that we don't
167  // start recording events before the first prerender occurs.
168  bool seen_any_pageload_;
169  bool seen_pageload_started_after_prerender_;
170
171  DISALLOW_COPY_AND_ASSIGN(PrerenderHistograms);
172};
173
174}  // namespace prerender
175
176#endif  // CHROME_BROWSER_PRERENDER_PRERENDER_HISTOGRAMS_H_
177