chrome_plugin_placeholder.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/renderer/plugins/chrome_plugin_placeholder.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/values.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/prerender_messages.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/render_messages.h"
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/renderer/chrome_content_renderer_client.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/renderer/custom_menu_commands.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/renderer/plugins/plugin_uma.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/common/context_menu_params.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/renderer/render_thread.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/renderer/render_view.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "grit/generated_resources.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "grit/renderer_resources.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "grit/webkit_strings.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebScriptSource.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/webui/jstemplate_builder.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::RenderThread;
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::RenderView;
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using WebKit::WebDocument;
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using WebKit::WebElement;
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using WebKit::WebFrame;
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using WebKit::WebMouseEvent;
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using WebKit::WebNode;
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using WebKit::WebPlugin;
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using WebKit::WebPluginContainer;
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using WebKit::WebPluginParams;
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using webkit_glue::CppArgumentList;
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using webkit_glue::CppVariant;
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const plugins::PluginPlaceholder* g_last_active_menu = NULL;
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char ChromePluginPlaceholder::kPluginPlaceholderDataURL[] =
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "chrome://pluginplaceholderdata/";
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder::ChromePluginPlaceholder(
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::RenderView* render_view,
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WebKit::WebFrame* frame,
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const WebKit::WebPluginParams& params,
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& html_data,
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const string16& title)
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    : plugins::PluginPlaceholder(render_view,
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 frame,
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 params,
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 html_data,
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 GURL(kPluginPlaceholderDataURL)),
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      status_(new ChromeViewHostMsg_GetPluginInfo_Status),
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      title_(title),
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      placeholder_routing_id_(MSG_ROUTING_NONE),
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      has_host_(false),
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      context_menu_request_id_(0) {
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->AddObserver(this);
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder::~ChromePluginPlaceholder() {
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->RemoveObserver(this);
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (context_menu_request_id_)
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    render_view()->CancelContextMenu(context_menu_request_id_);
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (placeholder_routing_id_ == MSG_ROUTING_NONE)
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->RemoveRoute(placeholder_routing_id_);
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (has_host_) {
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderThread::Get()->Send(new ChromeViewHostMsg_RemovePluginPlaceholderHost(
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        routing_id(), placeholder_routing_id_));
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateMissingPlugin(
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderView* render_view,
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WebFrame* frame,
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const WebPluginParams& params) {
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          IDR_BLOCKED_PLUGIN_HTML));
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message", l10n_util::GetStringUTF8(IDS_PLUGIN_SEARCHING));
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message",
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED));
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromePluginPlaceholder* missing_plugin = new ChromePluginPlaceholder(
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      render_view, frame, params, html_data, params.mimeType);
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  missing_plugin->set_allow_loading(true);
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->Send(
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ChromeViewHostMsg_FindMissingPlugin(missing_plugin->routing_id(),
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              missing_plugin->CreateRoutingId(),
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              params.mimeType.utf8()));
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return missing_plugin;
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateErrorPlugin(
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderView* render_view,
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const base::FilePath& file_path) {
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message",
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   l10n_util::GetStringUTF8(IDS_PLUGIN_INITIALIZATION_ERROR));
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          IDR_BLOCKED_PLUGIN_HTML));
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebPluginParams params;
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromePluginPlaceholder* plugin = new ChromePluginPlaceholder(
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      render_view, NULL, params, html_data, params.mimeType);
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->Send(new ChromeViewHostMsg_CouldNotLoadPlugin(
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      plugin->routing_id(), file_path));
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return plugin;
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin(
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderView* render_view,
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WebFrame* frame,
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const WebPluginParams& params,
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const content::WebPluginInfo& plugin,
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& identifier,
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const string16& name,
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int template_id,
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const string16& message) {
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message", message);
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("name", name);
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE));
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(template_id));
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!template_html.empty()) << "unable to load template. ID: "
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 << template_id;
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |blocked_plugin| will destroy itself when its WebViewPlugin is going away.
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromePluginPlaceholder* blocked_plugin =
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ChromePluginPlaceholder(render_view, frame, params, html_data, name);
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_plugin->SetPluginInfo(plugin);
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_plugin->SetIdentifier(identifier);
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return blocked_plugin;
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::SetStatus(
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ChromeViewHostMsg_GetPluginInfo_Status& status) {
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  status_->value = status.value;
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int32 ChromePluginPlaceholder::CreateRoutingId() {
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  placeholder_routing_id_ = RenderThread::Get()->GenerateRoutingID();
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->AddRoute(placeholder_routing_id_, this);
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return placeholder_routing_id_;
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool ChromePluginPlaceholder::OnMessageReceived(const IPC::Message& message) {
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool handled = true;
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ChromePluginPlaceholder, message)
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_HANDLER(ChromeViewMsg_FoundMissingPlugin, OnFoundMissingPlugin)
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_HANDLER(ChromeViewMsg_DidNotFindMissingPlugin,
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      OnDidNotFindMissingPlugin)
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_HANDLER(ChromeViewMsg_StartedDownloadingPlugin,
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      OnStartedDownloadingPlugin)
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_HANDLER(ChromeViewMsg_FinishedDownloadingPlugin,
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      OnFinishedDownloadingPlugin)
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_HANDLER(ChromeViewMsg_ErrorDownloadingPlugin,
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      OnErrorDownloadingPlugin)
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_HANDLER(ChromeViewMsg_CancelledDownloadingPlugin,
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      OnCancelledDownloadingPlugin)
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_UNHANDLED(handled = false)
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_END_MESSAGE_MAP()
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (handled)
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // We don't swallow these messages because multiple blocked plugins have an
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // interest in them.
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ChromePluginPlaceholder, message)
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_HANDLER(ChromeViewMsg_LoadBlockedPlugins, OnLoadBlockedPlugins)
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_MESSAGE_HANDLER(PrerenderMsg_SetIsPrerendering, OnSetIsPrerendering)
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_END_MESSAGE_MAP()
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return false;
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnLoadBlockedPlugins(
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& identifier) {
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugins::PluginPlaceholder::OnLoadBlockedPlugins(identifier);
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OpenAboutPluginsCallback(
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const CppArgumentList& args,
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CppVariant* result) {
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->Send(
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ChromeViewHostMsg_OpenAboutPlugins(routing_id()));
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnSetIsPrerendering(bool is_prerendering) {
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugins::PluginPlaceholder::OnSetIsPrerendering(is_prerendering);
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnDidNotFindMissingPlugin() {
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_FOUND));
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnFoundMissingPlugin(
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const string16& plugin_name) {
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status_->value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound)
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_FOUND, plugin_name));
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  has_host_ = true;
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugin_name_ = plugin_name;
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnStartedDownloadingPlugin() {
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING, plugin_name_));
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnFinishedDownloadingPlugin() {
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool is_installing =
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      status_->value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound;
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(l10n_util::GetStringFUTF16(
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      is_installing ? IDS_PLUGIN_INSTALLING : IDS_PLUGIN_UPDATING,
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      plugin_name_));
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnErrorDownloadingPlugin(
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& error) {
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR,
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                        UTF8ToUTF16(error)));
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnCancelledDownloadingPlugin() {
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(
2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED, plugin_name_));
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(ENABLE_PLUGIN_INSTALLATION)
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::PluginListChanged() {
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!GetFrame())
2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebDocument document = GetFrame()->top()->document();
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (document.isNull())
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromeViewHostMsg_GetPluginInfo_Output output;
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string mime_type(GetPluginParams().mimeType.utf8());
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  render_view()->Send(
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ChromeViewHostMsg_GetPluginInfo(routing_id(),
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          GURL(GetPluginParams().url),
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          document.url(),
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          mime_type,
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          &output));
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (output.status.value == status_->value)
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebPlugin* new_plugin = chrome::ChromeContentRendererClient::CreatePlugin(
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      render_view(), GetFrame(), GetPluginParams(), output);
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ReplacePlugin(new_plugin);
2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!new_plugin) {
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    PluginUMAReporter::GetInstance()->ReportPluginMissing(
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        GetPluginParams().mimeType.utf8(), GURL(GetPluginParams().url));
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnMenuAction(int request_id, unsigned action) {
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(context_menu_request_id_, request_id);
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (g_last_active_menu != this)
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switch (action) {
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case chrome::MENU_COMMAND_PLUGIN_RUN: {
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      RenderThread::Get()->RecordUserMetrics("Plugin_Load_Menu");
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LoadPlugin();
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case chrome::MENU_COMMAND_PLUGIN_HIDE: {
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      RenderThread::Get()->RecordUserMetrics("Plugin_Hide_Menu");
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      HidePlugin();
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    default:
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NOTREACHED();
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnMenuClosed(int request_id) {
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(context_menu_request_id_, request_id);
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  context_menu_request_id_ = 0;
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) {
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (context_menu_request_id_)
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;  // Don't allow nested context menu requests.
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::ContextMenuParams params;
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::MenuItem name_item;
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  name_item.label = title_;
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.custom_items.push_back(name_item);
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::MenuItem separator_item;
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  separator_item.type = content::MenuItem::SEPARATOR;
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.custom_items.push_back(separator_item);
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!GetPluginInfo().path.value().empty()) {
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::MenuItem run_item;
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    run_item.action = chrome::MENU_COMMAND_PLUGIN_RUN;
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Disable this menu item if the plugin is blocked by policy.
3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    run_item.enabled = LoadingAllowed();
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    run_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_RUN);
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    params.custom_items.push_back(run_item);
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::MenuItem hide_item;
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  hide_item.action = chrome::MENU_COMMAND_PLUGIN_HIDE;
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  hide_item.enabled = true;
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  hide_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_HIDE);
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.custom_items.push_back(hide_item);
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.x = event.windowX;
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.y = event.windowY;
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  context_menu_request_id_ = render_view()->ShowContextMenu(this, params);
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  g_last_active_menu = this;
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::BindWebFrame(WebKit::WebFrame* frame) {
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugins::PluginPlaceholder::BindWebFrame(frame);
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  BindCallback("openAboutPlugins",
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)               base::Bind(&ChromePluginPlaceholder::OpenAboutPluginsCallback,
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          base::Unretained(this)));
3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
361