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"
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/renderer_resources.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/renderer/chrome_content_renderer_client.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/renderer/custom_menu_commands.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/renderer/plugins/plugin_uma.h"
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/app/strings/grit/content_strings.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/common/context_menu_params.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/renderer/render_frame.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/renderer/render_thread.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/handle.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/object_template_builder.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebKit.h"
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "third_party/WebKit/public/web/WebLocalFrame.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;
35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing blink::WebLocalFrame;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebMouseEvent;
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebNode;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPlugin;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginContainer;
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginParams;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderThread;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderView;
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace {
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const plugins::PluginPlaceholder* g_last_active_menu = NULL;
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char ChromePluginPlaceholder::kPluginPlaceholderDataURL[] =
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "chrome://pluginplaceholderdata/";
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder::ChromePluginPlaceholder(
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::RenderFrame* render_frame,
53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    blink::WebLocalFrame* frame,
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebPluginParams& params,
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& html_data,
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& title)
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : plugins::PluginPlaceholder(render_frame,
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 frame,
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 params,
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 html_data,
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 GURL(kPluginPlaceholderDataURL)),
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      status_(new ChromeViewHostMsg_GetPluginInfo_Status),
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      title_(title),
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      placeholder_routing_id_(MSG_ROUTING_NONE),
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      has_host_(false),
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      context_menu_request_id_(0) {
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->AddObserver(this);
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder::~ChromePluginPlaceholder() {
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->RemoveObserver(this);
7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (context_menu_request_id_ && render_frame())
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    render_frame()->CancelContextMenu(context_menu_request_id_);
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (placeholder_routing_id_ == MSG_ROUTING_NONE)
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->RemoveRoute(placeholder_routing_id_);
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (has_host_) {
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    RenderThread::Get()->Send(new ChromeViewHostMsg_RemovePluginPlaceholderHost(
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        routing_id(), placeholder_routing_id_));
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateMissingPlugin(
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::RenderFrame* render_frame,
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebLocalFrame* frame,
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const WebPluginParams& params) {
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          IDR_BLOCKED_PLUGIN_HTML));
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message", l10n_util::GetStringUTF8(IDS_PLUGIN_SEARCHING));
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message",
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED));
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromePluginPlaceholder* missing_plugin = new ChromePluginPlaceholder(
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame, frame, params, html_data, params.mimeType);
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  missing_plugin->set_allow_loading(true);
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->Send(
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ChromeViewHostMsg_FindMissingPlugin(missing_plugin->routing_id(),
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              missing_plugin->CreateRoutingId(),
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                              params.mimeType.utf8()));
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return missing_plugin;
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateErrorPlugin(
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::RenderFrame* render_frame,
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const base::FilePath& file_path) {
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message",
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   l10n_util::GetStringUTF8(IDS_PLUGIN_INITIALIZATION_ERROR));
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          IDR_BLOCKED_PLUGIN_HTML));
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebPluginParams params;
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromePluginPlaceholder* plugin = new ChromePluginPlaceholder(
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame, NULL, params, html_data, params.mimeType);
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->Send(new ChromeViewHostMsg_CouldNotLoadPlugin(
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      plugin->routing_id(), file_path));
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return plugin;
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin(
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::RenderFrame* render_frame,
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebLocalFrame* frame,
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const WebPluginParams& params,
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const content::WebPluginInfo& plugin,
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& identifier,
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& name,
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int template_id,
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& message) {
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue values;
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("message", message);
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("name", name);
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE));
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::StringPiece template_html(
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(template_id));
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!template_html.empty()) << "unable to load template. ID: "
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 << template_id;
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |blocked_plugin| will destroy itself when its WebViewPlugin is going away.
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ChromePluginPlaceholder* blocked_plugin = new ChromePluginPlaceholder(
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame, frame, params, html_data, name);
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_plugin->SetPluginInfo(plugin);
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  blocked_plugin->SetIdentifier(identifier);
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return blocked_plugin;
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::SetStatus(
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ChromeViewHostMsg_GetPluginInfo_Status& status) {
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  status_->value = status.value;
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int32 ChromePluginPlaceholder::CreateRoutingId() {
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  placeholder_routing_id_ = RenderThread::Get()->GenerateRoutingID();
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->AddRoute(placeholder_routing_id_, this);
1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return placeholder_routing_id_;
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool ChromePluginPlaceholder::OnMessageReceived(const IPC::Message& message) {
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool handled = true;
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ChromePluginPlaceholder, message)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_FoundMissingPlugin, OnFoundMissingPlugin)
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_DidNotFindMissingPlugin,
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnDidNotFindMissingPlugin)
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_StartedDownloadingPlugin,
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnStartedDownloadingPlugin)
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_FinishedDownloadingPlugin,
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnFinishedDownloadingPlugin)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_ErrorDownloadingPlugin,
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnErrorDownloadingPlugin)
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_CancelledDownloadingPlugin,
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnCancelledDownloadingPlugin)
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_END_MESSAGE_MAP()
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (handled)
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // We don't swallow these messages because multiple blocked plugins and other
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // objects have an interest in them.
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ChromePluginPlaceholder, message)
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(PrerenderMsg_SetIsPrerendering, OnSetIsPrerendering)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_LoadBlockedPlugins, OnLoadBlockedPlugins)
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  IPC_END_MESSAGE_MAP()
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return false;
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnLoadBlockedPlugins(
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& identifier) {
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugins::PluginPlaceholder::OnLoadBlockedPlugins(identifier);
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromePluginPlaceholder::OpenAboutPluginsCallback() {
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderThread::Get()->Send(
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ChromeViewHostMsg_OpenAboutPlugins(routing_id()));
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnSetIsPrerendering(bool is_prerendering) {
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugins::PluginPlaceholder::OnSetIsPrerendering(is_prerendering);
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(ENABLE_PLUGIN_INSTALLATION)
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnDidNotFindMissingPlugin() {
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_FOUND));
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnFoundMissingPlugin(
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& plugin_name) {
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (status_->value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound)
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_FOUND, plugin_name));
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  has_host_ = true;
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugin_name_ = plugin_name;
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnStartedDownloadingPlugin() {
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING, plugin_name_));
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnFinishedDownloadingPlugin() {
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool is_installing =
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      status_->value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound;
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(l10n_util::GetStringFUTF16(
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      is_installing ? IDS_PLUGIN_INSTALLING : IDS_PLUGIN_UPDATING,
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      plugin_name_));
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnErrorDownloadingPlugin(
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& error) {
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR,
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        base::UTF8ToUTF16(error)));
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnCancelledDownloadingPlugin() {
2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetMessage(
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED, plugin_name_));
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(ENABLE_PLUGIN_INSTALLATION)
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::PluginListChanged() {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!GetFrame() || !plugin())
2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebDocument document = GetFrame()->top()->document();
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (document.isNull())
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ChromeViewHostMsg_GetPluginInfo_Output output;
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string mime_type(GetPluginParams().mimeType.utf8());
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  render_frame()->Send(
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      new ChromeViewHostMsg_GetPluginInfo(routing_id(),
2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          GURL(GetPluginParams().url),
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          document.url(),
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          mime_type,
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          &output));
2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (output.status.value == status_->value)
2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WebPlugin* new_plugin = ChromeContentRendererClient::CreatePlugin(
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame(),  GetFrame(), GetPluginParams(), output);
2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ReplacePlugin(new_plugin);
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!new_plugin) {
2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    PluginUMAReporter::GetInstance()->ReportPluginMissing(
2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        GetPluginParams().mimeType.utf8(), GURL(GetPluginParams().url));
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnMenuAction(int request_id, unsigned action) {
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(context_menu_request_id_, request_id);
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (g_last_active_menu != this)
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  switch (action) {
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case chrome::MENU_COMMAND_PLUGIN_RUN: {
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Menu"));
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      LoadPlugin();
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case chrome::MENU_COMMAND_PLUGIN_HIDE: {
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Hide_Menu"));
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      HidePlugin();
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    default:
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NOTREACHED();
3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::OnMenuClosed(int request_id) {
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_EQ(context_menu_request_id_, request_id);
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  context_menu_request_id_ = 0;
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ChromePluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) {
32123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#if !defined(OS_ANDROID)  // The context menu is not applicable on Android.
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (context_menu_request_id_)
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;  // Don't allow nested context menu requests.
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::ContextMenuParams params;
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::MenuItem name_item;
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  name_item.label = title_;
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.custom_items.push_back(name_item);
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::MenuItem separator_item;
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  separator_item.type = content::MenuItem::SEPARATOR;
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.custom_items.push_back(separator_item);
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!GetPluginInfo().path.value().empty()) {
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::MenuItem run_item;
3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    run_item.action = chrome::MENU_COMMAND_PLUGIN_RUN;
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Disable this menu item if the plugin is blocked by policy.
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    run_item.enabled = LoadingAllowed();
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    run_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_RUN);
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    params.custom_items.push_back(run_item);
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  content::MenuItem hide_item;
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  hide_item.action = chrome::MENU_COMMAND_PLUGIN_HIDE;
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  hide_item.enabled = true;
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  hide_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_HIDE);
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.custom_items.push_back(hide_item);
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.x = event.windowX;
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  params.y = event.windowY;
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  context_menu_request_id_ = render_frame()->ShowContextMenu(this, params);
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  g_last_active_menu = this;
35523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif  // OS_ANDROID
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ChromePluginPlaceholder::BindWebFrame(blink::WebFrame* frame) {
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Isolate* isolate = blink::mainThreadIsolate();
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::HandleScope handle_scope(isolate);
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!context.IsEmpty());
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Context::Scope context_scope(context);
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  v8::Handle<v8::Object> global = context->Global();
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  global->Set(gin::StringToV8(isolate, "plugin"),
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              gin::CreateHandle(isolate, this).ToV8());
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gin::ObjectTemplateBuilder ChromePluginPlaceholder::GetObjectTemplateBuilder(
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    v8::Isolate* isolate) {
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return PluginPlaceholder::GetObjectTemplateBuilder(isolate).SetMethod(
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "openAboutPlugins", &ChromePluginPlaceholder::OpenAboutPluginsCallback);
3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
375