blob: 80ff096d9f98c1078b7bf93c275b972520e801c2 [file] [log] [blame]
[email protected]27c521a2013-05-29 20:44:321// Copyright 2013 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#include "content/renderer/stats_collection_controller.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/json/json_writer.h"
10#include "base/metrics/histogram.h"
11#include "base/metrics/statistics_recorder.h"
[email protected]21aa99682013-06-11 07:17:0112#include "base/strings/string_util.h"
[email protected]27c521a2013-05-29 20:44:3213#include "content/common/child_process_messages.h"
14#include "content/renderer/render_view_impl.h"
15#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
16#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
17
18using webkit_glue::CppArgumentList;
19using webkit_glue::CppVariant;
20
21namespace content {
22
23namespace {
24
25bool CurrentRenderViewImpl(RenderViewImpl** out) {
26 WebKit::WebFrame* web_frame = WebKit::WebFrame::frameForCurrentContext();
27 if (!web_frame)
28 return false;
29
30 WebKit::WebView* web_view = web_frame->view();
31 if (!web_view)
32 return false;
33
34 RenderViewImpl* render_view_impl =
35 RenderViewImpl::FromWebView(web_view);
36 if (!render_view_impl)
37 return false;
38
39 *out = render_view_impl;
40 return true;
41}
42
43// Encodes a WebContentsLoadTime as JSON.
44// Input:
45// - |load_start_time| - time at which page load started.
46// - |load_stop_time| - time at which page load stopped.
47// - |result| - returned JSON.
48// Example return value:
49// {'load_start_ms': 1, 'load_duration_ms': 2.5}
50// either value may be null if a web contents hasn't fully loaded.
51// load_start_ms is represented as milliseconds since system boot.
52void ConvertLoadTimeToJSON(
53 const base::TimeTicks& load_start_time,
54 const base::TimeTicks& load_stop_time,
55 std::string *result) {
56 DictionaryValue item;
57
58 if (load_start_time.is_null()) {
59 item.Set("load_start_ms", Value::CreateNullValue());
60 } else {
61 // This code relies on an implementation detail of TimeTicks::Now() - that
62 // its return value happens to coincide with the system uptime value in
63 // microseconds, on Win/Mac/iOS/Linux/ChromeOS and Android. See comments
64 // in base::SysInfo::Uptime().
65 item.SetDouble("load_start_ms", load_start_time.ToInternalValue() / 1000);
66 }
67 if (load_stop_time.is_null() || load_stop_time.is_null()) {
68 item.Set("load_duration_ms", Value::CreateNullValue());
69 } else {
70 item.SetDouble("load_duration_ms",
71 (load_stop_time - load_start_time).InMilliseconds());
72 }
73 base::JSONWriter::Write(&item, result);
74}
75
76} // namespace
77
78StatsCollectionController::StatsCollectionController()
79 : sender_(NULL) {
80 BindCallback("getHistogram",
81 base::Bind(&StatsCollectionController::GetHistogram,
82 base::Unretained(this)));
83 BindCallback("getBrowserHistogram",
84 base::Bind(&StatsCollectionController::GetBrowserHistogram,
85 base::Unretained(this)));
86 BindCallback("tabLoadTiming",
87 base::Bind(
88 &StatsCollectionController::GetTabLoadTiming,
89 base::Unretained(this)));
90}
91
92void StatsCollectionController::GetHistogram(const CppArgumentList& args,
93 CppVariant* result) {
94 if (args.size() != 1) {
95 result->SetNull();
96 return;
97 }
98 base::HistogramBase* histogram =
99 base::StatisticsRecorder::FindHistogram(args[0].ToString());
100 std::string output;
101 if (!histogram) {
102 output = "{}";
103 } else {
104 histogram->WriteJSON(&output);
105 }
106 result->Set(output);
107}
108
109void StatsCollectionController::GetBrowserHistogram(const CppArgumentList& args,
110 CppVariant* result) {
111 if (args.size() != 1) {
112 result->SetNull();
113 return;
114 }
115
116 if (!sender_) {
117 NOTREACHED();
118 result->SetNull();
119 return;
120 }
121
122 std::string histogram_json;
123 sender_->Send(new ChildProcessHostMsg_GetBrowserHistogram(
124 args[0].ToString(), &histogram_json));
125 result->Set(histogram_json);
126}
127
128void StatsCollectionController::GetTabLoadTiming(
129 const CppArgumentList& args,
130 CppVariant* result) {
131 if (!sender_) {
132 NOTREACHED();
133 result->SetNull();
134 return;
135 }
136
137 RenderViewImpl *render_view_impl = NULL;
138 if (!CurrentRenderViewImpl(&render_view_impl)) {
139 NOTREACHED();
140 result->SetNull();
141 return;
142 }
143
144 StatsCollectionObserver* observer =
145 render_view_impl->GetStatsCollectionObserver();
146 if (!observer) {
147 NOTREACHED();
148 result->SetNull();
149 return;
150 }
151
152 std::string tab_timing_json;
153 ConvertLoadTimeToJSON(
154 observer->load_start_time(), observer->load_stop_time(),
155 &tab_timing_json);
156 result->Set(tab_timing_json);
157}
158
159} // namespace content