Index: content/renderer/stats_collection_controller.cc |
diff --git a/content/renderer/stats_collection_controller.cc b/content/renderer/stats_collection_controller.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0cd11640f529558ec629a081cc3710adf5a2ca3d |
--- /dev/null |
+++ b/content/renderer/stats_collection_controller.cc |
@@ -0,0 +1,159 @@ |
+// Copyright (c) 2013 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. |
+ |
+#include "content/renderer/stats_collection_controller.h" |
+ |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/json/json_writer.h" |
+#include "base/metrics/histogram.h" |
+#include "base/metrics/statistics_recorder.h" |
+#include "base/string_util.h" |
+#include "content/common/child_process_messages.h" |
+#include "content/renderer/render_view_impl.h" |
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
+ |
+using webkit_glue::CppArgumentList; |
+using webkit_glue::CppVariant; |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+bool CurrentRenderViewImpl(RenderViewImpl** out) { |
+ WebKit::WebFrame* web_frame = WebKit::WebFrame::frameForCurrentContext(); |
+ if (!web_frame) |
+ return false; |
+ |
+ WebKit::WebView* web_view = web_frame->view(); |
+ if (!web_view) |
+ return false; |
+ |
+ RenderViewImpl* render_view_impl = |
+ RenderViewImpl::FromWebView(web_view); |
+ if (!render_view_impl) |
+ return false; |
+ |
+ *out = render_view_impl; |
+ return true; |
+} |
+ |
+// Encodes a WebContentsLoadTime as JSON. |
+// Input: |
+// - |load_start_time| - time at which page load started. |
+// - |load_stop_time| - time at which page load stopped. |
+// - |result| - returned JSON. |
+// Example return value: |
+// {'load_start_ms': 1, 'load_duration_ms': 2.5} |
+// either value may be null if a web contents hasn't fully loaded. |
+// load_start_ms is represented as milliseconds since system boot. |
+void ConvertLoadTimeToJSON( |
+ const base::TimeTicks& load_start_time, |
+ const base::TimeTicks& load_stop_time, |
+ std::string *result) { |
+ DictionaryValue item; |
+ |
+ if (load_start_time.is_null()) { |
+ item.Set("load_start_ms", Value::CreateNullValue()); |
+ } else { |
+ // This code relies on an implementation detail of TimeTicks::Now() - that |
+ // its return value happens to coincide with the system uptime value in |
+ // microseconds, on Win/Mac/iOS/Linux/ChromeOS and Android. See comments |
+ // in base::SysInfo::Uptime(). |
+ item.SetDouble("load_start_ms", load_start_time.ToInternalValue() / 1000); |
+ } |
+ if (load_stop_time.is_null() || load_stop_time.is_null()) { |
+ item.Set("load_duration_ms", Value::CreateNullValue()); |
+ } else { |
+ item.SetDouble("load_duration_ms", |
+ (load_stop_time - load_start_time).InMilliseconds()); |
+ } |
+ base::JSONWriter::Write(&item, result); |
+} |
+ |
+} // namespace |
+ |
+StatsCollectionController::StatsCollectionController() |
+ : sender_(NULL) { |
+ BindCallback("getHistogram", |
+ base::Bind(&StatsCollectionController::GetHistogram, |
+ base::Unretained(this))); |
+ BindCallback("getBrowserHistogram", |
+ base::Bind(&StatsCollectionController::GetBrowserHistogram, |
+ base::Unretained(this))); |
+ BindCallback("tabLoadTiming", |
+ base::Bind( |
+ &StatsCollectionController::GetTabLoadTiming, |
+ base::Unretained(this))); |
+} |
+ |
+void StatsCollectionController::GetHistogram(const CppArgumentList& args, |
+ CppVariant* result) { |
+ if (args.size() != 1) { |
+ result->SetNull(); |
+ return; |
+ } |
+ base::HistogramBase* histogram = |
+ base::StatisticsRecorder::FindHistogram(args[0].ToString()); |
+ std::string output; |
+ if (!histogram) { |
+ output = "{}"; |
+ } else { |
+ histogram->WriteJSON(&output); |
+ } |
+ result->Set(output); |
+} |
+ |
+void StatsCollectionController::GetBrowserHistogram(const CppArgumentList& args, |
+ CppVariant* result) { |
+ if (args.size() != 1) { |
+ result->SetNull(); |
+ return; |
+ } |
+ |
+ if (!sender_) { |
+ NOTREACHED(); |
+ result->SetNull(); |
+ return; |
+ } |
+ |
+ std::string histogram_json; |
+ sender_->Send(new ChildProcessHostMsg_GetBrowserHistogram( |
+ args[0].ToString(), &histogram_json)); |
+ result->Set(histogram_json); |
+} |
+ |
+void StatsCollectionController::GetTabLoadTiming( |
+ const CppArgumentList& args, |
+ CppVariant* result) { |
+ if (!sender_) { |
+ NOTREACHED(); |
+ result->SetNull(); |
+ return; |
+ } |
+ |
+ RenderViewImpl *render_view_impl = NULL; |
+ if (!CurrentRenderViewImpl(&render_view_impl)) { |
+ NOTREACHED(); |
+ result->SetNull(); |
+ return; |
+ } |
+ |
+ StatsCollectionObserver* observer = |
+ render_view_impl->GetStatsCollectionObserver(); |
+ if (!observer) { |
+ NOTREACHED(); |
+ result->SetNull(); |
+ return; |
+ } |
+ |
+ std::string tab_timing_json; |
+ ConvertLoadTimeToJSON( |
+ observer->load_start_time(), observer->load_stop_time(), |
+ &tab_timing_json); |
+ result->Set(tab_timing_json); |
+} |
+ |
+} // namespace content |