OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 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/string_util.h" |
| 13 #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 |
| 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 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 |
| 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 |
OLD | NEW |