| Index: components/plugins/renderer/loadable_plugin_placeholder.cc
|
| diff --git a/components/plugins/renderer/loadable_plugin_placeholder.cc b/components/plugins/renderer/loadable_plugin_placeholder.cc
|
| index 1ea86a5994530e48e9962682ae2cb41d6e809dcd..70349d2cde0cb4d060a8c95b2eea53c3d17db648 100644
|
| --- a/components/plugins/renderer/loadable_plugin_placeholder.cc
|
| +++ b/components/plugins/renderer/loadable_plugin_placeholder.cc
|
| @@ -50,6 +50,17 @@ void LoadablePluginPlaceholder::BlockForPowerSaverPoster() {
|
| }
|
| #endif
|
|
|
| +void LoadablePluginPlaceholder::SetPremadePlugin(
|
| + blink::WebPlugin* plugin,
|
| + content::PluginInstanceThrottler* throttler) {
|
| + DCHECK(!premade_plugin_);
|
| + DCHECK(!premade_throttler_);
|
| + premade_plugin_ = plugin;
|
| + premade_throttler_ = throttler;
|
| +
|
| + premade_throttler_->AddObserver(this);
|
| +}
|
| +
|
| LoadablePluginPlaceholder::LoadablePluginPlaceholder(
|
| content::RenderFrame* render_frame,
|
| WebLocalFrame* frame,
|
| @@ -65,6 +76,8 @@ LoadablePluginPlaceholder::LoadablePluginPlaceholder(
|
| is_blocked_for_prerendering_(false),
|
| is_blocked_for_power_saver_poster_(false),
|
| power_saver_mode_(PluginPowerSaverMode::POWER_SAVER_MODE_ESSENTIAL),
|
| + premade_plugin_(nullptr),
|
| + premade_throttler_(nullptr),
|
| allow_loading_(false),
|
| placeholder_was_replaced_(false),
|
| hidden_(false),
|
| @@ -74,6 +87,9 @@ LoadablePluginPlaceholder::LoadablePluginPlaceholder(
|
|
|
| LoadablePluginPlaceholder::~LoadablePluginPlaceholder() {
|
| #if defined(ENABLE_PLUGINS)
|
| + if (premade_throttler_)
|
| + premade_throttler_->RemoveObserver(this);
|
| +
|
| if (!placeholder_was_replaced_ && !is_blocked_for_prerendering_ &&
|
| power_saver_mode_ != PluginPowerSaverMode::POWER_SAVER_MODE_ESSENTIAL) {
|
| PluginInstanceThrottler::RecordUnthrottleMethodMetric(
|
| @@ -89,7 +105,12 @@ void LoadablePluginPlaceholder::DisablePowerSaverForInstance(
|
| return;
|
|
|
| power_saver_mode_ = PluginPowerSaverMode::POWER_SAVER_MODE_ESSENTIAL;
|
| - PluginInstanceThrottler::RecordUnthrottleMethodMetric(method);
|
| + if (premade_throttler_) {
|
| + premade_throttler_->MarkPluginEssential(method);
|
| + } else {
|
| + PluginInstanceThrottler::RecordUnthrottleMethodMetric(method);
|
| + }
|
| +
|
| if (is_blocked_for_power_saver_poster_) {
|
| is_blocked_for_power_saver_poster_ = false;
|
| if (!LoadingBlocked())
|
| @@ -117,7 +138,7 @@ void LoadablePluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
|
| // Save the element in case the plug-in is removed from the page during
|
| // initialization.
|
| WebElement element = container->element();
|
| - if (!new_plugin->initialize(container)) {
|
| + if (new_plugin != premade_plugin_ && !new_plugin->initialize(container)) {
|
| // We couldn't initialize the new plug-in. Restore the old one and abort.
|
| container->setPlugin(plugin());
|
| return;
|
| @@ -130,6 +151,8 @@ void LoadablePluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
|
| return;
|
| }
|
|
|
| + placeholder_was_replaced_ = true;
|
| +
|
| // During initialization, the new plug-in might have replaced itself in turn
|
| // with another plug-in. Make sure not to use the passed in |new_plugin| after
|
| // this point.
|
| @@ -140,8 +163,6 @@ void LoadablePluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
|
| container->reportGeometry();
|
| plugin()->ReplayReceivedData(new_plugin);
|
| plugin()->destroy();
|
| -
|
| - placeholder_was_replaced_ = true;
|
| }
|
|
|
| void LoadablePluginPlaceholder::HidePlugin() {
|
| @@ -207,10 +228,16 @@ void LoadablePluginPlaceholder::UpdateMessage() {
|
| WebScriptSource(base::UTF8ToUTF16(script)));
|
| }
|
|
|
| -void LoadablePluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) {
|
| - // Does nothing by default. Will be overridden if a specific browser wants
|
| - // a context menu.
|
| - return;
|
| +void LoadablePluginPlaceholder::PluginDestroyed() {
|
| + // Since the premade plugin has been detached from the container, it will not
|
| + // be automatically destroyed along with the page.
|
| + if (!placeholder_was_replaced_ && premade_plugin_) {
|
| + premade_plugin_->destroy();
|
| + premade_plugin_ = nullptr;
|
| + premade_throttler_ = nullptr;
|
| + }
|
| +
|
| + PluginPlaceholder::PluginDestroyed();
|
| }
|
|
|
| void LoadablePluginPlaceholder::WasShown() {
|
| @@ -221,6 +248,15 @@ void LoadablePluginPlaceholder::WasShown() {
|
| }
|
| }
|
|
|
| +void LoadablePluginPlaceholder::OnThrottleStateChange() {
|
| + DCHECK(premade_plugin_);
|
| + DCHECK(premade_throttler_);
|
| + if (!premade_throttler_->IsThrottled()) {
|
| + // Premade plugin has been unthrottled externally (by audio playback, etc.).
|
| + LoadPlugin();
|
| + }
|
| +}
|
| +
|
| void LoadablePluginPlaceholder::OnLoadBlockedPlugins(
|
| const std::string& identifier) {
|
| if (!identifier.empty() && identifier != identifier_)
|
| @@ -253,17 +289,29 @@ void LoadablePluginPlaceholder::LoadPlugin() {
|
| return;
|
| }
|
|
|
| - // TODO(mmenke): In the case of prerendering, feed into
|
| - // ChromeContentRendererClient::CreatePlugin instead, to
|
| - // reduce the chance of future regressions.
|
| - scoped_ptr<PluginInstanceThrottler> throttler;
|
| + if (premade_plugin_) {
|
| + // Show the (presumably hidden) premade plugin again.
|
| + premade_plugin_->updateVisibility(true);
|
| +
|
| + ReplacePlugin(premade_plugin_);
|
| +
|
| + premade_throttler_->RemoveObserver(this);
|
| + premade_plugin_ = nullptr;
|
| + premade_throttler_ = nullptr;
|
| + } else {
|
| + // TODO(mmenke): In the case of prerendering, feed into
|
| + // ChromeContentRendererClient::CreatePlugin instead, to
|
| + // reduce the chance of future regressions.
|
| + scoped_ptr<PluginInstanceThrottler> throttler;
|
| #if defined(ENABLE_PLUGINS)
|
| - throttler = PluginInstanceThrottler::Get(
|
| - render_frame(), GetPluginParams().url, power_saver_mode_);
|
| + throttler = PluginInstanceThrottler::Get(
|
| + render_frame(), GetPluginParams().url, power_saver_mode_);
|
| #endif
|
| - WebPlugin* plugin = render_frame()->CreatePlugin(
|
| - GetFrame(), plugin_info_, GetPluginParams(), throttler.Pass());
|
| - ReplacePlugin(plugin);
|
| + WebPlugin* plugin = render_frame()->CreatePlugin(
|
| + GetFrame(), plugin_info_, GetPluginParams(), throttler.Pass());
|
| +
|
| + ReplacePlugin(plugin);
|
| + }
|
| }
|
|
|
| void LoadablePluginPlaceholder::LoadCallback() {
|
| @@ -286,6 +334,12 @@ void LoadablePluginPlaceholder::DidFinishLoadingCallback() {
|
| finished_loading_ = true;
|
| if (message_.length() > 0)
|
| UpdateMessage();
|
| +
|
| + // Wait for the placeholder to finish loading to hide the premade plugin.
|
| + // This is necessary to prevent a flicker.
|
| + if (premade_plugin_ && !placeholder_was_replaced_) {
|
| + premade_plugin_->updateVisibility(false);
|
| + }
|
| }
|
|
|
| void LoadablePluginPlaceholder::SetPluginInfo(
|
|
|