OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/renderer/plugins/plugin_uma.h" | |
6 | |
7 #include <algorithm> | |
8 #include <cstring> | |
9 | |
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" | |
14 | |
15 namespace { | |
16 | |
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"; | |
23 | |
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[] = { | |
27 ".asx" | |
28 }; | |
29 | |
30 const char* kRealPlayerExtensions[] = { | |
31 ".ra", | |
32 ".ram", | |
33 ".rm", | |
34 ".rmm", | |
35 ".rmp", | |
36 ".rpm" | |
37 }; | |
38 | |
39 const char* kQuickTimeExtensions[] = { | |
40 ".moov", | |
41 ".mov", | |
42 ".qif", | |
43 ".qt", | |
44 ".qti", | |
45 ".qtif" | |
46 }; | |
47 | |
48 const char* kShockwaveFlashExtensions[] = { | |
49 ".spl", | |
50 ".swf" | |
51 }; | |
52 | |
53 } // namespace. | |
54 | |
55 class UMASenderImpl : public PluginUMAReporter::UMASender { | |
56 virtual void SendPluginUMA( | |
57 PluginUMAReporter::ReportType report_type, | |
58 PluginUMAReporter::PluginType plugin_type) OVERRIDE; | |
59 }; | |
60 | |
61 void UMASenderImpl::SendPluginUMA(PluginUMAReporter::ReportType report_type, | |
62 PluginUMAReporter::PluginType plugin_type) { | |
63 // UMA_HISTOGRAM_ENUMERATION requires constant histogram name. Use string | |
64 // constants explicitly instead of trying to use variables for names. | |
65 switch (report_type) { | |
66 case PluginUMAReporter::MISSING_PLUGIN: | |
67 UMA_HISTOGRAM_ENUMERATION("Plugin.MissingPlugins", | |
68 plugin_type, | |
69 PluginUMAReporter::PLUGIN_TYPE_MAX); | |
70 break; | |
71 case PluginUMAReporter::DISABLED_PLUGIN: | |
72 UMA_HISTOGRAM_ENUMERATION("Plugin.DisabledPlugins", | |
73 plugin_type, | |
74 PluginUMAReporter::PLUGIN_TYPE_MAX); | |
75 break; | |
76 default: | |
77 NOTREACHED(); | |
78 } | |
79 } | |
80 | |
81 // static. | |
82 PluginUMAReporter* PluginUMAReporter::GetInstance() { | |
83 return Singleton<PluginUMAReporter>::get(); | |
84 } | |
85 | |
86 void PluginUMAReporter::ReportPluginMissing( | |
87 const std::string& plugin_mime_type, const GURL& plugin_src) { | |
88 report_sender_->SendPluginUMA(MISSING_PLUGIN, | |
89 GetPluginType(plugin_mime_type, plugin_src)); | |
90 } | |
91 | |
92 void PluginUMAReporter::ReportPluginDisabled( | |
93 const std::string& plugin_mime_type, const GURL& plugin_src) { | |
94 report_sender_->SendPluginUMA(DISABLED_PLUGIN, | |
95 GetPluginType(plugin_mime_type, plugin_src)); | |
96 } | |
97 | |
98 PluginUMAReporter::PluginUMAReporter() : report_sender_(new UMASenderImpl()) { | |
99 } | |
100 | |
101 PluginUMAReporter::~PluginUMAReporter() { | |
102 } | |
103 | |
104 // static. | |
105 bool PluginUMAReporter::CompareCStrings(const char* first, const char* second) { | |
106 return strcmp(first, second) < 0; | |
107 } | |
108 | |
109 bool PluginUMAReporter::CStringArrayContainsCString(const char** array, | |
110 size_t array_size, | |
111 const char* str) { | |
112 return std::binary_search(array, array + array_size, str, CompareCStrings); | |
113 } | |
114 | |
115 void PluginUMAReporter::ExtractFileExtension(const GURL& src, | |
116 std::string* extension) { | |
117 std::string extension_file_path(src.ExtractFileName()); | |
118 if (extension_file_path.empty()) | |
119 extension_file_path = src.host(); | |
120 | |
121 size_t last_dot = extension_file_path.find_last_of('.'); | |
122 if (last_dot != std::string::npos) { | |
123 *extension = extension_file_path.substr(last_dot); | |
124 } else { | |
125 extension->clear(); | |
126 } | |
127 | |
128 StringToLowerASCII(extension); | |
129 } | |
130 | |
131 PluginUMAReporter::PluginType PluginUMAReporter::GetPluginType( | |
132 const std::string& plugin_mime_type, const GURL& plugin_src) { | |
133 // If we know plugin's mime type, we use it to determine plugin's type. Else, | |
134 // we try to determine plugin type using plugin source's extension. | |
135 if (!plugin_mime_type.empty()) | |
136 return MimeTypeToPluginType(StringToLowerASCII(plugin_mime_type)); | |
137 | |
138 return SrcToPluginType(plugin_src); | |
139 } | |
140 | |
141 PluginUMAReporter::PluginType PluginUMAReporter::SrcToPluginType( | |
142 const GURL& src) { | |
143 std::string file_extension; | |
144 ExtractFileExtension(src, &file_extension); | |
145 if (CStringArrayContainsCString(kWindowsMediaPlayerExtensions, | |
146 arraysize(kWindowsMediaPlayerExtensions), | |
147 file_extension.c_str())) { | |
148 return WINDOWS_MEDIA_PLAYER; | |
149 } | |
150 | |
151 if (CStringArrayContainsCString(kQuickTimeExtensions, | |
152 arraysize(kQuickTimeExtensions), | |
153 file_extension.c_str())) { | |
154 return QUICKTIME; | |
155 } | |
156 | |
157 if (CStringArrayContainsCString(kRealPlayerExtensions, | |
158 arraysize(kRealPlayerExtensions), | |
159 file_extension.c_str())) { | |
160 return REALPLAYER; | |
161 } | |
162 | |
163 if (CStringArrayContainsCString(kShockwaveFlashExtensions, | |
164 arraysize(kShockwaveFlashExtensions), | |
165 file_extension.c_str())) { | |
166 return SHOCKWAVE_FLASH; | |
167 } | |
168 | |
169 return UNSUPPORTED_EXTENSION; | |
170 } | |
171 | |
172 PluginUMAReporter::PluginType PluginUMAReporter::MimeTypeToPluginType( | |
173 const std::string& mime_type) { | |
174 if (mime_type == kWindowsMediaPlayerType) | |
175 return WINDOWS_MEDIA_PLAYER; | |
176 | |
177 size_t prefix_length = strlen(kSilverlightTypePrefix); | |
178 if (strncmp(mime_type.c_str(), kSilverlightTypePrefix, prefix_length) == 0) | |
179 return SILVERLIGHT; | |
180 | |
181 prefix_length = strlen(kRealPlayerTypePrefix); | |
182 if (strncmp(mime_type.c_str(), kRealPlayerTypePrefix, prefix_length) == 0) | |
183 return REALPLAYER; | |
184 | |
185 if (strstr(mime_type.c_str(), kJavaTypeSubstring)) | |
186 return JAVA; | |
187 | |
188 if (mime_type == kQuickTimeType) | |
189 return QUICKTIME; | |
190 | |
191 if (mime_type == content::kBrowserPluginMimeType) | |
192 return BROWSER_PLUGIN; | |
193 | |
194 if (mime_type == content::kFlashPluginSwfMimeType || | |
195 mime_type == content::kFlashPluginSplMimeType) { | |
196 return SHOCKWAVE_FLASH; | |
197 } | |
198 | |
199 #if defined(ENABLE_PEPPER_CDMS) | |
200 if (mime_type == kWidevineCdmPluginMimeType) | |
201 return WIDEVINE_CDM; | |
202 #endif | |
203 | |
204 return UNSUPPORTED_MIMETYPE; | |
205 } | |
OLD | NEW |