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
|
// Copyright 2015 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 COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_OBSERVER_H_
#define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_OBSERVER_H_
#include "base/containers/scoped_ptr_map.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "components/page_load_metrics/common/page_load_timing.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "net/base/net_errors.h"
namespace content {
class NavigationHandle;
class RenderFrameHost;
} // namespace content
namespace IPC {
class Message;
} // namespace IPC
namespace rappor {
class RapporService;
}
namespace page_load_metrics {
// If you add elements from this enum, make sure you update the enum
// value in histograms.xml. Only add elements to the end to prevent
// inconsistencies between versions.
enum PageLoadEvent {
PAGE_LOAD_STARTED,
// A provisional load is a load before it commits, i.e. before it receives the
// first bytes of the response body or knows the encoding of the response
// body. A load failed before it was committed for any reason, e.g. from a
// user abort or a network timeout.
PAGE_LOAD_FAILED_BEFORE_COMMIT,
// A subset of PAGE_LOAD_FAILED_BEFORE_COMMIT, this counts the
// specific failures due to user aborts.
PAGE_LOAD_ABORTED_BEFORE_COMMIT,
// When a load is aborted anytime before the page's first layout, we increase
// these counts. This includes all failed provisional loads.
PAGE_LOAD_ABORTED_BEFORE_FIRST_LAYOUT,
// We increase this count if a page load successfully has a layout.
// Differentiate between loads that were backgrounded before first layout.
// Note that a load that is backgrounded, then foregrounded before first
// layout will still end up in the backgrounded bucket.
PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND,
PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND,
// Add values before this final count.
PAGE_LOAD_LAST_ENTRY
};
// This class tracks a given page load, starting from navigation start /
// provisional load, until a new navigation commits or the navigation fails. It
// also records RAPPOR/UMA about the page load.
// MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as
// well as a committed PageLoadTracker.
class PageLoadTracker {
public:
PageLoadTracker(bool in_foreground,
rappor::RapporService* const rappor_service);
~PageLoadTracker();
void Commit(const GURL& committed_url);
void WebContentsHidden();
// Returns true if the timing was successfully updated.
bool UpdateTiming(const PageLoadTiming& timing);
void RecordEvent(PageLoadEvent event);
private:
// Only valid to call post-commit.
const GURL& GetCommittedURL();
base::TimeDelta GetBackgroundDelta();
void RecordTimingHistograms();
void RecordRappor();
bool has_commit_;
// We record separate metrics for events that occur after a background,
// because metrics like layout/paint are delayed artificially
// when they occur in the bacground.
base::TimeTicks background_time_;
bool started_in_foreground_;
PageLoadTiming timing_;
GURL url_;
// This RapporService is owned by and shares a lifetime with
// g_browser_process's MetricsServicesManager. It can be NULL. The underlying
// RapporService will be freed when the when the browser process is killed.
rappor::RapporService* const rappor_service_;
DISALLOW_COPY_AND_ASSIGN(PageLoadTracker);
};
// MetricsWebContentsObserver logs page load UMA metrics based on
// IPC messages received from a MetricsRenderFrameObserver.
class MetricsWebContentsObserver
: public content::WebContentsObserver,
public content::WebContentsUserData<MetricsWebContentsObserver> {
public:
// The caller must guarantee that the RapporService (if non-null) will
// outlive the WebContents.
static void CreateForWebContents(content::WebContents* web_contents,
rappor::RapporService* rappor_service);
~MetricsWebContentsObserver() override;
// content::WebContentsObserver implementation:
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* render_frame_host) override;
void DidStartNavigation(
content::NavigationHandle* navigation_handle) override;
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override;
void WasShown() override;
void WasHidden() override;
void RenderProcessGone(base::TerminationStatus status) override;
private:
MetricsWebContentsObserver(content::WebContents* web_contents,
rappor::RapporService* rappor_service);
friend class content::WebContentsUserData<MetricsWebContentsObserver>;
friend class MetricsWebContentsObserverTest;
void OnTimingUpdated(content::RenderFrameHost*, const PageLoadTiming& timing);
bool IsRelevantNavigation(content::NavigationHandle* navigation_handle);
// True if the web contents is currently in the foreground.
bool in_foreground_;
// This map tracks all of the navigations ongoing that are not committed
// yet. Once a navigation is committed, it moves from the map to
// committed_load_. Note that a PageLoadTrackers NavigationHandle is only
// valid until commit time, when we remove it from the map.
base::ScopedPtrMap<content::NavigationHandle*, scoped_ptr<PageLoadTracker>>
provisional_loads_;
scoped_ptr<PageLoadTracker> committed_load_;
rappor::RapporService* const rappor_service_;
DISALLOW_COPY_AND_ASSIGN(MetricsWebContentsObserver);
};
} // namespace page_load_metrics
#endif // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_WEB_CONTENTS_OBSERVER_H_
|