plugin_info_message_filter.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/plugins/plugin_info_message_filter.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h" 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/metrics/histogram.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/prefs/pref_service.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/content_settings/content_settings_utils.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/plugins/chrome_plugin_service_filter.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/plugins/plugin_finder.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/plugins/plugin_metadata.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/plugins/plugin_prefs.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/content_settings.h" 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/common/pref_names.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/render_messages.h" 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/plugin_service.h" 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/plugin_service_filter.h" 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "url/gurl.h" 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_EXTENSIONS) 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/guest_view/web_view/web_view_renderer_state.h" 31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_WIN) 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/win/metro.h" 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(DISABLE_NACL) 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/nacl/common/nacl_constants.h" 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using content::PluginService; 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using content::WebPluginInfo; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// For certain sandboxed Pepper plugins, use the JavaScript Content Settings. 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShouldUseJavaScriptSettingForPlugin(const WebPluginInfo& plugin) { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS && 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS) { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if !defined(DISABLE_NACL) 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Treat Native Client invocations like JavaScript. 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (plugin.name == base::ASCIIToUTF16(nacl::kNaClPluginName)) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Treat CDM invocations like JavaScript. 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (plugin.name == base::ASCIIToUTF16(kWidevineCdmDisplayName)) { 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(plugin.type == WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS); 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(ENABLE_PEPPER_CDMS) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum PluginAvailabilityStatusForUMA { 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PLUGIN_NOT_REGISTERED, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PLUGIN_AVAILABLE, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PLUGIN_DISABLED, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PLUGIN_AVAILABILITY_STATUS_MAX 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void SendPluginAvailabilityUMA(const std::string& mime_type, 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PluginAvailabilityStatusForUMA status) { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(WIDEVINE_CDM_AVAILABLE) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only report results for Widevine CDM. 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mime_type != kWidevineCdmPluginMimeType) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Plugin.AvailabilityStatus.WidevineCdm", 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) status, PLUGIN_AVAILABILITY_STATUS_MAX); 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif // defined(WIDEVINE_CDM_AVAILABLE) 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif // defined(ENABLE_PEPPER_CDMS) 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)PluginInfoMessageFilter::Context::Context(int render_process_id, 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Profile* profile) 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : render_process_id_(render_process_id), 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) resource_context_(profile->GetResourceContext()), 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_content_settings_map_(profile->GetHostContentSettingsMap()), 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) plugin_prefs_(PluginPrefs::GetForProfile(profile)) { 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) allow_outdated_plugins_.Init(prefs::kPluginsAllowOutdated, 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) profile->GetPrefs()); 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) allow_outdated_plugins_.MoveToThread( 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserThread::GetMessageLoopProxyForThread( 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserThread::IO)); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) always_authorize_plugins_.Init(prefs::kPluginsAlwaysAuthorize, 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) profile->GetPrefs()); 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) always_authorize_plugins_.MoveToThread( 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::GetMessageLoopProxyForThread( 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::IO)); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PluginInfoMessageFilter::Context::~Context() { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PluginInfoMessageFilter::PluginInfoMessageFilter( 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int render_process_id, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : BrowserMessageFilter(ChromeMsgStart), 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_(render_process_id, profile), 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_(this) { 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PluginInfoMessageFilter::OnMessageReceived(const IPC::Message& message) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(PluginInfoMessageFilter, message) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_GetPluginInfo, 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnGetPluginInfo) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_PEPPER_CDMS) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER( 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChromeViewHostMsg_IsInternalPluginAvailableForMimeType, 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnIsInternalPluginAvailableForMimeType) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_UNHANDLED(return false) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_END_MESSAGE_MAP() 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginInfoMessageFilter::OnDestruct() const { 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const_cast<PluginInfoMessageFilter*>(this)-> 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Destroy on the UI thread because we contain a |PrefMember|. 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserThread::DeleteOnUIThread::Destruct(this); 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)PluginInfoMessageFilter::~PluginInfoMessageFilter() {} 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)struct PluginInfoMessageFilter::GetPluginInfo_Params { 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int render_frame_id; 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GURL url; 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GURL top_origin_url; 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string mime_type; 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PluginInfoMessageFilter::OnGetPluginInfo( 1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int render_frame_id, 1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const GURL& url, 1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const GURL& top_origin_url, 1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const std::string& mime_type, 1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) IPC::Message* reply_msg) { 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetPluginInfo_Params params = { 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) render_frame_id, 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) url, 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) top_origin_url, 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) mime_type 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }; 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PluginService::GetInstance()->GetPlugins( 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(&PluginInfoMessageFilter::PluginsLoaded, 16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) params, reply_msg)); 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PluginInfoMessageFilter::PluginsLoaded( 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GetPluginInfo_Params& params, 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IPC::Message* reply_msg, 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<WebPluginInfo>& plugins) { 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ChromeViewHostMsg_GetPluginInfo_Output output; 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // This also fills in |actual_mime_type|. 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<PluginMetadata> plugin_metadata; 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (context_.FindEnabledPlugin(params.render_frame_id, params.url, 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params.top_origin_url, params.mime_type, 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &output.status, &output.plugin, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &output.actual_mime_type, 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &plugin_metadata)) { 1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) context_.DecidePluginStatus(params, output.plugin, plugin_metadata.get(), 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &output.status); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (plugin_metadata) { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output.group_identifier = plugin_metadata->identifier(); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output.group_name = plugin_metadata->name(); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_.MaybeGrantAccess(output.status, output.plugin.path); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ChromeViewHostMsg_GetPluginInfo::WriteReplyParams(reply_msg, output); 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Send(reply_msg); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_PEPPER_CDMS) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PluginInfoMessageFilter::OnIsInternalPluginAvailableForMimeType( 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& mime_type, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* is_available, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::string16>* additional_param_names, 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::string16>* additional_param_values) { 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<WebPluginInfo> plugins; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PluginService::GetInstance()->GetInternalPlugins(&plugins); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_plugin_disabled = false; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < plugins.size(); ++i) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebPluginInfo& plugin = plugins[i]; 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<content::WebPluginMimeType>& mime_types = 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) plugin.mime_types; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t j = 0; j < mime_types.size(); ++j) { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (mime_types[j].mime_type == mime_type) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context_.IsPluginEnabled(plugin)) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_plugin_disabled = true; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222 *is_available = true; 223 *additional_param_names = mime_types[j].additional_param_names; 224 *additional_param_values = mime_types[j].additional_param_values; 225 SendPluginAvailabilityUMA(mime_type, PLUGIN_AVAILABLE); 226 return; 227 } 228 } 229 } 230 231 *is_available = false; 232 SendPluginAvailabilityUMA( 233 mime_type, is_plugin_disabled ? PLUGIN_DISABLED : PLUGIN_NOT_REGISTERED); 234} 235 236#endif // defined(ENABLE_PEPPER_CDMS) 237 238void PluginInfoMessageFilter::Context::DecidePluginStatus( 239 const GetPluginInfo_Params& params, 240 const WebPluginInfo& plugin, 241 const PluginMetadata* plugin_metadata, 242 ChromeViewHostMsg_GetPluginInfo_Status* status) const { 243#if defined(OS_WIN) 244 if (plugin.type == WebPluginInfo::PLUGIN_TYPE_NPAPI && 245 base::win::IsMetroProcess()) { 246 status->value = 247 ChromeViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported; 248 return; 249 } 250#endif 251 if (plugin.type == WebPluginInfo::PLUGIN_TYPE_NPAPI) { 252 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 253 // NPAPI plugins are not supported inside <webview> guests. 254#if defined(ENABLE_EXTENSIONS) 255 if (extensions::WebViewRendererState::GetInstance()->IsGuest( 256 render_process_id_)) { 257 status->value = 258 ChromeViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported; 259 return; 260 } 261#endif 262 } 263 264 ContentSetting plugin_setting = CONTENT_SETTING_DEFAULT; 265 bool uses_default_content_setting = true; 266 bool is_managed = false; 267 // Check plug-in content settings. The primary URL is the top origin URL and 268 // the secondary URL is the plug-in URL. 269 GetPluginContentSetting(plugin, params.top_origin_url, params.url, 270 plugin_metadata->identifier(), &plugin_setting, 271 &uses_default_content_setting, &is_managed); 272 DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT); 273 274 PluginMetadata::SecurityStatus plugin_status = 275 plugin_metadata->GetSecurityStatus(plugin); 276#if defined(ENABLE_PLUGIN_INSTALLATION) 277 // Check if the plug-in is outdated. 278 if (plugin_status == PluginMetadata::SECURITY_STATUS_OUT_OF_DATE && 279 !allow_outdated_plugins_.GetValue()) { 280 if (allow_outdated_plugins_.IsManaged()) { 281 status->value = 282 ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed; 283 } else { 284 status->value = ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked; 285 } 286 return; 287 } 288#endif 289 // Check if the plug-in or its group is enabled by policy. 290 PluginPrefs::PolicyStatus plugin_policy = 291 plugin_prefs_->PolicyStatusForPlugin(plugin.name); 292 PluginPrefs::PolicyStatus group_policy = 293 plugin_prefs_->PolicyStatusForPlugin(plugin_metadata->name()); 294 295 // Check if the plug-in requires authorization. 296 if (plugin_status == 297 PluginMetadata::SECURITY_STATUS_REQUIRES_AUTHORIZATION && 298 plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS && 299 plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS && 300 !always_authorize_plugins_.GetValue() && 301 plugin_setting != CONTENT_SETTING_BLOCK && 302 uses_default_content_setting && 303 plugin_policy != PluginPrefs::POLICY_ENABLED && 304 group_policy != PluginPrefs::POLICY_ENABLED && 305 !ChromePluginServiceFilter::GetInstance()->IsPluginRestricted( 306 plugin.path)) { 307 status->value = ChromeViewHostMsg_GetPluginInfo_Status::kUnauthorized; 308 return; 309 } 310 311 // Check if the plug-in is crashing too much. 312 if (PluginService::GetInstance()->IsPluginUnstable(plugin.path) && 313 !always_authorize_plugins_.GetValue() && 314 plugin_setting != CONTENT_SETTING_BLOCK && 315 uses_default_content_setting) { 316 status->value = ChromeViewHostMsg_GetPluginInfo_Status::kUnauthorized; 317 return; 318 } 319 320 if (plugin_setting == CONTENT_SETTING_ASK) { 321 status->value = ChromeViewHostMsg_GetPluginInfo_Status::kClickToPlay; 322 } else if (plugin_setting == CONTENT_SETTING_BLOCK) { 323 status->value = 324 is_managed ? ChromeViewHostMsg_GetPluginInfo_Status::kBlockedByPolicy 325 : ChromeViewHostMsg_GetPluginInfo_Status::kBlocked; 326 } 327 328 if (status->value == ChromeViewHostMsg_GetPluginInfo_Status::kAllowed) { 329 // Allow an embedder of <webview> to block a plugin from being loaded inside 330 // the guest. In order to do this, set the status to 'Unauthorized' here, 331 // and update the status as appropriate depending on the response from the 332 // embedder. 333#if defined(ENABLE_EXTENSIONS) 334 if (extensions::WebViewRendererState::GetInstance()->IsGuest( 335 render_process_id_)) 336 status->value = ChromeViewHostMsg_GetPluginInfo_Status::kUnauthorized; 337 338#endif 339 } 340} 341 342bool PluginInfoMessageFilter::Context::FindEnabledPlugin( 343 int render_frame_id, 344 const GURL& url, 345 const GURL& top_origin_url, 346 const std::string& mime_type, 347 ChromeViewHostMsg_GetPluginInfo_Status* status, 348 WebPluginInfo* plugin, 349 std::string* actual_mime_type, 350 scoped_ptr<PluginMetadata>* plugin_metadata) const { 351 bool allow_wildcard = true; 352 std::vector<WebPluginInfo> matching_plugins; 353 std::vector<std::string> mime_types; 354 PluginService::GetInstance()->GetPluginInfoArray( 355 url, mime_type, allow_wildcard, &matching_plugins, &mime_types); 356 if (matching_plugins.empty()) { 357 status->value = ChromeViewHostMsg_GetPluginInfo_Status::kNotFound; 358 return false; 359 } 360 361 content::PluginServiceFilter* filter = 362 PluginService::GetInstance()->GetFilter(); 363 size_t i = 0; 364 for (; i < matching_plugins.size(); ++i) { 365 if (!filter || filter->IsPluginAvailable(render_process_id_, 366 render_frame_id, 367 resource_context_, 368 url, 369 top_origin_url, 370 &matching_plugins[i])) { 371 break; 372 } 373 } 374 375 // If we broke out of the loop, we have found an enabled plug-in. 376 bool enabled = i < matching_plugins.size(); 377 if (!enabled) { 378 // Otherwise, we only found disabled plug-ins, so we take the first one. 379 i = 0; 380 status->value = ChromeViewHostMsg_GetPluginInfo_Status::kDisabled; 381 } 382 383 *plugin = matching_plugins[i]; 384 *actual_mime_type = mime_types[i]; 385 if (plugin_metadata) 386 *plugin_metadata = PluginFinder::GetInstance()->GetPluginMetadata(*plugin); 387 388 return enabled; 389} 390 391void PluginInfoMessageFilter::Context::GetPluginContentSetting( 392 const WebPluginInfo& plugin, 393 const GURL& policy_url, 394 const GURL& plugin_url, 395 const std::string& resource, 396 ContentSetting* setting, 397 bool* uses_default_content_setting, 398 bool* is_managed) const { 399 scoped_ptr<base::Value> value; 400 content_settings::SettingInfo info; 401 bool uses_plugin_specific_setting = false; 402 if (ShouldUseJavaScriptSettingForPlugin(plugin)) { 403 value.reset( 404 host_content_settings_map_->GetWebsiteSetting( 405 policy_url, policy_url, CONTENT_SETTINGS_TYPE_JAVASCRIPT, 406 std::string(), &info)); 407 } else { 408 content_settings::SettingInfo specific_info; 409 scoped_ptr<base::Value> specific_setting( 410 host_content_settings_map_->GetWebsiteSetting( 411 policy_url, plugin_url, CONTENT_SETTINGS_TYPE_PLUGINS, resource, 412 &specific_info)); 413 content_settings::SettingInfo general_info; 414 scoped_ptr<base::Value> general_setting( 415 host_content_settings_map_->GetWebsiteSetting( 416 policy_url, plugin_url, CONTENT_SETTINGS_TYPE_PLUGINS, 417 std::string(), &general_info)); 418 419 // If there is a plugin-specific setting, we use it, unless the general 420 // setting was set by policy, in which case it takes precedence. 421 uses_plugin_specific_setting = specific_setting && 422 (general_info.source != content_settings::SETTING_SOURCE_POLICY); 423 if (uses_plugin_specific_setting) { 424 value = specific_setting.Pass(); 425 info = specific_info; 426 } else { 427 value = general_setting.Pass(); 428 info = general_info; 429 } 430 } 431 *setting = content_settings::ValueToContentSetting(value.get()); 432 *uses_default_content_setting = 433 !uses_plugin_specific_setting && 434 info.primary_pattern == ContentSettingsPattern::Wildcard() && 435 info.secondary_pattern == ContentSettingsPattern::Wildcard(); 436 *is_managed = info.source == content_settings::SETTING_SOURCE_POLICY; 437} 438 439void PluginInfoMessageFilter::Context::MaybeGrantAccess( 440 const ChromeViewHostMsg_GetPluginInfo_Status& status, 441 const base::FilePath& path) const { 442 if (status.value == ChromeViewHostMsg_GetPluginInfo_Status::kAllowed || 443 status.value == ChromeViewHostMsg_GetPluginInfo_Status::kClickToPlay) { 444 ChromePluginServiceFilter::GetInstance()->AuthorizePlugin( 445 render_process_id_, path); 446 } 447} 448 449bool PluginInfoMessageFilter::Context::IsPluginEnabled( 450 const content::WebPluginInfo& plugin) const { 451 return plugin_prefs_->IsPluginEnabled(plugin); 452} 453