1 // Copyright (c) 2011 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/plugins/plugin_uma.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/string_util.h"
12 #include "content/public/common/content_constants.h"
13 #include "third_party/widevine/cdm/widevine_cdm_common.h"
17 // String we will use to convert mime type to plugin type.
18 const char kWindowsMediaPlayerType
[] = "application/x-mplayer2";
19 const char kSilverlightTypePrefix
[] = "application/x-silverlight";
20 const char kRealPlayerTypePrefix
[] = "audio/x-pn-realaudio";
21 const char kJavaTypeSubstring
[] = "application/x-java-applet";
22 const char kQuickTimeType
[] = "video/quicktime";
24 // Arrays containing file extensions connected with specific plugins.
25 // Note: THE ARRAYS MUST BE SORTED BECAUSE BINARY SEARCH IS USED ON THEM!
26 const char* kWindowsMediaPlayerExtensions
[] = {".asx"};
28 const char* kRealPlayerExtensions
[] = {".ra", ".ram", ".rm",
29 ".rmm", ".rmp", ".rpm"};
31 const char* kQuickTimeExtensions
[] = {".moov", ".mov", ".qif",
32 ".qt", ".qti", ".qtif"};
34 const char* kShockwaveFlashExtensions
[] = {".spl", ".swf"};
38 class UMASenderImpl
: public PluginUMAReporter::UMASender
{
39 virtual void SendPluginUMA(
40 PluginUMAReporter::ReportType report_type
,
41 PluginUMAReporter::PluginType plugin_type
) OVERRIDE
;
44 void UMASenderImpl::SendPluginUMA(PluginUMAReporter::ReportType report_type
,
45 PluginUMAReporter::PluginType plugin_type
) {
46 // UMA_HISTOGRAM_ENUMERATION requires constant histogram name. Use string
47 // constants explicitly instead of trying to use variables for names.
48 switch (report_type
) {
49 case PluginUMAReporter::MISSING_PLUGIN
:
50 UMA_HISTOGRAM_ENUMERATION("Plugin.MissingPlugins",
52 PluginUMAReporter::PLUGIN_TYPE_MAX
);
54 case PluginUMAReporter::DISABLED_PLUGIN
:
55 UMA_HISTOGRAM_ENUMERATION("Plugin.DisabledPlugins",
57 PluginUMAReporter::PLUGIN_TYPE_MAX
);
65 PluginUMAReporter
* PluginUMAReporter::GetInstance() {
66 return Singleton
<PluginUMAReporter
>::get();
69 void PluginUMAReporter::ReportPluginMissing(const std::string
& plugin_mime_type
,
70 const GURL
& plugin_src
) {
71 report_sender_
->SendPluginUMA(MISSING_PLUGIN
,
72 GetPluginType(plugin_mime_type
, plugin_src
));
75 void PluginUMAReporter::ReportPluginDisabled(
76 const std::string
& plugin_mime_type
,
77 const GURL
& plugin_src
) {
78 report_sender_
->SendPluginUMA(DISABLED_PLUGIN
,
79 GetPluginType(plugin_mime_type
, plugin_src
));
82 PluginUMAReporter::PluginUMAReporter() : report_sender_(new UMASenderImpl()) {}
84 PluginUMAReporter::~PluginUMAReporter() {}
87 bool PluginUMAReporter::CompareCStrings(const char* first
, const char* second
) {
88 return strcmp(first
, second
) < 0;
91 bool PluginUMAReporter::CStringArrayContainsCString(const char** array
,
94 return std::binary_search(array
, array
+ array_size
, str
, CompareCStrings
);
97 void PluginUMAReporter::ExtractFileExtension(const GURL
& src
,
98 std::string
* extension
) {
99 std::string
extension_file_path(src
.ExtractFileName());
100 if (extension_file_path
.empty())
101 extension_file_path
= src
.host();
103 size_t last_dot
= extension_file_path
.find_last_of('.');
104 if (last_dot
!= std::string::npos
) {
105 *extension
= extension_file_path
.substr(last_dot
);
110 StringToLowerASCII(extension
);
113 PluginUMAReporter::PluginType
PluginUMAReporter::GetPluginType(
114 const std::string
& plugin_mime_type
,
115 const GURL
& plugin_src
) {
116 // If we know plugin's mime type, we use it to determine plugin's type. Else,
117 // we try to determine plugin type using plugin source's extension.
118 if (!plugin_mime_type
.empty())
119 return MimeTypeToPluginType(StringToLowerASCII(plugin_mime_type
));
121 return SrcToPluginType(plugin_src
);
124 PluginUMAReporter::PluginType
PluginUMAReporter::SrcToPluginType(
126 std::string file_extension
;
127 ExtractFileExtension(src
, &file_extension
);
128 if (CStringArrayContainsCString(kWindowsMediaPlayerExtensions
,
129 arraysize(kWindowsMediaPlayerExtensions
),
130 file_extension
.c_str())) {
131 return WINDOWS_MEDIA_PLAYER
;
134 if (CStringArrayContainsCString(kQuickTimeExtensions
,
135 arraysize(kQuickTimeExtensions
),
136 file_extension
.c_str())) {
140 if (CStringArrayContainsCString(kRealPlayerExtensions
,
141 arraysize(kRealPlayerExtensions
),
142 file_extension
.c_str())) {
146 if (CStringArrayContainsCString(kShockwaveFlashExtensions
,
147 arraysize(kShockwaveFlashExtensions
),
148 file_extension
.c_str())) {
149 return SHOCKWAVE_FLASH
;
152 return UNSUPPORTED_EXTENSION
;
155 PluginUMAReporter::PluginType
PluginUMAReporter::MimeTypeToPluginType(
156 const std::string
& mime_type
) {
157 if (mime_type
== kWindowsMediaPlayerType
)
158 return WINDOWS_MEDIA_PLAYER
;
160 size_t prefix_length
= strlen(kSilverlightTypePrefix
);
161 if (strncmp(mime_type
.c_str(), kSilverlightTypePrefix
, prefix_length
) == 0)
164 prefix_length
= strlen(kRealPlayerTypePrefix
);
165 if (strncmp(mime_type
.c_str(), kRealPlayerTypePrefix
, prefix_length
) == 0)
168 if (strstr(mime_type
.c_str(), kJavaTypeSubstring
))
171 if (mime_type
== kQuickTimeType
)
174 if (mime_type
== content::kBrowserPluginMimeType
)
175 return BROWSER_PLUGIN
;
177 if (mime_type
== content::kFlashPluginSwfMimeType
||
178 mime_type
== content::kFlashPluginSplMimeType
) {
179 return SHOCKWAVE_FLASH
;
182 #if defined(ENABLE_PEPPER_CDMS)
183 if (mime_type
== kWidevineCdmPluginMimeType
)
187 return UNSUPPORTED_MIMETYPE
;