15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/plugins/plugin_uma.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/content_constants.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/widevine/cdm/widevine_cdm_common.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// String we will use to convert mime type to plugin type. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kWindowsMediaPlayerType[] = "application/x-mplayer2"; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSilverlightTypePrefix[] = "application/x-silverlight"; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRealPlayerTypePrefix[] = "audio/x-pn-realaudio"; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kJavaTypeSubstring[] = "application/x-java-applet"; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kQuickTimeType[] = "video/quicktime"; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Arrays containing file extensions connected with specific plugins. 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Note: THE ARRAYS MUST BE SORTED BECAUSE BINARY SEARCH IS USED ON THEM! 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char* kWindowsMediaPlayerExtensions[] = {".asx"}; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char* kRealPlayerExtensions[] = {".ra", ".ram", ".rm", 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ".rmm", ".rmp", ".rpm"}; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char* kQuickTimeExtensions[] = {".moov", ".mov", ".qif", 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ".qt", ".qti", ".qtif"}; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char* kShockwaveFlashExtensions[] = {".spl", ".swf"}; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class UMASenderImpl : public PluginUMAReporter::UMASender { 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SendPluginUMA( 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PluginUMAReporter::ReportType report_type, 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PluginUMAReporter::PluginType plugin_type) OVERRIDE; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void UMASenderImpl::SendPluginUMA(PluginUMAReporter::ReportType report_type, 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PluginUMAReporter::PluginType plugin_type) { 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // UMA_HISTOGRAM_ENUMERATION requires constant histogram name. Use string 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // constants explicitly instead of trying to use variables for names. 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (report_type) { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case PluginUMAReporter::MISSING_PLUGIN: 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Plugin.MissingPlugins", 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) plugin_type, 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PluginUMAReporter::PLUGIN_TYPE_MAX); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case PluginUMAReporter::DISABLED_PLUGIN: 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Plugin.DisabledPlugins", 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) plugin_type, 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PluginUMAReporter::PLUGIN_TYPE_MAX); 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED(); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static. 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PluginUMAReporter* PluginUMAReporter::GetInstance() { 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Singleton<PluginUMAReporter>::get(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginUMAReporter::ReportPluginMissing(const std::string& plugin_mime_type, 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& plugin_src) { 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) report_sender_->SendPluginUMA(MISSING_PLUGIN, 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetPluginType(plugin_mime_type, plugin_src)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PluginUMAReporter::ReportPluginDisabled( 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& plugin_mime_type, 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& plugin_src) { 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) report_sender_->SendPluginUMA(DISABLED_PLUGIN, 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetPluginType(plugin_mime_type, plugin_src)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)PluginUMAReporter::PluginUMAReporter() : report_sender_(new UMASenderImpl()) {} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)PluginUMAReporter::~PluginUMAReporter() {} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static. 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool PluginUMAReporter::CompareCStrings(const char* first, const char* second) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return strcmp(first, second) < 0; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool PluginUMAReporter::CStringArrayContainsCString(const char** array, 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t array_size, 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* str) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::binary_search(array, array + array_size, str, CompareCStrings); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PluginUMAReporter::ExtractFileExtension(const GURL& src, 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string* extension) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_file_path(src.ExtractFileName()); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_file_path.empty()) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_file_path = src.host(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t last_dot = extension_file_path.find_last_of('.'); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_dot != std::string::npos) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extension = extension_file_path.substr(last_dot); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension->clear(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::StringToLowerASCII(extension); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PluginUMAReporter::PluginType PluginUMAReporter::GetPluginType( 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& plugin_mime_type, 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& plugin_src) { 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If we know plugin's mime type, we use it to determine plugin's type. Else, 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // we try to determine plugin type using plugin source's extension. 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!plugin_mime_type.empty()) 1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return MimeTypeToPluginType(base::StringToLowerASCII(plugin_mime_type)); 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SrcToPluginType(plugin_src); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PluginUMAReporter::PluginType PluginUMAReporter::SrcToPluginType( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& src) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string file_extension; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtractFileExtension(src, &file_extension); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CStringArrayContainsCString(kWindowsMediaPlayerExtensions, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(kWindowsMediaPlayerExtensions), 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_extension.c_str())) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WINDOWS_MEDIA_PLAYER; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CStringArrayContainsCString(kQuickTimeExtensions, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(kQuickTimeExtensions), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_extension.c_str())) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return QUICKTIME; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CStringArrayContainsCString(kRealPlayerExtensions, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(kRealPlayerExtensions), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_extension.c_str())) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALPLAYER; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (CStringArrayContainsCString(kShockwaveFlashExtensions, 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) arraysize(kShockwaveFlashExtensions), 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_extension.c_str())) { 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SHOCKWAVE_FLASH; 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return UNSUPPORTED_EXTENSION; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PluginUMAReporter::PluginType PluginUMAReporter::MimeTypeToPluginType( 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& mime_type) { 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mime_type == kWindowsMediaPlayerType) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WINDOWS_MEDIA_PLAYER; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t prefix_length = strlen(kSilverlightTypePrefix); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strncmp(mime_type.c_str(), kSilverlightTypePrefix, prefix_length) == 0) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SILVERLIGHT; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix_length = strlen(kRealPlayerTypePrefix); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strncmp(mime_type.c_str(), kRealPlayerTypePrefix, prefix_length) == 0) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALPLAYER; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strstr(mime_type.c_str(), kJavaTypeSubstring)) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JAVA; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mime_type == kQuickTimeType) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return QUICKTIME; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mime_type == content::kBrowserPluginMimeType) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return BROWSER_PLUGIN; 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (mime_type == content::kFlashPluginSwfMimeType || 178ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch mime_type == content::kFlashPluginSplMimeType) { 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SHOCKWAVE_FLASH; 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(ENABLE_PEPPER_CDMS) 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mime_type == kWidevineCdmPluginMimeType) 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return WIDEVINE_CDM; 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return UNSUPPORTED_MIMETYPE; 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 189