Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / renderer / pepper / pepper_uma_host.cc
blobd929fc8a39b0795044bf495ae0cd6e30ba4e1178
1 // Copyright 2014 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.
5 #include "chrome/renderer/pepper/pepper_uma_host.h"
7 #include "base/metrics/histogram.h"
8 #include "base/sha1.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "chrome/common/chrome_content_client.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "chrome/common/render_messages.h"
13 #include "chrome/renderer/chrome_content_renderer_client.h"
14 #include "content/public/renderer/pepper_plugin_instance.h"
15 #include "content/public/renderer/render_thread.h"
16 #include "content/public/renderer/renderer_ppapi_host.h"
17 #include "ppapi/c/pp_errors.h"
18 #include "ppapi/host/dispatch_host_message.h"
19 #include "ppapi/host/host_message_context.h"
20 #include "ppapi/host/ppapi_host.h"
21 #include "ppapi/proxy/ppapi_messages.h"
23 #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
25 #if defined(ENABLE_EXTENSIONS)
26 #include "extensions/common/constants.h"
27 #include "extensions/common/extension.h"
28 #endif // defined(ENABLE_EXTENSIONS)
30 namespace {
32 const char* const kPredefinedAllowedUMAOrigins[] = {
33 "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", // see http://crbug.com/317833
34 "4EB74897CB187C7633357C2FE832E0AD6A44883A", // see http://crbug.com/317833
35 "9E527CDA9D7C50844E8A5DB964A54A640AE48F98", // see http://crbug.com/521189
36 "DF52618D0B040D8A054D8348D2E84DDEEE5974E7", // see http://crbug.com/521189
37 "269D721F163E587BC53C6F83553BF9CE2BB143CD", // see http://crbug.com/521189
38 "6B55A5329E3F1F30F6032BDB20B2EB4378DBF767", // see http://crbug.com/521189
39 "C449A798C495E6CF7D6AF10162113D564E67AD12", // see http://crbug.com/521189
40 "01E9FFA9A8F3C18271FE91BEE46207F3B81755CC", // see http://crbug.com/521189
41 "97B23E01B2AA064E8332EE43A7A85C628AADC3F2", // see http://crbug.com/521189
44 const char* const kWhitelistedHistogramPrefixes[] = {
45 "22F67DA2061FFC4DC9A4974036348D9C38C22919", // see http://crbug.com/390221
46 "3FEA4650221C5E6C39CF5C5C9F464FF74EAB6CE1", // see http://crbug.com/521189
49 const char* const kWhitelistedPluginBaseNames[] = {
50 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
51 kWidevineCdmAdapterFileName, // see http://crbug.com/368743
52 // and http://crbug.com/410630
53 #endif
54 ChromeContentClient::kPDFPluginPath,
57 std::string HashPrefix(const std::string& histogram) {
58 const std::string id_hash =
59 base::SHA1HashString(histogram.substr(0, histogram.find('.')));
60 DCHECK_EQ(id_hash.length(), base::kSHA1Length);
61 return base::HexEncode(id_hash.c_str(), id_hash.length());
64 } // namespace
66 PepperUMAHost::PepperUMAHost(content::RendererPpapiHost* host,
67 PP_Instance instance,
68 PP_Resource resource)
69 : ResourceHost(host->GetPpapiHost(), instance, resource),
70 document_url_(host->GetDocumentURL(instance)),
71 is_plugin_in_process_(host->IsRunningInProcess()) {
72 if (host->GetPluginInstance(instance)) {
73 plugin_base_name_ =
74 host->GetPluginInstance(instance)->GetModulePath().BaseName();
77 for (size_t i = 0; i < arraysize(kPredefinedAllowedUMAOrigins); ++i)
78 allowed_origins_.insert(kPredefinedAllowedUMAOrigins[i]);
79 for (size_t i = 0; i < arraysize(kWhitelistedHistogramPrefixes); ++i)
80 allowed_histogram_prefixes_.insert(kWhitelistedHistogramPrefixes[i]);
81 for (size_t i = 0; i < arraysize(kWhitelistedPluginBaseNames); ++i)
82 allowed_plugin_base_names_.insert(kWhitelistedPluginBaseNames[i]);
85 PepperUMAHost::~PepperUMAHost() {}
87 int32_t PepperUMAHost::OnResourceMessageReceived(
88 const IPC::Message& msg,
89 ppapi::host::HostMessageContext* context) {
90 PPAPI_BEGIN_MESSAGE_MAP(PepperUMAHost, msg)
91 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomTimes,
92 OnHistogramCustomTimes)
93 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomCounts,
94 OnHistogramCustomCounts)
95 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramEnumeration,
96 OnHistogramEnumeration)
97 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
98 PpapiHostMsg_UMA_IsCrashReportingEnabled, OnIsCrashReportingEnabled)
99 PPAPI_END_MESSAGE_MAP()
100 return PP_ERROR_FAILED;
103 bool PepperUMAHost::IsPluginWhitelisted() {
104 #if defined(ENABLE_EXTENSIONS)
105 return ChromeContentRendererClient::IsExtensionOrSharedModuleWhitelisted(
106 document_url_, allowed_origins_);
107 #else
108 return false;
109 #endif
112 bool PepperUMAHost::IsHistogramAllowed(const std::string& histogram) {
113 if (is_plugin_in_process_ && histogram.find("NaCl.") == 0) {
114 return true;
117 if (IsPluginWhitelisted() &&
118 ContainsKey(allowed_histogram_prefixes_, HashPrefix(histogram))) {
119 return true;
122 if (ContainsKey(allowed_plugin_base_names_,
123 plugin_base_name_.MaybeAsASCII())) {
124 return true;
127 LOG(ERROR) << "Host or histogram name is not allowed to use the UMA API.";
128 return false;
131 #define RETURN_IF_BAD_ARGS(_min, _max, _buckets) \
132 do { \
133 if (_min >= _max || _buckets <= 1) \
134 return PP_ERROR_BADARGUMENT; \
135 } while (0)
137 int32_t PepperUMAHost::OnHistogramCustomTimes(
138 ppapi::host::HostMessageContext* context,
139 const std::string& name,
140 int64_t sample,
141 int64_t min,
142 int64_t max,
143 uint32_t bucket_count) {
144 if (!IsHistogramAllowed(name)) {
145 return PP_ERROR_NOACCESS;
147 RETURN_IF_BAD_ARGS(min, max, bucket_count);
149 base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
150 name,
151 base::TimeDelta::FromMilliseconds(min),
152 base::TimeDelta::FromMilliseconds(max),
153 bucket_count,
154 base::HistogramBase::kUmaTargetedHistogramFlag);
155 // The histogram can be NULL if it is constructed with bad arguments. Ignore
156 // that data for this API. An error message will be logged.
157 if (counter)
158 counter->AddTime(base::TimeDelta::FromMilliseconds(sample));
159 return PP_OK;
162 int32_t PepperUMAHost::OnHistogramCustomCounts(
163 ppapi::host::HostMessageContext* context,
164 const std::string& name,
165 int32_t sample,
166 int32_t min,
167 int32_t max,
168 uint32_t bucket_count) {
169 if (!IsHistogramAllowed(name)) {
170 return PP_ERROR_NOACCESS;
172 RETURN_IF_BAD_ARGS(min, max, bucket_count);
174 base::HistogramBase* counter = base::Histogram::FactoryGet(
175 name,
176 min,
177 max,
178 bucket_count,
179 base::HistogramBase::kUmaTargetedHistogramFlag);
180 // The histogram can be NULL if it is constructed with bad arguments. Ignore
181 // that data for this API. An error message will be logged.
182 if (counter)
183 counter->Add(sample);
184 return PP_OK;
187 int32_t PepperUMAHost::OnHistogramEnumeration(
188 ppapi::host::HostMessageContext* context,
189 const std::string& name,
190 int32_t sample,
191 int32_t boundary_value) {
192 if (!IsHistogramAllowed(name)) {
193 return PP_ERROR_NOACCESS;
195 RETURN_IF_BAD_ARGS(0, boundary_value, boundary_value + 1);
197 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
198 name,
200 boundary_value,
201 boundary_value + 1,
202 base::HistogramBase::kUmaTargetedHistogramFlag);
203 // The histogram can be NULL if it is constructed with bad arguments. Ignore
204 // that data for this API. An error message will be logged.
205 if (counter)
206 counter->Add(sample);
207 return PP_OK;
210 int32_t PepperUMAHost::OnIsCrashReportingEnabled(
211 ppapi::host::HostMessageContext* context) {
212 if (!IsPluginWhitelisted())
213 return PP_ERROR_NOACCESS;
214 bool enabled = false;
215 content::RenderThread::Get()->Send(
216 new ChromeViewHostMsg_IsCrashReportingEnabled(&enabled));
217 if (enabled)
218 return PP_OK;
219 return PP_ERROR_FAILED;