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