chrome_plugin_placeholder.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/renderer/render_frame.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/renderer/render_thread.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/handle.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/object_template_builder.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "grit/generated_resources.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "grit/renderer_resources.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "grit/webkit_strings.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebKit.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebScriptSource.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/base/webui/jstemplate_builder.h"
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebDocument;
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebElement;
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFrame;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebMouseEvent;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebNode;
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPlugin;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginContainer;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginParams;
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderThread;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderView;
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const plugins::PluginPlaceholder* g_last_active_menu = NULL;
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char ChromePluginPlaceholder::kPluginPlaceholderDataURL[] =
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "chrome://pluginplaceholderdata/";
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder::ChromePluginPlaceholder(
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::RenderFrame* render_frame,
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebFrame* frame,
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebPluginParams& params,
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& html_data,
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& title)
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : plugins::PluginPlaceholder(render_frame,
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 frame,
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 params,
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 html_data,
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 GURL(kPluginPlaceholderDataURL)),
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      status_(new ChromeViewHostMsg_GetPluginInfo_Status),
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      title_(title),
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      placeholder_routing_id_(MSG_ROUTING_NONE),
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      has_host_(false),
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      context_menu_request_id_(0) {
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->AddObserver(this);
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder::~ChromePluginPlaceholder() {
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->RemoveObserver(this);
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (context_menu_request_id_)
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_frame()->CancelContextMenu(context_menu_request_id_);
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (placeholder_routing_id_ == MSG_ROUTING_NONE)
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->RemoveRoute(placeholder_routing_id_);
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (has_host_) {
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderThread::Get()->Send(new ChromeViewHostMsg_RemovePluginPlaceholderHost(
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        routing_id(), placeholder_routing_id_));
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateMissingPlugin(
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::RenderFrame* render_frame,
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WebFrame* frame,
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const WebPluginParams& params) {
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          IDR_BLOCKED_PLUGIN_HTML));
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message", l10n_util::GetStringUTF8(IDS_PLUGIN_SEARCHING));
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message",
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED));
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromePluginPlaceholder* missing_plugin = new ChromePluginPlaceholder(
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame, frame, params, html_data, params.mimeType);
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  missing_plugin->set_allow_loading(true);
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->Send(
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ChromeViewHostMsg_FindMissingPlugin(missing_plugin->routing_id(),
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              missing_plugin->CreateRoutingId(),
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              params.mimeType.utf8()));
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return missing_plugin;
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateErrorPlugin(
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::RenderFrame* render_frame,
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const base::FilePath& file_path) {
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message",
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   l10n_util::GetStringUTF8(IDS_PLUGIN_INITIALIZATION_ERROR));
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          IDR_BLOCKED_PLUGIN_HTML));
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebPluginParams params;
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromePluginPlaceholder* plugin = new ChromePluginPlaceholder(
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame, NULL, params, html_data, params.mimeType);
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->Send(new ChromeViewHostMsg_CouldNotLoadPlugin(
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      plugin->routing_id(), file_path));
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return plugin;
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin(
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::RenderFrame* render_frame,
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WebFrame* frame,
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const WebPluginParams& params,
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const content::WebPluginInfo& plugin,
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& identifier,
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& name,
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int template_id,
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& message) {
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message", message);
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("name", name);
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE));
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(template_id));
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!template_html.empty()) << "unable to load template. ID: "
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 << template_id;
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |blocked_plugin| will destroy itself when its WebViewPlugin is going away.
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ChromePluginPlaceholder* blocked_plugin = new ChromePluginPlaceholder(
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame, frame, params, html_data, name);
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_plugin->SetPluginInfo(plugin);
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_plugin->SetIdentifier(identifier);
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return blocked_plugin;
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::SetStatus(
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ChromeViewHostMsg_GetPluginInfo_Status& status) {
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  status_->value = status.value;
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int32 ChromePluginPlaceholder::CreateRoutingId() {
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  placeholder_routing_id_ = RenderThread::Get()->GenerateRoutingID();
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->AddRoute(placeholder_routing_id_, this);
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return placeholder_routing_id_;
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool ChromePluginPlaceholder::OnMessageReceived(const IPC::Message& message) {
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool handled = true;
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ChromePluginPlaceholder, message)
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_FoundMissingPlugin, OnFoundMissingPlugin)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_DidNotFindMissingPlugin,
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnDidNotFindMissingPlugin)
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_StartedDownloadingPlugin,
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnStartedDownloadingPlugin)
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_FinishedDownloadingPlugin,
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnFinishedDownloadingPlugin)
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_ErrorDownloadingPlugin,
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnErrorDownloadingPlugin)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_CancelledDownloadingPlugin,
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnCancelledDownloadingPlugin)
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_END_MESSAGE_MAP()
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (handled)
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // We don't swallow these messages because multiple blocked plugins and other
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // objects have an interest in them.
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ChromePluginPlaceholder, message)
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PrerenderMsg_SetIsPrerendering, OnSetIsPrerendering)
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_LoadBlockedPlugins, OnLoadBlockedPlugins)
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_END_MESSAGE_MAP()
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return false;
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnLoadBlockedPlugins(
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& identifier) {
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugins::PluginPlaceholder::OnLoadBlockedPlugins(identifier);
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromePluginPlaceholder::OpenAboutPluginsCallback() {
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(
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::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,
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        base::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() {
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!GetFrame() || !plugin())
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());
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  render_frame()->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;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WebPlugin* new_plugin = ChromeContentRendererClient::CreatePlugin(
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame(),  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: {
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Menu"));
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LoadPlugin();
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case chrome::MENU_COMMAND_PLUGIN_HIDE: {
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      RenderThread::Get()->RecordAction(UserMetricsAction("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)
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  context_menu_request_id_ = render_frame()->ShowContextMenu(this, params);
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  g_last_active_menu = this;
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ChromePluginPlaceholder::BindWebFrame(blink::WebFrame* frame) {
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Isolate* isolate = blink::mainThreadIsolate();
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::HandleScope handle_scope(isolate);
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!context.IsEmpty());
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Context::Scope context_scope(context);
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Handle<v8::Object> global = context->Global();
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  global->Set(gin::StringToV8(isolate, "plugin"),
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              gin::CreateHandle(isolate, this).ToV8());
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gin::ObjectTemplateBuilder ChromePluginPlaceholder::GetObjectTemplateBuilder(
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    v8::Isolate* isolate) {
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return PluginPlaceholder::GetObjectTemplateBuilder(isolate).SetMethod(
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "openAboutPlugins", &ChromePluginPlaceholder::OpenAboutPluginsCallback);
3714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
372