plugin_info_message_filter.cc revision f2477e01787aa58f445919b809d89e252beef54f
133873d2b41a5cd2597b20a4e88eb8942944c0f23Tyler Schultz// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard// Use of this source code is governed by a BSD-style license that can be
3bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard// found in the LICENSE file.
4bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard
522c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwin#include "chrome/browser/plugins/plugin_info_message_filter.h"
622c22c9aa4ca68c2deac6164edc1d82bc9645310Christian Williams & Phil Goodwin
770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "base/bind.h"
8bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard#include "base/memory/scoped_ptr.h"
928da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "base/metrics/histogram.h"
1028da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "base/prefs/pref_service.h"
1128da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "base/strings/utf_string_conversions.h"
1228da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "chrome/browser/content_settings/content_settings_utils.h"
1328da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "chrome/browser/content_settings/host_content_settings_map.h"
1428da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "chrome/browser/extensions/extension_renderer_state.h"
1528da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
1628da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "chrome/browser/plugins/plugin_finder.h"
1728da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "chrome/browser/plugins/plugin_metadata.h"
1828da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz#include "chrome/browser/plugins/plugin_prefs.h"
19bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard#include "chrome/browser/profiles/profile.h"
20bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard#include "chrome/common/chrome_content_client.h"
21afe0a89d904a7fe2f5980b9deb26cc3240192459Christian Williams#include "chrome/common/content_settings.h"
2270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "chrome/common/pref_names.h"
2370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "chrome/common/render_messages.h"
2470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "content/public/browser/browser_thread.h"
2570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "content/public/browser/plugin_service.h"
2670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "content/public/browser/plugin_service_filter.h"
2770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "url/gurl.h"
2870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
2970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "widevine_cdm_version.h"  // In SHARED_INTERMEDIATE_DIR.
3070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
3170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#if defined(OS_WIN)
3270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#include "base/win/metro.h"
3370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#endif
3470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
3570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadusing content::PluginService;
3670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadusing content::WebPluginInfo;
3770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
3870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadnamespace {
3970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
4070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead// For certain sandboxed Pepper plugins, use the JavaScript Content Settings.
4170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadbool ShouldUseJavaScriptSettingForPlugin(const WebPluginInfo& plugin) {
4270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  if (plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS &&
4370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS) {
4470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    return false;
4570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  }
4670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
4770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  // Treat Native Client invocations like JavaScript.
4870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  if (plugin.name == ASCIIToUTF16(ChromeContentClient::kNaClPluginName))
4970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    return true;
5070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
5170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
5270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  // Treat CDM invocations like JavaScript.
5370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  if (plugin.name == ASCIIToUTF16(kWidevineCdmDisplayName)) {
5470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    DCHECK(plugin.type == WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS);
5570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    return true;
5670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  }
5770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#endif  // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
5870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
5970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  return false;
6070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}
6170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
6270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}  // namespace
6370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
6470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadPluginInfoMessageFilter::Context::Context(int render_process_id,
6570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                                          Profile* profile)
6670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    : render_process_id_(render_process_id),
6770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      resource_context_(profile->GetResourceContext()),
6870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      host_content_settings_map_(profile->GetHostContentSettingsMap()),
6970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      plugin_prefs_(PluginPrefs::GetForProfile(profile)) {
7070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  allow_outdated_plugins_.Init(prefs::kPluginsAllowOutdated,
7170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                               profile->GetPrefs());
7270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  allow_outdated_plugins_.MoveToThread(
7370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      content::BrowserThread::GetMessageLoopProxyForThread(
7470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead          content::BrowserThread::IO));
7570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  always_authorize_plugins_.Init(prefs::kPluginsAlwaysAuthorize,
7670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                                 profile->GetPrefs());
7770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  always_authorize_plugins_.MoveToThread(
7870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      content::BrowserThread::GetMessageLoopProxyForThread(
7970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead          content::BrowserThread::IO));
8070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}
8170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
8270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadPluginInfoMessageFilter::Context::Context()
8370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    : render_process_id_(0),
8470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      resource_context_(NULL),
8570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      host_content_settings_map_(NULL) {
8670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}
8770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
8870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadPluginInfoMessageFilter::Context::~Context() {
8970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}
9070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
9170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadPluginInfoMessageFilter::PluginInfoMessageFilter(
9270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    int render_process_id,
9370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    Profile* profile)
9470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    : context_(render_process_id, profile),
9570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      weak_ptr_factory_(this) {
96de9feed5ddf1d91a3e76cbc71712c36a7652201eChristian Williams}
97bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard
9828da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultzbool PluginInfoMessageFilter::OnMessageReceived(const IPC::Message& message,
9928da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz                                                bool* message_was_ok) {
10028da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz  IPC_BEGIN_MESSAGE_MAP_EX(PluginInfoMessageFilter, message, *message_was_ok)
10128da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz    IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_GetPluginInfo,
10228da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz                                    OnGetPluginInfo)
10328da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz    IPC_MESSAGE_HANDLER(
10428da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz        ChromeViewHostMsg_IsInternalPluginRegisteredForMimeType,
10528da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz        OnIsInternalPluginRegisteredForMimeType)
10628da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz    IPC_MESSAGE_UNHANDLED(return false)
10728da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz  IPC_END_MESSAGE_MAP()
10828da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz  return true;
10928da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz}
11028da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz
11128da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultzvoid PluginInfoMessageFilter::OnDestruct() const {
11228da27e00f41dcfb8e3cc162644550147d3892e7Tyler Schultz  const_cast<PluginInfoMessageFilter*>(this)->
113bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard      weak_ptr_factory_.InvalidateWeakPtrs();
11470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
11570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  // Destroy on the UI thread because we contain a |PrefMember|.
11670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  content::BrowserThread::DeleteOnUIThread::Destruct(this);
11770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}
11870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
11970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadPluginInfoMessageFilter::~PluginInfoMessageFilter() {}
12070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
12170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadstruct PluginInfoMessageFilter::GetPluginInfo_Params {
12270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  int render_view_id;
12370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  GURL url;
12470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  GURL top_origin_url;
12570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  std::string mime_type;
12670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead};
12770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
12870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadvoid PluginInfoMessageFilter::OnGetPluginInfo(
12970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    int render_view_id,
13070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const GURL& url,
13170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const GURL& top_origin_url,
13270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const std::string& mime_type,
13370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    IPC::Message* reply_msg) {
13470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  GetPluginInfo_Params params = {
13570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    render_view_id,
13670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    url,
13770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    top_origin_url,
13870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    mime_type
13970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  };
14070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  PluginService::GetInstance()->GetPlugins(
14170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      base::Bind(&PluginInfoMessageFilter::PluginsLoaded,
14270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                 weak_ptr_factory_.GetWeakPtr(),
14370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                 params, reply_msg));
14470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}
14570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
14670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadvoid PluginInfoMessageFilter::PluginsLoaded(
14770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const GetPluginInfo_Params& params,
14870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    IPC::Message* reply_msg,
14970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const std::vector<WebPluginInfo>& plugins) {
15070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  ChromeViewHostMsg_GetPluginInfo_Output output;
15170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  // This also fills in |actual_mime_type|.
15270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  scoped_ptr<PluginMetadata> plugin_metadata;
15370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  if (context_.FindEnabledPlugin(params.render_view_id, params.url,
15470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                                 params.top_origin_url, params.mime_type,
15570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                                 &output.status, &output.plugin,
15670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                                 &output.actual_mime_type,
15770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                                 &plugin_metadata)) {
15870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    context_.DecidePluginStatus(params, output.plugin, plugin_metadata.get(),
15970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead                                &output.status);
16070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  }
16170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
16270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  if (plugin_metadata) {
16370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    output.group_identifier = plugin_metadata->identifier();
16470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    output.group_name = plugin_metadata->name();
16570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  }
16670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
16770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  context_.MaybeGrantAccess(output.status, output.plugin.path);
16870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
16970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  ChromeViewHostMsg_GetPluginInfo::WriteReplyParams(reply_msg, output);
17070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  Send(reply_msg);
17170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}
17270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
17370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadvoid PluginInfoMessageFilter::OnIsInternalPluginRegisteredForMimeType(
17470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const std::string& mime_type,
17570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    bool* is_registered,
17670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    std::vector<base::string16>* additional_param_names,
17770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    std::vector<base::string16>* additional_param_values) {
17870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  std::vector<WebPluginInfo> plugins;
17970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  PluginService::GetInstance()->GetInternalPlugins(&plugins);
18070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  for (size_t i = 0; i < plugins.size(); ++i) {
18170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const std::vector<content::WebPluginMimeType>& mime_types =
18270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead        plugins[i].mime_types;
18370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    for (size_t j = 0; j < mime_types.size(); ++j) {
18470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      if (mime_types[j].mime_type == mime_type) {
18570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead        *is_registered = true;
18670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead        *additional_param_names = mime_types[j].additional_param_names;
18770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead        *additional_param_values = mime_types[j].additional_param_values;
18870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead        return;
18970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      }
19070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    }
19170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  }
19270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
19370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  *is_registered = false;
19470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead}
19570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead
19670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalheadvoid PluginInfoMessageFilter::Context::DecidePluginStatus(
19770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const GetPluginInfo_Params& params,
19870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const WebPluginInfo& plugin,
19970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    const PluginMetadata* plugin_metadata,
20070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    ChromeViewHostMsg_GetPluginInfo_Status* status) const {
20170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#if defined(OS_WIN)
20270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  if (plugin.type == WebPluginInfo::PLUGIN_TYPE_NPAPI &&
20370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      base::win::IsMetroProcess()) {
20470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    status->value =
20570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead        ChromeViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported;
20670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    return;
20770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  }
20870ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead#endif
20970ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead  if (plugin.type == WebPluginInfo::PLUGIN_TYPE_NPAPI) {
21070ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
21170ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    // NPAPI plugins are not supported inside <webview> guests.
21270ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    ExtensionRendererState::WebViewInfo info;
21370ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead    if (ExtensionRendererState::GetInstance()->GetWebViewInfo(
21470ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead            render_process_id_, params.render_view_id, &info)) {
21570ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      status->value =
21670ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead          ChromeViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported;
21770ffa98f3d32a2fd7aae7cb4ddce5fd31754cfe5metalhead      return;
218bc13a3d997b9ff39a55543d59d75231d90f8fca3Joe Moore & Ryan Richard    }
219  }
220
221  ContentSetting plugin_setting = CONTENT_SETTING_DEFAULT;
222  bool uses_default_content_setting = true;
223  // Check plug-in content settings. The primary URL is the top origin URL and
224  // the secondary URL is the plug-in URL.
225  GetPluginContentSetting(plugin, params.top_origin_url, params.url,
226                          plugin_metadata->identifier(), &plugin_setting,
227                          &uses_default_content_setting);
228  DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT);
229
230  PluginMetadata::SecurityStatus plugin_status =
231      plugin_metadata->GetSecurityStatus(plugin);
232#if defined(ENABLE_PLUGIN_INSTALLATION)
233  // Check if the plug-in is outdated.
234  if (plugin_status == PluginMetadata::SECURITY_STATUS_OUT_OF_DATE &&
235      !allow_outdated_plugins_.GetValue()) {
236    if (allow_outdated_plugins_.IsManaged()) {
237      status->value =
238          ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed;
239    } else {
240      status->value = ChromeViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked;
241    }
242    return;
243  }
244#endif
245  // Check if the plug-in or its group is enabled by policy.
246  PluginPrefs::PolicyStatus plugin_policy =
247      plugin_prefs_->PolicyStatusForPlugin(plugin.name);
248  PluginPrefs::PolicyStatus group_policy =
249      plugin_prefs_->PolicyStatusForPlugin(plugin_metadata->name());
250
251  // Check if the plug-in requires authorization.
252  if (plugin_status ==
253          PluginMetadata::SECURITY_STATUS_REQUIRES_AUTHORIZATION &&
254      plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS &&
255      plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS &&
256      !always_authorize_plugins_.GetValue() &&
257      plugin_setting != CONTENT_SETTING_BLOCK &&
258      uses_default_content_setting &&
259      plugin_policy != PluginPrefs::POLICY_ENABLED &&
260      group_policy != PluginPrefs::POLICY_ENABLED &&
261      !ChromePluginServiceFilter::GetInstance()->IsPluginRestricted(
262          plugin.path)) {
263    status->value = ChromeViewHostMsg_GetPluginInfo_Status::kUnauthorized;
264    return;
265  }
266
267  // Check if the plug-in is crashing too much.
268  if (PluginService::GetInstance()->IsPluginUnstable(plugin.path) &&
269      !always_authorize_plugins_.GetValue() &&
270      plugin_setting != CONTENT_SETTING_BLOCK &&
271      uses_default_content_setting) {
272    status->value = ChromeViewHostMsg_GetPluginInfo_Status::kUnauthorized;
273    return;
274  }
275
276  if (plugin_setting == CONTENT_SETTING_ASK)
277    status->value = ChromeViewHostMsg_GetPluginInfo_Status::kClickToPlay;
278  else if (plugin_setting == CONTENT_SETTING_BLOCK)
279    status->value = ChromeViewHostMsg_GetPluginInfo_Status::kBlocked;
280
281  if (status->value == ChromeViewHostMsg_GetPluginInfo_Status::kAllowed) {
282    // Allow an embedder of <webview> to block a plugin from being loaded inside
283    // the guest. In order to do this, set the status to 'Unauthorized' here,
284    // and update the status as appropriate depending on the response from the
285    // embedder.
286    ExtensionRendererState::WebViewInfo info;
287    if (ExtensionRendererState::GetInstance()->GetWebViewInfo(
288            render_process_id_, params.render_view_id, &info)) {
289      status->value =
290          ChromeViewHostMsg_GetPluginInfo_Status::kUnauthorized;
291    }
292  }
293}
294
295bool PluginInfoMessageFilter::Context::FindEnabledPlugin(
296    int render_view_id,
297    const GURL& url,
298    const GURL& top_origin_url,
299    const std::string& mime_type,
300    ChromeViewHostMsg_GetPluginInfo_Status* status,
301    WebPluginInfo* plugin,
302    std::string* actual_mime_type,
303    scoped_ptr<PluginMetadata>* plugin_metadata) const {
304  bool allow_wildcard = true;
305  std::vector<WebPluginInfo> matching_plugins;
306  std::vector<std::string> mime_types;
307  PluginService::GetInstance()->GetPluginInfoArray(
308      url, mime_type, allow_wildcard, &matching_plugins, &mime_types);
309  if (matching_plugins.empty()) {
310    status->value = ChromeViewHostMsg_GetPluginInfo_Status::kNotFound;
311    return false;
312  }
313
314  content::PluginServiceFilter* filter =
315      PluginService::GetInstance()->GetFilter();
316  size_t i = 0;
317  for (; i < matching_plugins.size(); ++i) {
318    if (!filter || filter->IsPluginAvailable(render_process_id_,
319                                             render_view_id,
320                                             resource_context_,
321                                             url,
322                                             top_origin_url,
323                                             &matching_plugins[i])) {
324      break;
325    }
326  }
327
328  // If we broke out of the loop, we have found an enabled plug-in.
329  bool enabled = i < matching_plugins.size();
330  if (!enabled) {
331    // Otherwise, we only found disabled plug-ins, so we take the first one.
332    i = 0;
333    status->value = ChromeViewHostMsg_GetPluginInfo_Status::kDisabled;
334  }
335
336  *plugin = matching_plugins[i];
337  *actual_mime_type = mime_types[i];
338  if (plugin_metadata)
339    *plugin_metadata = PluginFinder::GetInstance()->GetPluginMetadata(*plugin);
340
341  return enabled;
342}
343
344void PluginInfoMessageFilter::Context::GetPluginContentSetting(
345    const WebPluginInfo& plugin,
346    const GURL& policy_url,
347    const GURL& plugin_url,
348    const std::string& resource,
349    ContentSetting* setting,
350    bool* uses_default_content_setting) const {
351  scoped_ptr<base::Value> value;
352  content_settings::SettingInfo info;
353  bool uses_plugin_specific_setting = false;
354  if (ShouldUseJavaScriptSettingForPlugin(plugin)) {
355    value.reset(
356        host_content_settings_map_->GetWebsiteSetting(
357            policy_url, policy_url, CONTENT_SETTINGS_TYPE_JAVASCRIPT,
358            std::string(), &info));
359  } else {
360    value.reset(
361        host_content_settings_map_->GetWebsiteSetting(
362            policy_url, plugin_url, CONTENT_SETTINGS_TYPE_PLUGINS, resource,
363            &info));
364    if (value.get()) {
365      uses_plugin_specific_setting = true;
366    } else {
367      value.reset(host_content_settings_map_->GetWebsiteSetting(
368          policy_url, plugin_url, CONTENT_SETTINGS_TYPE_PLUGINS, std::string(),
369          &info));
370    }
371  }
372  *setting = content_settings::ValueToContentSetting(value.get());
373  *uses_default_content_setting =
374      !uses_plugin_specific_setting &&
375      info.primary_pattern == ContentSettingsPattern::Wildcard() &&
376      info.secondary_pattern == ContentSettingsPattern::Wildcard();
377}
378
379void PluginInfoMessageFilter::Context::MaybeGrantAccess(
380    const ChromeViewHostMsg_GetPluginInfo_Status& status,
381    const base::FilePath& path) const {
382  if (status.value == ChromeViewHostMsg_GetPluginInfo_Status::kAllowed ||
383      status.value == ChromeViewHostMsg_GetPluginInfo_Status::kClickToPlay) {
384    ChromePluginServiceFilter::GetInstance()->AuthorizePlugin(
385        render_process_id_, path);
386  }
387}
388
389