blob: 93734ab7b12daa720c80399a5a1b88916636a3cb [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"
[email protected]2255a9332013-06-17 05:12:3115#include "third_party/WebKit/public/web/WebFrame.h"
16#include "third_party/WebKit/public/web/WebView.h"
[email protected]27c521a2013-05-29 20:44:3217
18using webkit_glue::CppArgumentList;
19using webkit_glue::CppVariant;
20
21namespace content {
22
23namespace {
24
25bool CurrentRenderViewImpl(RenderViewImpl** out) {
[email protected]180ef242013-11-07 06:50:4626 blink::WebFrame* web_frame = blink::WebFrame::frameForCurrentContext();
[email protected]27c521a2013-05-29 20:44:3227 if (!web_frame)
28 return false;
29
[email protected]180ef242013-11-07 06:50:4630 blink::WebView* web_view = web_frame->view();
[email protected]27c521a2013-05-29 20:44:3231 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(
[email protected]538dde872013-11-19 16:44:1753 const base::Time& load_start_time,
54 const base::Time& load_stop_time,
[email protected]27c521a2013-05-29 20:44:3255 std::string *result) {
[email protected]716775252013-06-14 17:58:0056 base::DictionaryValue item;
[email protected]27c521a2013-05-29 20:44:3257
58 if (load_start_time.is_null()) {
[email protected]538dde872013-11-19 16:44:1759 item.Set("load_start_ms", base::Value::CreateNullValue());
[email protected]27c521a2013-05-29 20:44:3260 } else {
[email protected]27c521a2013-05-29 20:44:3261 item.SetDouble("load_start_ms", load_start_time.ToInternalValue() / 1000);
62 }
[email protected]c81e3fd2013-08-05 16:30:2263 if (load_start_time.is_null() || load_stop_time.is_null()) {
[email protected]716775252013-06-14 17:58:0064 item.Set("load_duration_ms", base::Value::CreateNullValue());
[email protected]27c521a2013-05-29 20:44:3265 } else {
66 item.SetDouble("load_duration_ms",
[email protected]538dde872013-11-19 16:44:1767 (load_stop_time - load_start_time).InMillisecondsF());
[email protected]27c521a2013-05-29 20:44:3268 }
69 base::JSONWriter::Write(&item, result);
70}
71
72} // namespace
73
74StatsCollectionController::StatsCollectionController()
75 : sender_(NULL) {
76 BindCallback("getHistogram",
77 base::Bind(&StatsCollectionController::GetHistogram,
78 base::Unretained(this)));
79 BindCallback("getBrowserHistogram",
80 base::Bind(&StatsCollectionController::GetBrowserHistogram,
81 base::Unretained(this)));
82 BindCallback("tabLoadTiming",
83 base::Bind(
84 &StatsCollectionController::GetTabLoadTiming,
85 base::Unretained(this)));
86}
87
88void StatsCollectionController::GetHistogram(const CppArgumentList& args,
89 CppVariant* result) {
90 if (args.size() != 1) {
91 result->SetNull();
92 return;
93 }
94 base::HistogramBase* histogram =
95 base::StatisticsRecorder::FindHistogram(args[0].ToString());
96 std::string output;
97 if (!histogram) {
98 output = "{}";
99 } else {
100 histogram->WriteJSON(&output);
101 }
102 result->Set(output);
103}
104
105void StatsCollectionController::GetBrowserHistogram(const CppArgumentList& args,
106 CppVariant* result) {
107 if (args.size() != 1) {
108 result->SetNull();
109 return;
110 }
111
112 if (!sender_) {
113 NOTREACHED();
114 result->SetNull();
115 return;
116 }
117
118 std::string histogram_json;
119 sender_->Send(new ChildProcessHostMsg_GetBrowserHistogram(
120 args[0].ToString(), &histogram_json));
121 result->Set(histogram_json);
122}
123
124void StatsCollectionController::GetTabLoadTiming(
125 const CppArgumentList& args,
126 CppVariant* result) {
127 if (!sender_) {
128 NOTREACHED();
129 result->SetNull();
130 return;
131 }
132
133 RenderViewImpl *render_view_impl = NULL;
134 if (!CurrentRenderViewImpl(&render_view_impl)) {
135 NOTREACHED();
136 result->SetNull();
137 return;
138 }
139
140 StatsCollectionObserver* observer =
141 render_view_impl->GetStatsCollectionObserver();
142 if (!observer) {
143 NOTREACHED();
144 result->SetNull();
145 return;
146 }
147
148 std::string tab_timing_json;
149 ConvertLoadTimeToJSON(
150 observer->load_start_time(), observer->load_stop_time(),
151 &tab_timing_json);
152 result->Set(tab_timing_json);
153}
154
155} // namespace content