- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / stats_collection_controller.cc
1 // 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"
12 #include "base/strings/string_util.h"
13 #include "content/common/child_process_messages.h"
14 #include "content/renderer/render_view_impl.h"
15 #include "third_party/WebKit/public/web/WebFrame.h"
16 #include "third_party/WebKit/public/web/WebView.h"
17
18 using webkit_glue::CppArgumentList;
19 using webkit_glue::CppVariant;
20
21 namespace content {
22
23 namespace {
24
25 bool 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.
52 void ConvertLoadTimeToJSON(
53     const base::TimeTicks& load_start_time,
54     const base::TimeTicks& load_stop_time,
55     std::string *result) {
56   base::DictionaryValue item;
57
58   if (load_start_time.is_null()) {
59      item.Set("load_start_ms", base::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_start_time.is_null() || load_stop_time.is_null()) {
68     item.Set("load_duration_ms", base::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
78 StatsCollectionController::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
92 void 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
109 void 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
128 void 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