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 "components/plugins/renderer/plugin_placeholder.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/bind.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/bind_helpers.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/json/string_escape.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_piece.h"
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_util.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/values.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/common/content_constants.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/common/context_menu_params.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/renderer/render_frame.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/renderer/render_thread.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/object_template_builder.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "third_party/WebKit/public/web/WebLocalFrame.h"
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebPluginContainer.h"
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebScriptSource.h"
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "third_party/re2/re2/re2.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebElement;
30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing blink::WebLocalFrame;
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebMouseEvent;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebNode;
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPlugin;
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginContainer;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPluginParams;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebScriptSource;
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebURLRequest;
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::RenderThread;
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace plugins {
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin};
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                     WebLocalFrame* frame,
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                     const WebPluginParams& params,
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                     const std::string& html_data,
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                     GURL placeholderDataUrl)
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : content::RenderFrameObserver(render_frame),
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      frame_(frame),
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      plugin_params_(params),
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      plugin_(WebViewPlugin::Create(this,
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    render_frame->GetWebkitPreferences(),
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    html_data,
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    placeholderDataUrl)),
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      is_blocked_for_prerendering_(false),
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      allow_loading_(false),
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      hidden_(false),
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      finished_loading_(false) {}
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)PluginPlaceholder::~PluginPlaceholder() {}
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gin::ObjectTemplateBuilder PluginPlaceholder::GetObjectTemplateBuilder(
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    v8::Isolate* isolate) {
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return gin::Wrappable<PluginPlaceholder>::GetObjectTemplateBuilder(isolate)
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .SetMethod("load", &PluginPlaceholder::LoadCallback)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .SetMethod("hide", &PluginPlaceholder::HideCallback)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .SetMethod("didFinishLoading",
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 &PluginPlaceholder::DidFinishLoadingCallback);
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CHECK(plugin_);
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!new_plugin) return;
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebPluginContainer* container = plugin_->container();
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Set the new plug-in on the container before initializing it.
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  container->setPlugin(new_plugin);
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Save the element in case the plug-in is removed from the page during
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // initialization.
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebElement element = container->element();
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!new_plugin->initialize(container)) {
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // We couldn't initialize the new plug-in. Restore the old one and abort.
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    container->setPlugin(plugin_);
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The plug-in has been removed from the page. Destroy the old plug-in. We
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // will be destroyed as soon as V8 garbage collects us.
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!element.pluginContainer()) {
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    plugin_->destroy();
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // During initialization, the new plug-in might have replaced itself in turn
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // with another plug-in. Make sure not to use the passed in |new_plugin| after
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // this point.
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  new_plugin = container->plugin();
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugin_->RestoreTitleText();
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  container->invalidate();
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  container->reportGeometry();
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugin_->ReplayReceivedData(new_plugin);
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugin_->destroy();
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::HidePlugin() {
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  hidden_ = true;
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!plugin_)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebPluginContainer* container = plugin_->container();
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebElement element = container->element();
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  element.setAttribute("style", "display: none;");
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // If we have a width and height, search for a parent (often <div>) with the
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // same dimensions. If we find such a parent, hide that as well.
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This makes much more uncovered page content usable (including clickable)
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // as opposed to merely visible.
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(cevans) -- it's a foul heurisitc but we're going to tolerate it for
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // now for these reasons:
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 1) Makes the user experience better.
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 2) Foulness is encapsulated within this single function.
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 3) Confidence in no fasle positives.
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // 4) Seems to have a good / low false negative rate at this time.
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (element.hasAttribute("width") && element.hasAttribute("height")) {
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string width_str("width:[\\s]*");
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    width_str += element.getAttribute("width").utf8().data();
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (EndsWith(width_str, "px", false)) {
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      width_str = width_str.substr(0, width_str.length() - 2);
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::TrimWhitespace(width_str, base::TRIM_TRAILING, &width_str);
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    width_str += "[\\s]*px";
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::string height_str("height:[\\s]*");
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    height_str += element.getAttribute("height").utf8().data();
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (EndsWith(height_str, "px", false)) {
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      height_str = height_str.substr(0, height_str.length() - 2);
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::TrimWhitespace(height_str, base::TRIM_TRAILING, &height_str);
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    height_str += "[\\s]*px";
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WebNode parent = element;
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    while (!parent.parentNode().isNull()) {
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      parent = parent.parentNode();
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (!parent.isElementNode())
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        continue;
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      element = parent.toConst<WebElement>();
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (element.hasAttribute("style")) {
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        std::string style_str = element.getAttribute("style").utf8();
1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (RE2::PartialMatch(style_str, width_str) &&
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            RE2::PartialMatch(style_str, height_str))
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          element.setAttribute("style", "display: none;");
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PluginPlaceholder::SetMessage(const base::string16& message) {
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  message_ = message;
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (finished_loading_)
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    UpdateMessage();
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::UpdateMessage() {
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!plugin_)
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string script =
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "window.setMessage(" + base::GetQuotedJSONString(message_) + ")";
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugin_->web_view()->mainFrame()->executeScript(
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      WebScriptSource(base::UTF8ToUTF16(script)));
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) {
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Does nothing by default. Will be overridden if a specific browser wants
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // a context menu.
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return;
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PluginPlaceholder::PluginDestroyed() {
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  plugin_ = NULL;
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PluginPlaceholder::OnDestruct() {
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_ = NULL;
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::OnLoadBlockedPlugins(const std::string& identifier) {
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!identifier.empty() && identifier != identifier_)
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_UI"));
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LoadPlugin();
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::OnSetIsPrerendering(bool is_prerendering) {
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Prerendering can only be enabled prior to a RenderView's first navigation,
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // so no BlockedPlugin should see the notification that enables prerendering.
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!is_prerendering);
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_blocked_for_prerendering_ && !is_prerendering)
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LoadPlugin();
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::LoadPlugin() {
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This is not strictly necessary but is an important defense in case the
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // event propagation changes between "close" vs. "click-to-play".
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (hidden_)
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!plugin_)
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!allow_loading_) {
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    NOTREACHED();
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // TODO(mmenke):  In the case of prerendering, feed into
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //                ChromeContentRendererClient::CreatePlugin instead, to
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  //                reduce the chance of future regressions.
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WebPlugin* plugin =
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      render_frame()->CreatePlugin(frame_, plugin_info_, plugin_params_);
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ReplacePlugin(plugin);
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PluginPlaceholder::LoadCallback() {
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Click"));
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LoadPlugin();
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PluginPlaceholder::HideCallback() {
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Hide_Click"));
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HidePlugin();
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PluginPlaceholder::DidFinishLoadingCallback() {
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  finished_loading_ = true;
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (message_.length() > 0)
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    UpdateMessage();
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::SetPluginInfo(
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const content::WebPluginInfo& plugin_info) {
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  plugin_info_ = plugin_info;
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const content::WebPluginInfo& PluginPlaceholder::GetPluginInfo() const {
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return plugin_info_;
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PluginPlaceholder::SetIdentifier(const std::string& identifier) {
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  identifier_ = identifier;
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochblink::WebLocalFrame* PluginPlaceholder::GetFrame() { return frame_; }
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const blink::WebPluginParams& PluginPlaceholder::GetPluginParams() const {
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return plugin_params_;
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace plugins
255