Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / renderer / pepper / pepper_uma_host.cc
blob693c4977a0a9c3c3492e68520627a2cd68511e15
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
37 const char* const kWhitelistedHistogramPrefixes[] = {
38 "22F67DA2061FFC4DC9A4974036348D9C38C22919", // see http://crbug.com/390221
41 const char* const kWhitelistedPluginBaseNames[] = {
42 #if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
43 kWidevineCdmAdapterFileName, // see http://crbug.com/368743
44 // and http://crbug.com/410630
45 #endif
46 ChromeContentClient::kPDFPluginPath,
49 std::string HashPrefix(const std::string& histogram) {
50 const std::string id_hash =
51 base::SHA1HashString(histogram.substr(0, histogram.find('.')));
52 DCHECK_EQ(id_hash.length(), base::kSHA1Length);
53 return base::HexEncode(id_hash.c_str(), id_hash.length());
56 } // namespace
58 PepperUMAHost::PepperUMAHost(content::RendererPpapiHost* host,
59 PP_Instance instance,
60 PP_Resource resource)
61 : ResourceHost(host->GetPpapiHost(), instance, resource),
62 document_url_(host->GetDocumentURL(instance)),
63 is_plugin_in_process_(host->IsRunningInProcess()) {
64 if (host->GetPluginInstance(instance)) {
65 plugin_base_name_ =
66 host->GetPluginInstance(instance)->GetModulePath().BaseName();
69 for (size_t i = 0; i < arraysize(kPredefinedAllowedUMAOrigins); ++i)
70 allowed_origins_.insert(kPredefinedAllowedUMAOrigins[i]);
71 for (size_t i = 0; i < arraysize(kWhitelistedHistogramPrefixes); ++i)
72 allowed_histogram_prefixes_.insert(kWhitelistedHistogramPrefixes[i]);
73 for (size_t i = 0; i < arraysize(kWhitelistedPluginBaseNames); ++i)
74 allowed_plugin_base_names_.insert(kWhitelistedPluginBaseNames[i]);
77 PepperUMAHost::~PepperUMAHost() {}
79 int32_t PepperUMAHost::OnResourceMessageReceived(
80 const IPC::Message& msg,
81 ppapi::host::HostMessageContext* context) {
82 PPAPI_BEGIN_MESSAGE_MAP(PepperUMAHost, msg)
83 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomTimes,
84 OnHistogramCustomTimes)
85 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramCustomCounts,
86 OnHistogramCustomCounts)
87 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UMA_HistogramEnumeration,
88 OnHistogramEnumeration)
89 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
90 PpapiHostMsg_UMA_IsCrashReportingEnabled, OnIsCrashReportingEnabled)
91 PPAPI_END_MESSAGE_MAP()
92 return PP_ERROR_FAILED;
95 bool PepperUMAHost::IsPluginWhitelisted() {
96 #if defined(ENABLE_EXTENSIONS)
97 return ChromeContentRendererClient::IsExtensionOrSharedModuleWhitelisted(
98 document_url_, allowed_origins_);
99 #else
100 return false;
101 #endif
104 bool PepperUMAHost::IsHistogramAllowed(const std::string& histogram) {
105 if (is_plugin_in_process_ && histogram.find("NaCl.") == 0) {
106 return true;
109 if (IsPluginWhitelisted() &&
110 ContainsKey(allowed_histogram_prefixes_, HashPrefix(histogram))) {
111 return true;
114 if (ContainsKey(allowed_plugin_base_names_,
115 plugin_base_name_.MaybeAsASCII())) {
116 return true;
119 LOG(ERROR) << "Host or histogram name is not allowed to use the UMA API.";
120 return false;
123 #define RETURN_IF_BAD_ARGS(_min, _max, _buckets) \
124 do { \
125 if (_min >= _max || _buckets <= 1) \
126 return PP_ERROR_BADARGUMENT; \
127 } while (0)
129 int32_t PepperUMAHost::OnHistogramCustomTimes(
130 ppapi::host::HostMessageContext* context,
131 const std::string& name,
132 int64_t sample,
133 int64_t min,
134 int64_t max,
135 uint32_t bucket_count) {
136 if (!IsHistogramAllowed(name)) {
137 return PP_ERROR_NOACCESS;
139 RETURN_IF_BAD_ARGS(min, max, bucket_count);
141 base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
142 name,
143 base::TimeDelta::FromMilliseconds(min),
144 base::TimeDelta::FromMilliseconds(max),
145 bucket_count,
146 base::HistogramBase::kUmaTargetedHistogramFlag);
147 // The histogram can be NULL if it is constructed with bad arguments. Ignore
148 // that data for this API. An error message will be logged.
149 if (counter)
150 counter->AddTime(base::TimeDelta::FromMilliseconds(sample));
151 return PP_OK;
154 int32_t PepperUMAHost::OnHistogramCustomCounts(
155 ppapi::host::HostMessageContext* context,
156 const std::string& name,
157 int32_t sample,
158 int32_t min,
159 int32_t max,
160 uint32_t bucket_count) {
161 if (!IsHistogramAllowed(name)) {
162 return PP_ERROR_NOACCESS;
164 RETURN_IF_BAD_ARGS(min, max, bucket_count);
166 base::HistogramBase* counter = base::Histogram::FactoryGet(
167 name,
168 min,
169 max,
170 bucket_count,
171 base::HistogramBase::kUmaTargetedHistogramFlag);
172 // The histogram can be NULL if it is constructed with bad arguments. Ignore
173 // that data for this API. An error message will be logged.
174 if (counter)
175 counter->Add(sample);
176 return PP_OK;
179 int32_t PepperUMAHost::OnHistogramEnumeration(
180 ppapi::host::HostMessageContext* context,
181 const std::string& name,
182 int32_t sample,
183 int32_t boundary_value) {
184 if (!IsHistogramAllowed(name)) {
185 return PP_ERROR_NOACCESS;
187 RETURN_IF_BAD_ARGS(0, boundary_value, boundary_value + 1);
189 base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
190 name,
192 boundary_value,
193 boundary_value + 1,
194 base::HistogramBase::kUmaTargetedHistogramFlag);
195 // The histogram can be NULL if it is constructed with bad arguments. Ignore
196 // that data for this API. An error message will be logged.
197 if (counter)
198 counter->Add(sample);
199 return PP_OK;
202 int32_t PepperUMAHost::OnIsCrashReportingEnabled(
203 ppapi::host::HostMessageContext* context) {
204 if (!IsPluginWhitelisted())
205 return PP_ERROR_NOACCESS;
206 bool enabled = false;
207 content::RenderThread::Get()->Send(
208 new ChromeViewHostMsg_IsCrashReportingEnabled(&enabled));
209 if (enabled)
210 return PP_OK;
211 return PP_ERROR_FAILED;