summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortommycli <tommycli@chromium.org>2015-06-11 15:20:14 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-11 22:21:17 +0000
commit425d6965196e7448a2ba9180a3fd2f5b08f5b329 (patch)
tree0799c08a8aa683b6196ebbf7f3963b29731abbcc
parent60b17299b23088c43179c092a26977cdb294b0da (diff)
downloadchromium_src-425d6965196e7448a2ba9180a3fd2f5b08f5b329.zip
chromium_src-425d6965196e7448a2ba9180a3fd2f5b08f5b329.tar.gz
chromium_src-425d6965196e7448a2ba9180a3fd2f5b08f5b329.tar.bz2
Reland: Plugin Placeholders: Refactor for platforms that don't support plugins
This patch removes a lot of plugin placeholder code from builds that don't support plugins (enable_plugins==0). This is a reland of https://codereview.chromium.org/1126073003/. See patchsets for fixes of the crashes. BUG=493889 TBR= Review URL: https://codereview.chromium.org/1161923004 Cr-Commit-Position: refs/heads/master@{#334054}
-rw-r--r--chrome/chrome_renderer.gypi6
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc110
-rw-r--r--chrome/renderer/chrome_content_renderer_client.h2
-rw-r--r--chrome/renderer/plugins/chrome_plugin_placeholder.cc71
-rw-r--r--chrome/renderer/plugins/chrome_plugin_placeholder.h19
-rw-r--r--chrome/renderer/plugins/non_loadable_plugin_placeholder.cc60
-rw-r--r--chrome/renderer/plugins/non_loadable_plugin_placeholder.h43
-rw-r--r--chrome/renderer/plugins/plugin_preroller.cc1
-rw-r--r--chrome/renderer/resources/blocked_plugin.html11
-rw-r--r--components/plugins.gypi9
-rw-r--r--components/plugins/renderer/BUILD.gn10
-rw-r--r--components/plugins/renderer/loadable_plugin_placeholder.cc129
-rw-r--r--components/plugins/renderer/loadable_plugin_placeholder.h34
-rw-r--r--components/plugins/renderer/mobile_youtube_plugin.cc34
-rw-r--r--components/plugins/renderer/mobile_youtube_plugin.h14
-rw-r--r--components/plugins/renderer/plugin_placeholder.cc120
-rw-r--r--components/plugins/renderer/plugin_placeholder.h60
-rw-r--r--components/plugins/renderer/webview_plugin.cc17
-rw-r--r--components/plugins/renderer/webview_plugin.h7
-rw-r--r--content/content_shell.gypi2
-rw-r--r--content/shell/BUILD.gn2
-rw-r--r--content/shell/renderer/layout_test/blink_test_runner.cc13
-rw-r--r--content/shell/renderer/layout_test/test_plugin_placeholder.cc35
-rw-r--r--content/shell/renderer/layout_test/test_plugin_placeholder.h23
-rw-r--r--gin/wrappable.cc2
-rw-r--r--gin/wrappable.h28
-rw-r--r--gin/wrappable_unittest.cc72
27 files changed, 455 insertions, 479 deletions
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index 2945b6a..73b86fe 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -36,8 +36,8 @@
'renderer/net_benchmarking_extension.h',
'renderer/page_load_histograms.cc',
'renderer/page_load_histograms.h',
- 'renderer/plugins/chrome_plugin_placeholder.cc',
- 'renderer/plugins/chrome_plugin_placeholder.h',
+ 'renderer/plugins/non_loadable_plugin_placeholder.cc',
+ 'renderer/plugins/non_loadable_plugin_placeholder.h',
'renderer/plugins/plugin_uma.cc',
'renderer/plugins/plugin_uma.h',
'renderer/plugins/shadow_dom_plugin_placeholder.cc',
@@ -182,6 +182,8 @@
'renderer/pepper/pepper_shared_memory_message_filter.h',
'renderer/pepper/pepper_uma_host.cc',
'renderer/pepper/pepper_uma_host.h',
+ 'renderer/plugins/chrome_plugin_placeholder.cc',
+ 'renderer/plugins/chrome_plugin_placeholder.h',
'renderer/plugins/plugin_preroller.cc',
'renderer/plugins/plugin_preroller.h',
],
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 59de107..258817d 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -40,7 +40,7 @@
#include "chrome/renderer/net_benchmarking_extension.h"
#include "chrome/renderer/page_load_histograms.h"
#include "chrome/renderer/pepper/pepper_helper.h"
-#include "chrome/renderer/plugins/chrome_plugin_placeholder.h"
+#include "chrome/renderer/plugins/non_loadable_plugin_placeholder.h"
#include "chrome/renderer/plugins/plugin_preroller.h"
#include "chrome/renderer/plugins/plugin_uma.h"
#include "chrome/renderer/plugins/shadow_dom_plugin_placeholder.h"
@@ -132,6 +132,10 @@
#include "chrome/common/external_ipc_dumper.h"
#endif
+#if defined(ENABLE_PLUGINS)
+#include "chrome/renderer/plugins/chrome_plugin_placeholder.h"
+#endif
+
#if defined(ENABLE_PRINTING)
#include "chrome/renderer/printing/chrome_print_web_view_helper_delegate.h"
#include "components/printing/renderer/print_web_view_helper.h"
@@ -196,6 +200,7 @@ const char* const kPredefinedAllowedCompositorOrigins[] = {
};
#endif
+#if defined(ENABLE_PLUGINS)
void AppendParams(const std::vector<base::string16>& additional_names,
const std::vector<base::string16>& additional_values,
WebVector<WebString>* existing_names,
@@ -223,26 +228,6 @@ void AppendParams(const std::vector<base::string16>& additional_names,
existing_values->swap(values);
}
-#if defined(ENABLE_SPELLCHECK)
-class SpellCheckReplacer : public content::RenderViewVisitor {
- public:
- explicit SpellCheckReplacer(SpellCheck* spellcheck)
- : spellcheck_(spellcheck) {}
- bool Visit(content::RenderView* render_view) override;
-
- private:
- SpellCheck* spellcheck_; // New shared spellcheck for all views. Weak Ptr.
- DISALLOW_COPY_AND_ASSIGN(SpellCheckReplacer);
-};
-
-bool SpellCheckReplacer::Visit(content::RenderView* render_view) {
- SpellCheckProvider* provider = SpellCheckProvider::Get(render_view);
- DCHECK(provider);
- provider->set_spellcheck(spellcheck_);
- return true;
-}
-#endif
-
// For certain sandboxed Pepper plugins, use the JavaScript Content Settings.
bool ShouldUseJavaScriptSettingForPlugin(const WebPluginInfo& plugin) {
if (plugin.type != WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS &&
@@ -266,6 +251,27 @@ bool ShouldUseJavaScriptSettingForPlugin(const WebPluginInfo& plugin) {
return false;
}
+#endif // defined(ENABLE_PLUGINS)
+
+#if defined(ENABLE_SPELLCHECK)
+class SpellCheckReplacer : public content::RenderViewVisitor {
+ public:
+ explicit SpellCheckReplacer(SpellCheck* spellcheck)
+ : spellcheck_(spellcheck) {}
+ bool Visit(content::RenderView* render_view) override;
+
+ private:
+ SpellCheck* spellcheck_; // New shared spellcheck for all views. Weak Ptr.
+ DISALLOW_COPY_AND_ASSIGN(SpellCheckReplacer);
+};
+
+bool SpellCheckReplacer::Visit(content::RenderView* render_view) {
+ SpellCheckProvider* provider = SpellCheckProvider::Get(render_view);
+ DCHECK(provider);
+ provider->set_spellcheck(spellcheck_);
+ return true;
+}
+#endif
#if defined(ENABLE_EXTENSIONS)
void IsGuestViewApiAvailableToScriptContext(
@@ -650,25 +656,39 @@ bool ChromeContentRendererClient::OverrideCreatePlugin(
}
#endif
- ChromeViewHostMsg_GetPluginInfo_Output output;
+ GURL url(params.url);
#if defined(ENABLE_PLUGINS)
+ ChromeViewHostMsg_GetPluginInfo_Output output;
render_frame->Send(new ChromeViewHostMsg_GetPluginInfo(
- render_frame->GetRoutingID(), GURL(params.url),
- frame->top()->document().url(), orig_mime_type, &output));
-
-#else
- output.status = ChromeViewHostMsg_GetPluginInfo_Status::kNotFound;
-#endif
+ render_frame->GetRoutingID(), url, frame->top()->document().url(),
+ orig_mime_type, &output));
*plugin = CreatePlugin(render_frame, frame, params, output);
+#else // !defined(ENABLE_PLUGINS)
+
+#if defined(OS_ANDROID)
+ if (plugins::MobileYouTubePlugin::IsYouTubeURL(url, orig_mime_type)) {
+ base::StringPiece template_html(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_MOBILE_YOUTUBE_PLUGIN_HTML));
+ *plugin = (new plugins::MobileYouTubePlugin(render_frame, frame, params,
+ template_html))->plugin();
+ return true;
+ }
+#endif // defined(OS_ANDROID)
+
+ PluginUMAReporter::GetInstance()->ReportPluginMissing(orig_mime_type, url);
+ *plugin = NonLoadablePluginPlaceholder::CreateNotSupportedPlugin(
+ render_frame, frame, params)->plugin();
+
+#endif // defined(ENABLE_PLUGINS)
return true;
}
WebPlugin* ChromeContentRendererClient::CreatePluginReplacement(
content::RenderFrame* render_frame,
const base::FilePath& plugin_path) {
- ChromePluginPlaceholder* placeholder =
- ChromePluginPlaceholder::CreateErrorPlugin(render_frame, plugin_path);
- return placeholder->plugin();
+ return NonLoadablePluginPlaceholder::CreateErrorPlugin(render_frame,
+ plugin_path)->plugin();
}
void ChromeContentRendererClient::DeferMediaLoad(
@@ -689,6 +709,7 @@ void ChromeContentRendererClient::DeferMediaLoad(
#endif
}
+#if defined(ENABLE_PLUGINS)
WebPlugin* ChromeContentRendererClient::CreatePlugin(
content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
@@ -708,22 +729,8 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
// OverrideCreatePlugin.
if (status == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound ||
orig_mime_type == content::kBrowserPluginMimeType) {
-#if defined(OS_ANDROID)
- if (plugins::MobileYouTubePlugin::IsYouTubeURL(url, orig_mime_type)) {
- base::StringPiece template_html(
- ResourceBundle::GetSharedInstance().GetRawDataResource(
- IDR_MOBILE_YOUTUBE_PLUGIN_HTML));
- return (new plugins::MobileYouTubePlugin(
- render_frame,
- frame,
- original_params,
- template_html,
- GURL(ChromePluginPlaceholder::kPluginPlaceholderDataURL)))
- ->plugin();
- }
-#endif
PluginUMAReporter::GetInstance()->ReportPluginMissing(orig_mime_type, url);
- placeholder = ChromePluginPlaceholder::CreateMissingPlugin(
+ placeholder = ChromePluginPlaceholder::CreateLoadableMissingPlugin(
render_frame, frame, original_params);
} else {
// TODO(bauerb): This should be in content/.
@@ -846,7 +853,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
}
#endif // !defined(DISABLE_NACL) && defined(ENABLE_EXTENSIONS)
-#if defined(ENABLE_PLUGINS)
// Delay loading plugins if prerendering.
// TODO(mmenke): In the case of prerendering, feed into
// ChromeContentRendererClient::CreatePlugin instead, to
@@ -881,7 +887,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
blocked_for_background_tab);
placeholder->set_blocked_for_prerendering(is_prerendering);
placeholder->set_power_saver_enabled(power_saver_enabled);
- placeholder->set_allow_loading(true);
break;
}
@@ -897,9 +902,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
return render_frame->CreatePlugin(frame, info, params,
throttler.Pass());
-#else // !defined(ENABLE_PLUGINS)
- return render_frame->CreatePlugin(frame, info, params, nullptr);
-#endif // defined(ENABLE_PLUGINS)
}
case ChromeViewHostMsg_GetPluginInfo_Status::kNPAPINotSupported: {
RenderThread::Get()->RecordAction(
@@ -924,7 +926,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
placeholder = create_blocked_plugin(
IDR_BLOCKED_PLUGIN_HTML,
l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED, group_name));
- placeholder->set_allow_loading(true);
render_frame->Send(new ChromeViewHostMsg_BlockedOutdatedPlugin(
render_frame->GetRoutingID(), placeholder->CreateRoutingId(),
identifier));
@@ -943,7 +944,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
placeholder = create_blocked_plugin(
IDR_BLOCKED_PLUGIN_HTML,
l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, group_name));
- placeholder->set_allow_loading(true);
if (info.type != content::WebPluginInfo::PLUGIN_TYPE_NPAPI) {
render_frame->Send(new ChromeViewHostMsg_BlockedUnauthorizedPlugin(
render_frame->GetRoutingID(),
@@ -957,7 +957,6 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
placeholder = create_blocked_plugin(
IDR_BLOCKED_PLUGIN_HTML,
l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name));
- placeholder->set_allow_loading(true);
RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Blocked"));
observer->DidBlockContentType(content_type, group_name);
break;
@@ -967,7 +966,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
IDR_BLOCKED_PLUGIN_HTML,
l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED_BY_POLICY,
group_name));
- placeholder->set_allow_loading(false);
+ placeholder->DisallowLoading();
RenderThread::Get()->RecordAction(
UserMetricsAction("Plugin_BlockedByPolicy"));
observer->DidBlockContentType(content_type, group_name);
@@ -978,6 +977,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
placeholder->SetStatus(status);
return placeholder->plugin();
}
+#endif // defined(ENABLE_PLUGINS)
// For NaCl content handling plugins, the NaCl manifest is stored in an
// additonal 'nacl' param associated with the MIME type.
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 952e879..93fe153 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -168,11 +168,13 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
void SetSpellcheck(SpellCheck* spellcheck);
#endif
+#if defined(ENABLE_PLUGINS)
static blink::WebPlugin* CreatePlugin(
content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
const ChromeViewHostMsg_GetPluginInfo_Output& output);
+#endif
#if defined(ENABLE_PLUGINS) && defined(ENABLE_EXTENSIONS)
static bool IsExtensionOrSharedModuleWhitelisted(
diff --git a/chrome/renderer/plugins/chrome_plugin_placeholder.cc b/chrome/renderer/plugins/chrome_plugin_placeholder.cc
index 402bfb6..165eebb 100644
--- a/chrome/renderer/plugins/chrome_plugin_placeholder.cc
+++ b/chrome/renderer/plugins/chrome_plugin_placeholder.cc
@@ -16,7 +16,6 @@
#include "chrome/renderer/plugins/plugin_preroller.h"
#include "chrome/renderer/plugins/plugin_uma.h"
#include "components/content_settings/content/common/content_settings_messages.h"
-#include "content/app/strings/grit/content_strings.h"
#include "content/public/common/context_menu_params.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
@@ -45,13 +44,11 @@ using content::RenderThread;
using content::RenderView;
namespace {
-const plugins::PluginPlaceholder* g_last_active_menu = NULL;
+const ChromePluginPlaceholder* g_last_active_menu = NULL;
} // namespace
-// The placeholder is loaded in normal web renderer processes, so it should not
-// have a chrome:// scheme that might let it be confused with a WebUI page.
-const char ChromePluginPlaceholder::kPluginPlaceholderDataURL[] =
- "data:text/html,pluginplaceholderdata";
+gin::WrapperInfo ChromePluginPlaceholder::kWrapperInfo = {
+ gin::kEmbedderNativeGin};
ChromePluginPlaceholder::ChromePluginPlaceholder(
content::RenderFrame* render_frame,
@@ -62,8 +59,7 @@ ChromePluginPlaceholder::ChromePluginPlaceholder(
: plugins::LoadablePluginPlaceholder(render_frame,
frame,
params,
- html_data,
- GURL(kPluginPlaceholderDataURL)),
+ html_data),
status_(ChromeViewHostMsg_GetPluginInfo_Status::kAllowed),
title_(title),
#if defined(ENABLE_PLUGIN_INSTALLATION)
@@ -91,7 +87,7 @@ ChromePluginPlaceholder::~ChromePluginPlaceholder() {
}
// static
-ChromePluginPlaceholder* ChromePluginPlaceholder::CreateMissingPlugin(
+ChromePluginPlaceholder* ChromePluginPlaceholder::CreateLoadableMissingPlugin(
content::RenderFrame* render_frame,
WebLocalFrame* frame,
const WebPluginParams& params) {
@@ -105,34 +101,9 @@ ChromePluginPlaceholder* ChromePluginPlaceholder::CreateMissingPlugin(
std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
- // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
- ChromePluginPlaceholder* missing_plugin = new ChromePluginPlaceholder(
- render_frame, frame, params, html_data, params.mimeType);
- missing_plugin->set_allow_loading(true);
- return missing_plugin;
-}
-
-// static
-ChromePluginPlaceholder* ChromePluginPlaceholder::CreateErrorPlugin(
- content::RenderFrame* render_frame,
- const base::FilePath& file_path) {
- base::DictionaryValue values;
- values.SetString("message",
- l10n_util::GetStringUTF8(IDS_PLUGIN_INITIALIZATION_ERROR));
-
- const base::StringPiece template_html(
- ResourceBundle::GetSharedInstance().GetRawDataResource(
- IDR_BLOCKED_PLUGIN_HTML));
- std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
-
- WebPluginParams params;
- // |missing_plugin| will destroy itself when its WebViewPlugin is going away.
- ChromePluginPlaceholder* plugin = new ChromePluginPlaceholder(
- render_frame, NULL, params, html_data, params.mimeType);
-
- RenderThread::Get()->Send(new ChromeViewHostMsg_CouldNotLoadPlugin(
- plugin->routing_id(), file_path));
- return plugin;
+ // Will destroy itself when its WebViewPlugin is going away.
+ return new ChromePluginPlaceholder(render_frame, frame, params, html_data,
+ params.mimeType);
}
// static
@@ -176,10 +147,8 @@ ChromePluginPlaceholder* ChromePluginPlaceholder::CreateBlockedPlugin(
ChromePluginPlaceholder* blocked_plugin = new ChromePluginPlaceholder(
render_frame, frame, params, html_data, name);
-#if defined(ENABLE_PLUGINS)
if (!poster_info.poster_attribute.empty())
blocked_plugin->BlockForPowerSaverPoster();
-#endif
blocked_plugin->SetPluginInfo(info);
blocked_plugin->SetIdentifier(identifier);
return blocked_plugin;
@@ -305,10 +274,8 @@ void ChromePluginPlaceholder::OnMenuAction(int request_id, unsigned action) {
switch (action) {
case chrome::MENU_COMMAND_PLUGIN_RUN: {
RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Menu"));
-#if defined(ENABLE_PLUGINS)
MarkPluginEssential(
content::PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_CLICK);
-#endif
LoadPlugin();
break;
}
@@ -327,8 +294,12 @@ void ChromePluginPlaceholder::OnMenuClosed(int request_id) {
context_menu_request_id_ = 0;
}
+v8::Local<v8::Value> ChromePluginPlaceholder::GetV8Handle(
+ v8::Isolate* isolate) {
+ return gin::CreateHandle(isolate, this).ToV8();
+}
+
void ChromePluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) {
-#if !defined(OS_ANDROID) // The context menu is not applicable on Android.
if (context_menu_request_id_)
return; // Don't allow nested context menu requests.
@@ -364,12 +335,10 @@ void ChromePluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) {
context_menu_request_id_ = render_frame()->ShowContextMenu(this, params);
g_last_active_menu = this;
-#endif // OS_ANDROID
}
blink::WebPlugin* ChromePluginPlaceholder::CreatePlugin() {
scoped_ptr<content::PluginInstanceThrottler> throttler;
-#if defined(ENABLE_PLUGINS)
// If the plugin has already been marked essential in its placeholder form,
// we shouldn't create a new throttler and start the process all over again.
if (power_saver_enabled()) {
@@ -380,13 +349,21 @@ blink::WebPlugin* ChromePluginPlaceholder::CreatePlugin() {
l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, title_),
throttler.get());
}
-#endif
return render_frame()->CreatePlugin(GetFrame(), GetPluginInfo(),
GetPluginParams(), throttler.Pass());
}
gin::ObjectTemplateBuilder ChromePluginPlaceholder::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
- return LoadablePluginPlaceholder::GetObjectTemplateBuilder(isolate).SetMethod(
- "openAboutPlugins", &ChromePluginPlaceholder::OpenAboutPluginsCallback);
+ return gin::Wrappable<ChromePluginPlaceholder>::GetObjectTemplateBuilder(
+ isolate)
+ .SetMethod<void (ChromePluginPlaceholder::*)()>(
+ "hide", &ChromePluginPlaceholder::HideCallback)
+ .SetMethod<void (ChromePluginPlaceholder::*)()>(
+ "load", &ChromePluginPlaceholder::LoadCallback)
+ .SetMethod<void (ChromePluginPlaceholder::*)()>(
+ "didFinishLoading",
+ &ChromePluginPlaceholder::DidFinishLoadingCallback)
+ .SetMethod("openAboutPlugins",
+ &ChromePluginPlaceholder::OpenAboutPluginsCallback);
}
diff --git a/chrome/renderer/plugins/chrome_plugin_placeholder.h b/chrome/renderer/plugins/chrome_plugin_placeholder.h
index d5fb2f9..85d49b7 100644
--- a/chrome/renderer/plugins/chrome_plugin_placeholder.h
+++ b/chrome/renderer/plugins/chrome_plugin_placeholder.h
@@ -28,11 +28,13 @@ struct PlaceholderPosterInfo {
gfx::Size custom_poster_size;
};
-class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder,
- public content::RenderProcessObserver,
- public content::ContextMenuClient {
+class ChromePluginPlaceholder final
+ : public plugins::LoadablePluginPlaceholder,
+ public content::RenderProcessObserver,
+ public content::ContextMenuClient,
+ public gin::Wrappable<ChromePluginPlaceholder> {
public:
- static const char kPluginPlaceholderDataURL[];
+ static gin::WrapperInfo kWrapperInfo;
static ChromePluginPlaceholder* CreateBlockedPlugin(
content::RenderFrame* render_frame,
@@ -46,15 +48,11 @@ class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder,
const PlaceholderPosterInfo& poster_info);
// Creates a new WebViewPlugin with a MissingPlugin as a delegate.
- static ChromePluginPlaceholder* CreateMissingPlugin(
+ static ChromePluginPlaceholder* CreateLoadableMissingPlugin(
content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params);
- static ChromePluginPlaceholder* CreateErrorPlugin(
- content::RenderFrame* render_frame,
- const base::FilePath& plugin_path);
-
void SetStatus(ChromeViewHostMsg_GetPluginInfo_Status status);
#if defined(ENABLE_PLUGIN_INSTALLATION)
@@ -74,12 +72,13 @@ class ChromePluginPlaceholder : public plugins::LoadablePluginPlaceholder,
// gin::Wrappable (via PluginPlaceholder) method
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override;
+ v8::Isolate* isolate) final;
// content::RenderViewObserver (via PluginPlaceholder) override:
bool OnMessageReceived(const IPC::Message& message) override;
// WebViewPlugin::Delegate (via PluginPlaceholder) methods:
+ v8::Local<v8::Value> GetV8Handle(v8::Isolate* isolate) override;
void ShowContextMenu(const blink::WebMouseEvent&) override;
// content::RenderProcessObserver methods:
diff --git a/chrome/renderer/plugins/non_loadable_plugin_placeholder.cc b/chrome/renderer/plugins/non_loadable_plugin_placeholder.cc
new file mode 100644
index 0000000..598ad16
--- /dev/null
+++ b/chrome/renderer/plugins/non_loadable_plugin_placeholder.cc
@@ -0,0 +1,60 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/plugins/non_loadable_plugin_placeholder.h"
+
+#include "base/files/file_path.h"
+#include "base/values.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/grit/generated_resources.h"
+#include "chrome/grit/renderer_resources.h"
+#include "components/plugins/renderer/plugin_placeholder.h"
+#include "content/app/strings/grit/content_strings.h"
+#include "content/public/renderer/render_thread.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/webui/jstemplate_builder.h"
+
+// static
+plugins::PluginPlaceholder*
+NonLoadablePluginPlaceholder::CreateNotSupportedPlugin(
+ content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params) {
+ const base::StringPiece template_html(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_BLOCKED_PLUGIN_HTML));
+
+ base::DictionaryValue values;
+ values.SetString("message",
+ l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED));
+
+ std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
+
+ // PluginPlaceholder will destroy itself when its WebViewPlugin is going away.
+ return new plugins::PluginPlaceholder(render_frame, frame, params, html_data);
+}
+
+// static
+plugins::PluginPlaceholder* NonLoadablePluginPlaceholder::CreateErrorPlugin(
+ content::RenderFrame* render_frame,
+ const base::FilePath& file_path) {
+ base::DictionaryValue values;
+ values.SetString("message",
+ l10n_util::GetStringUTF8(IDS_PLUGIN_INITIALIZATION_ERROR));
+
+ const base::StringPiece template_html(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_BLOCKED_PLUGIN_HTML));
+ std::string html_data = webui::GetI18nTemplateHtml(template_html, &values);
+
+ blink::WebPluginParams params;
+ // PluginPlaceholder will destroy itself when its WebViewPlugin is going away.
+ plugins::PluginPlaceholder* plugin =
+ new plugins::PluginPlaceholder(render_frame, nullptr, params, html_data);
+
+ content::RenderThread::Get()->Send(new ChromeViewHostMsg_CouldNotLoadPlugin(
+ plugin->routing_id(), file_path));
+ return plugin;
+}
diff --git a/chrome/renderer/plugins/non_loadable_plugin_placeholder.h b/chrome/renderer/plugins/non_loadable_plugin_placeholder.h
new file mode 100644
index 0000000..e872e5e
--- /dev/null
+++ b/chrome/renderer/plugins/non_loadable_plugin_placeholder.h
@@ -0,0 +1,43 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_PLUGINS_NON_LOADABLE_PLUGIN_PLACEHOLDER_H_
+#define CHROME_RENDERER_PLUGINS_NON_LOADABLE_PLUGIN_PLACEHOLDER_H_
+
+#include "base/macros.h"
+
+namespace base {
+class FilePath;
+}
+
+namespace blink {
+class WebLocalFrame;
+struct WebPluginParams;
+}
+
+namespace content {
+class RenderFrame;
+}
+
+namespace plugins {
+class PluginPlaceholder;
+}
+
+class NonLoadablePluginPlaceholder {
+ public:
+ // Creates a non-loadable plugin placeholder for platforms without plugins.
+ static plugins::PluginPlaceholder* CreateNotSupportedPlugin(
+ content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params);
+
+ static plugins::PluginPlaceholder* CreateErrorPlugin(
+ content::RenderFrame* render_frame,
+ const base::FilePath& file_path);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(NonLoadablePluginPlaceholder);
+};
+
+#endif // CHROME_RENDERER_PLUGINS_NON_LOADABLE_PLUGIN_PLACEHOLDER_H_
diff --git a/chrome/renderer/plugins/plugin_preroller.cc b/chrome/renderer/plugins/plugin_preroller.cc
index 2d42f4e..6c27793 100644
--- a/chrome/renderer/plugins/plugin_preroller.cc
+++ b/chrome/renderer/plugins/plugin_preroller.cc
@@ -68,7 +68,6 @@ void PluginPreroller::OnThrottleStateChange() {
IDR_PLUGIN_POSTER_HTML, message_, poster_info);
placeholder->SetPremadePlugin(throttler_);
placeholder->set_power_saver_enabled(true);
- placeholder->set_allow_loading(true);
blink::WebPluginContainer* container =
throttler_->GetWebPlugin()->container();
diff --git a/chrome/renderer/resources/blocked_plugin.html b/chrome/renderer/resources/blocked_plugin.html
index 7a92c1d..0d4dc4a 100644
--- a/chrome/renderer/resources/blocked_plugin.html
+++ b/chrome/renderer/resources/blocked_plugin.html
@@ -3,10 +3,8 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
+<if expr="not is_android">
<script>
-function debug(msg) {
- document.getElementById('debug').textContent = msg;
-}
function setMessage(msg) {
document.getElementById('message').textContent = msg;
}
@@ -15,6 +13,12 @@ function notifyDidFinishLoading() {
plugin.didFinishLoading();
}
</script>
+</if>
+<if expr="is_android">
+<script>
+function notifyDidFinishLoading() {}
+</script>
+</if>
<link rel="stylesheet" href="plugin_placeholders.css"></link>
<style>
body {
@@ -37,7 +41,6 @@ body {
<img id="plugin_icon" src="plugin_blocked_android.png">
</if>
<h1 id="message" i18n-content="message"></h1>
-<p id="debug"> </p>
</div>
<div id="close" i18n-values="title:hide" onclick="plugin.hide();"></div>
</div>
diff --git a/components/plugins.gypi b/components/plugins.gypi
index fde25c6..9061833 100644
--- a/components/plugins.gypi
+++ b/components/plugins.gypi
@@ -36,14 +36,19 @@
],
'sources': [
# Note: sources list duplicated in GN build.
- 'plugins/renderer/loadable_plugin_placeholder.cc',
- 'plugins/renderer/loadable_plugin_placeholder.h',
'plugins/renderer/plugin_placeholder.cc',
'plugins/renderer/plugin_placeholder.h',
'plugins/renderer/webview_plugin.cc',
'plugins/renderer/webview_plugin.h',
],
'conditions' : [
+ ['enable_plugins==1', {
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'plugins/renderer/loadable_plugin_placeholder.cc',
+ 'plugins/renderer/loadable_plugin_placeholder.h',
+ ]
+ }],
['OS=="android"', {
'sources': [
# Note: sources list duplicated in GN build.
diff --git a/components/plugins/renderer/BUILD.gn b/components/plugins/renderer/BUILD.gn
index ef7e8f1..446ad99 100644
--- a/components/plugins/renderer/BUILD.gn
+++ b/components/plugins/renderer/BUILD.gn
@@ -2,15 +2,21 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/config/features.gni")
+
static_library("renderer") {
sources = [
- "loadable_plugin_placeholder.cc",
- "loadable_plugin_placeholder.h",
"plugin_placeholder.cc",
"plugin_placeholder.h",
"webview_plugin.cc",
"webview_plugin.h",
]
+ if (enable_plugins) {
+ sources += [
+ "loadable_plugin_placeholder.cc",
+ "loadable_plugin_placeholder.h",
+ ]
+ }
if (is_android) {
sources += [
"mobile_youtube_plugin.cc",
diff --git a/components/plugins/renderer/loadable_plugin_placeholder.cc b/components/plugins/renderer/loadable_plugin_placeholder.cc
index ea288e2..a41c9ea 100644
--- a/components/plugins/renderer/loadable_plugin_placeholder.cc
+++ b/components/plugins/renderer/loadable_plugin_placeholder.cc
@@ -9,7 +9,6 @@
#include "base/command_line.h"
#include "base/json/string_escape.h"
#include "base/strings/string_piece.h"
-#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
@@ -29,24 +28,13 @@
#include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
#include "third_party/WebKit/public/web/WebView.h"
-#include "third_party/re2/re2/re2.h"
using base::UserMetricsAction;
-using blink::WebElement;
-using blink::WebLocalFrame;
-using blink::WebMouseEvent;
-using blink::WebNode;
-using blink::WebPlugin;
-using blink::WebPluginContainer;
-using blink::WebPluginParams;
-using blink::WebScriptSource;
-using blink::WebURLRequest;
using content::PluginInstanceThrottler;
using content::RenderThread;
namespace plugins {
-#if defined(ENABLE_PLUGINS)
// TODO(tommycli): After an unthrottling size update, re-check the size after
// this delay, as Blink can report incorrect sizes to plugins while the
// compositing state is dirty. Chosen because it seems to work.
@@ -69,26 +57,19 @@ void LoadablePluginPlaceholder::SetPremadePlugin(
DCHECK(!premade_throttler_);
premade_throttler_ = throttler;
}
-#endif
LoadablePluginPlaceholder::LoadablePluginPlaceholder(
content::RenderFrame* render_frame,
- WebLocalFrame* frame,
- const WebPluginParams& params,
- const std::string& html_data,
- GURL placeholderDataUrl)
- : PluginPlaceholder(render_frame,
- frame,
- params,
- html_data,
- placeholderDataUrl),
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data)
+ : PluginPlaceholderBase(render_frame, frame, params, html_data),
is_blocked_for_background_tab_(false),
is_blocked_for_prerendering_(false),
is_blocked_for_power_saver_poster_(false),
power_saver_enabled_(false),
premade_throttler_(nullptr),
- allow_loading_(false),
- hidden_(false),
+ allow_loading_(true),
finished_loading_(false),
in_size_recheck_(false),
weak_factory_(this) {
@@ -97,7 +78,6 @@ LoadablePluginPlaceholder::LoadablePluginPlaceholder(
LoadablePluginPlaceholder::~LoadablePluginPlaceholder() {
}
-#if defined(ENABLE_PLUGINS)
void LoadablePluginPlaceholder::MarkPluginEssential(
PluginInstanceThrottler::PowerSaverUnthrottleMethod method) {
if (!power_saver_enabled_)
@@ -116,39 +96,17 @@ void LoadablePluginPlaceholder::MarkPluginEssential(
LoadPlugin();
}
}
-#endif
-
-void LoadablePluginPlaceholder::BindWebFrame(blink::WebFrame* frame) {
- v8::Isolate* isolate = blink::mainThreadIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context = frame->mainWorldScriptContext();
- DCHECK(!context.IsEmpty());
-
- v8::Context::Scope context_scope(context);
- v8::Local<v8::Object> global = context->Global();
- global->Set(gin::StringToV8(isolate, "plugin"),
- gin::CreateHandle(isolate, this).ToV8());
-}
-
-gin::ObjectTemplateBuilder LoadablePluginPlaceholder::GetObjectTemplateBuilder(
- v8::Isolate* isolate) {
- return gin::Wrappable<PluginPlaceholder>::GetObjectTemplateBuilder(isolate)
- .SetMethod("load", &LoadablePluginPlaceholder::LoadCallback)
- .SetMethod("hide", &LoadablePluginPlaceholder::HideCallback)
- .SetMethod("didFinishLoading",
- &LoadablePluginPlaceholder::DidFinishLoadingCallback);
-}
-void LoadablePluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
+void LoadablePluginPlaceholder::ReplacePlugin(blink::WebPlugin* new_plugin) {
CHECK(plugin());
if (!new_plugin)
return;
- WebPluginContainer* container = plugin()->container();
+ blink::WebPluginContainer* container = plugin()->container();
// Set the new plugin on the container before initializing it.
container->setPlugin(new_plugin);
// Save the element in case the plugin is removed from the page during
// initialization.
- WebElement element = container->element();
+ blink::WebElement element = container->element();
bool plugin_needs_initialization =
!premade_throttler_ || new_plugin != premade_throttler_->GetWebPlugin();
if (plugin_needs_initialization && !new_plugin->initialize(container)) {
@@ -176,54 +134,6 @@ void LoadablePluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) {
plugin()->destroy();
}
-void LoadablePluginPlaceholder::HidePlugin() {
- hidden_ = true;
- if (!plugin())
- return;
- WebPluginContainer* container = plugin()->container();
- WebElement element = container->element();
- element.setAttribute("style", "display: none;");
- // If we have a width and height, search for a parent (often <div>) with the
- // same dimensions. If we find such a parent, hide that as well.
- // This makes much more uncovered page content usable (including clickable)
- // as opposed to merely visible.
- // TODO(cevans) -- it's a foul heuristic but we're going to tolerate it for
- // now for these reasons:
- // 1) Makes the user experience better.
- // 2) Foulness is encapsulated within this single function.
- // 3) Confidence in no fasle positives.
- // 4) Seems to have a good / low false negative rate at this time.
- if (element.hasAttribute("width") && element.hasAttribute("height")) {
- std::string width_str("width:[\\s]*");
- width_str += element.getAttribute("width").utf8().data();
- if (EndsWith(width_str, "px", false)) {
- width_str = width_str.substr(0, width_str.length() - 2);
- }
- base::TrimWhitespace(width_str, base::TRIM_TRAILING, &width_str);
- width_str += "[\\s]*px";
- std::string height_str("height:[\\s]*");
- height_str += element.getAttribute("height").utf8().data();
- if (EndsWith(height_str, "px", false)) {
- height_str = height_str.substr(0, height_str.length() - 2);
- }
- base::TrimWhitespace(height_str, base::TRIM_TRAILING, &height_str);
- height_str += "[\\s]*px";
- WebNode parent = element;
- while (!parent.parentNode().isNull()) {
- parent = parent.parentNode();
- if (!parent.isElementNode())
- continue;
- element = parent.toConst<WebElement>();
- if (element.hasAttribute("style")) {
- std::string style_str = element.getAttribute("style").utf8();
- if (RE2::PartialMatch(style_str, width_str) &&
- RE2::PartialMatch(style_str, height_str))
- element.setAttribute("style", "display: none;");
- }
- }
- }
-}
-
void LoadablePluginPlaceholder::SetMessage(const base::string16& message) {
message_ = message;
if (finished_loading_)
@@ -236,11 +146,10 @@ void LoadablePluginPlaceholder::UpdateMessage() {
std::string script =
"window.setMessage(" + base::GetQuotedJSONString(message_) + ")";
plugin()->web_view()->mainFrame()->executeScript(
- WebScriptSource(base::UTF8ToUTF16(script)));
+ blink::WebScriptSource(base::UTF8ToUTF16(script)));
}
void LoadablePluginPlaceholder::PluginDestroyed() {
-#if defined(ENABLE_PLUGINS)
if (power_saver_enabled_) {
if (premade_throttler_) {
// Since the premade plugin has been detached from the container, it will
@@ -256,23 +165,19 @@ void LoadablePluginPlaceholder::PluginDestroyed() {
// Prevent processing subsequent calls to MarkPluginEssential.
power_saver_enabled_ = false;
}
-#endif
- PluginPlaceholder::PluginDestroyed();
+ PluginPlaceholderBase::PluginDestroyed();
}
v8::Local<v8::Object> LoadablePluginPlaceholder::GetV8ScriptableObject(
v8::Isolate* isolate) const {
-#if defined(ENABLE_PLUGINS)
// Pass through JavaScript access to the underlying throttled plugin.
if (premade_throttler_ && premade_throttler_->GetWebPlugin()) {
return premade_throttler_->GetWebPlugin()->v8ScriptableObject(isolate);
}
-#endif
return v8::Local<v8::Object>();
}
-#if defined(ENABLE_PLUGINS)
void LoadablePluginPlaceholder::OnUnobscuredSizeUpdate(
const gfx::Size& unobscured_size) {
DCHECK(
@@ -304,7 +209,6 @@ void LoadablePluginPlaceholder::OnUnobscuredSizeUpdate(
size_update_timer_.Stop();
}
}
-#endif // defined(ENABLE_PLUGINS)
void LoadablePluginPlaceholder::WasShown() {
if (is_blocked_for_background_tab_) {
@@ -337,7 +241,7 @@ void LoadablePluginPlaceholder::OnSetIsPrerendering(bool is_prerendering) {
void LoadablePluginPlaceholder::LoadPlugin() {
// This is not strictly necessary but is an important defense in case the
// event propagation changes between "close" vs. "click-to-play".
- if (hidden_)
+ if (hidden())
return;
if (!plugin())
return;
@@ -357,19 +261,12 @@ void LoadablePluginPlaceholder::LoadPlugin() {
void LoadablePluginPlaceholder::LoadCallback() {
RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Load_Click"));
-#if defined(ENABLE_PLUGINS)
// If the user specifically clicks on the plugin content's placeholder,
// disable power saver throttling for this instance.
MarkPluginEssential(PluginInstanceThrottler::UNTHROTTLE_METHOD_BY_CLICK);
-#endif
LoadPlugin();
}
-void LoadablePluginPlaceholder::HideCallback() {
- RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Hide_Click"));
- HidePlugin();
-}
-
void LoadablePluginPlaceholder::DidFinishLoadingCallback() {
finished_loading_ = true;
if (message_.length() > 0)
@@ -384,7 +281,7 @@ void LoadablePluginPlaceholder::DidFinishLoadingCallback() {
// placeholder to be ready to receive simulated user input.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnablePluginPlaceholderTesting)) {
- WebElement element = plugin()->container()->element();
+ blink::WebElement element = plugin()->container()->element();
element.setAttribute("placeholderLoaded", "true");
scoped_ptr<content::V8ValueConverter> converter(
@@ -430,7 +327,6 @@ bool LoadablePluginPlaceholder::LoadingBlocked() const {
is_blocked_for_prerendering_;
}
-#if defined(ENABLE_PLUGINS)
void LoadablePluginPlaceholder::RecheckSizeAndMaybeUnthrottle() {
DCHECK(
content::RenderThread::Get()->GetTaskRunner()->BelongsToCurrentThread());
@@ -448,6 +344,5 @@ void LoadablePluginPlaceholder::RecheckSizeAndMaybeUnthrottle() {
in_size_recheck_ = false;
}
-#endif // defined(ENABLE_PLUGINS)
} // namespace plugins
diff --git a/components/plugins/renderer/loadable_plugin_placeholder.h b/components/plugins/renderer/loadable_plugin_placeholder.h
index 0111dff..13b903d 100644
--- a/components/plugins/renderer/loadable_plugin_placeholder.h
+++ b/components/plugins/renderer/loadable_plugin_placeholder.h
@@ -10,11 +10,12 @@
#include "components/plugins/renderer/plugin_placeholder.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/renderer/plugin_instance_throttler.h"
+#include "content/public/renderer/render_thread.h"
namespace plugins {
// Placeholders can be used if a plugin is missing or not available
// (blocked or disabled).
-class LoadablePluginPlaceholder : public PluginPlaceholder {
+class LoadablePluginPlaceholder : public PluginPlaceholderBase {
public:
void set_blocked_for_background_tab(bool blocked_for_background_tab) {
is_blocked_for_background_tab_ = blocked_for_background_tab;
@@ -24,7 +25,6 @@ class LoadablePluginPlaceholder : public PluginPlaceholder {
is_blocked_for_prerendering_ = blocked_for_prerendering;
}
-#if defined(ENABLE_PLUGINS)
bool power_saver_enabled() const { return power_saver_enabled_; }
void set_power_saver_enabled(bool power_saver_enabled) {
@@ -36,23 +36,19 @@ class LoadablePluginPlaceholder : public PluginPlaceholder {
// When we load the plugin, use this already-created plugin, not a new one.
void SetPremadePlugin(content::PluginInstanceThrottler* throttler);
-#endif
- void set_allow_loading(bool allow_loading) { allow_loading_ = allow_loading; }
+ void DisallowLoading() { allow_loading_ = false; }
protected:
LoadablePluginPlaceholder(content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
- const std::string& html_data,
- GURL placeholderDataUrl);
+ const std::string& html_data);
~LoadablePluginPlaceholder() override;
-#if defined(ENABLE_PLUGINS)
void MarkPluginEssential(
content::PluginInstanceThrottler::PowerSaverUnthrottleMethod method);
-#endif
void OnLoadBlockedPlugins(const std::string& identifier);
void OnSetIsPrerendering(bool is_prerendering);
@@ -68,42 +64,27 @@ class LoadablePluginPlaceholder : public PluginPlaceholder {
// a placeholder again).
void ReplacePlugin(blink::WebPlugin* new_plugin);
- // Hide this placeholder.
- void HidePlugin();
-
// Load the blocked plugin.
void LoadPlugin();
- // WebViewPlugin::Delegate (via PluginPlaceholder) method
- void BindWebFrame(blink::WebFrame* frame) override;
-
- // gin::Wrappable method:
- gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override;
+ // Javascript callbacks:
+ void LoadCallback();
+ void DidFinishLoadingCallback();
private:
// WebViewPlugin::Delegate methods:
void PluginDestroyed() override;
v8::Local<v8::Object> GetV8ScriptableObject(
v8::Isolate* isolate) const override;
-#if defined(ENABLE_PLUGINS)
void OnUnobscuredSizeUpdate(const gfx::Size& unobscured_size) override;
-#endif
// RenderFrameObserver methods:
void WasShown() override;
- // Javascript callbacks:
- void LoadCallback();
- void HideCallback();
- void DidFinishLoadingCallback();
-
void UpdateMessage();
bool LoadingBlocked() const;
-#if defined(ENABLE_PLUGINS)
void RecheckSizeAndMaybeUnthrottle();
-#endif
// Plugin creation is embedder-specific.
virtual blink::WebPlugin* CreatePlugin() = 0;
@@ -132,7 +113,6 @@ class LoadablePluginPlaceholder : public PluginPlaceholder {
bool allow_loading_;
- bool hidden_;
bool finished_loading_;
std::string identifier_;
diff --git a/components/plugins/renderer/mobile_youtube_plugin.cc b/components/plugins/renderer/mobile_youtube_plugin.cc
index 6db102a..9745a0a 100644
--- a/components/plugins/renderer/mobile_youtube_plugin.cc
+++ b/components/plugins/renderer/mobile_youtube_plugin.cc
@@ -11,10 +11,8 @@
#include "base/values.h"
#include "content/public/common/content_constants.h"
#include "content/public/renderer/render_frame.h"
-#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebKit.h"
#include "ui/base/webui/jstemplate_builder.h"
using blink::WebFrame;
@@ -73,16 +71,17 @@ bool IsValidYouTubeVideo(const std::string& path) {
namespace plugins {
+gin::WrapperInfo MobileYouTubePlugin::kWrapperInfo = {gin::kEmbedderNativeGin};
+
MobileYouTubePlugin::MobileYouTubePlugin(content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
- base::StringPiece& template_html,
- GURL placeholderDataUrl)
- : PluginPlaceholder(render_frame,
- frame,
- params,
- HtmlData(params, template_html),
- placeholderDataUrl) {}
+ base::StringPiece& template_html)
+ : PluginPlaceholderBase(render_frame,
+ frame,
+ params,
+ HtmlData(params, template_html)) {
+}
MobileYouTubePlugin::~MobileYouTubePlugin() {}
@@ -108,22 +107,15 @@ void MobileYouTubePlugin::OpenYoutubeUrlCallback() {
GetFrame(), request, blink::WebNavigationPolicyNewForegroundTab);
}
-void MobileYouTubePlugin::BindWebFrame(WebFrame* frame) {
- v8::Isolate* isolate = blink::mainThreadIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context = frame->mainWorldScriptContext();
- DCHECK(!context.IsEmpty());
-
- v8::Context::Scope context_scope(context);
- v8::Local<v8::Object> global = context->Global();
- global->Set(gin::StringToV8(isolate, "plugin"),
- gin::CreateHandle(isolate, this).ToV8());
+v8::Local<v8::Value> MobileYouTubePlugin::GetV8Handle(v8::Isolate* isolate) {
+ return gin::CreateHandle(isolate, this).ToV8();
}
gin::ObjectTemplateBuilder MobileYouTubePlugin::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
- return PluginPlaceholder::GetObjectTemplateBuilder(isolate)
- .SetMethod("openYoutubeURL", &MobileYouTubePlugin::OpenYoutubeUrlCallback);
+ return gin::Wrappable<MobileYouTubePlugin>::GetObjectTemplateBuilder(isolate)
+ .SetMethod("openYoutubeURL",
+ &MobileYouTubePlugin::OpenYoutubeUrlCallback);
}
} // namespace plugins
diff --git a/components/plugins/renderer/mobile_youtube_plugin.h b/components/plugins/renderer/mobile_youtube_plugin.h
index 99a6213..9d46700 100644
--- a/components/plugins/renderer/mobile_youtube_plugin.h
+++ b/components/plugins/renderer/mobile_youtube_plugin.h
@@ -14,13 +14,15 @@ namespace plugins {
// of http://www.youtube.com/v/VIDEO_ID. This placeholder replaces the url with
// a simple html page and clicking the play image redirects the user to the
// mobile youtube app.
-class MobileYouTubePlugin : public PluginPlaceholder {
+class MobileYouTubePlugin final : public PluginPlaceholderBase,
+ public gin::Wrappable<MobileYouTubePlugin> {
public:
+ static gin::WrapperInfo kWrapperInfo;
+
MobileYouTubePlugin(content::RenderFrame* render_frame,
blink::WebLocalFrame* frame,
const blink::WebPluginParams& params,
- base::StringPiece& template_html,
- GURL placeholderDataUrl);
+ base::StringPiece& template_html);
// Whether this is a youtube url.
static bool IsYouTubeURL(const GURL& url, const std::string& mime_type);
@@ -31,12 +33,12 @@ class MobileYouTubePlugin : public PluginPlaceholder {
// Opens a youtube app in the current tab.
void OpenYoutubeUrlCallback();
- // WebViewPlugin::Delegate (via PluginPlaceholder) method
- void BindWebFrame(blink::WebFrame* frame) override;
+ // WebViewPlugin::Delegate methods:
+ v8::Local<v8::Value> GetV8Handle(v8::Isolate* isolate) override;
// gin::Wrappable (via PluginPlaceholder) method
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override;
+ v8::Isolate* isolate) final;
DISALLOW_COPY_AND_ASSIGN(MobileYouTubePlugin);
};
diff --git a/components/plugins/renderer/plugin_placeholder.cc b/components/plugins/renderer/plugin_placeholder.cc
index 180e913..98fc8cb 100644
--- a/components/plugins/renderer/plugin_placeholder.cc
+++ b/components/plugins/renderer/plugin_placeholder.cc
@@ -4,18 +4,26 @@
#include "components/plugins/renderer/plugin_placeholder.h"
+#include "base/strings/string_util.h"
#include "content/public/common/web_preferences.h"
#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_thread.h"
+#include "gin/object_template_builder.h"
+#include "third_party/WebKit/public/web/WebElement.h"
+#include "third_party/WebKit/public/web/WebPluginContainer.h"
+#include "third_party/re2/re2/re2.h"
namespace plugins {
-gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin};
+// The placeholder is loaded in normal web renderer processes, so it should not
+// have a chrome:// scheme that might let it be confused with a WebUI page.
+const char kPluginPlaceholderDataURL[] = "data:text/html,pluginplaceholderdata";
-PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
- const blink::WebPluginParams& params,
- const std::string& html_data,
- GURL placeholderDataUrl)
+PluginPlaceholderBase::PluginPlaceholderBase(
+ content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data)
: content::RenderFrameObserver(render_frame),
frame_(frame),
plugin_params_(params),
@@ -24,36 +32,116 @@ PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
? render_frame->GetWebkitPreferences()
: content::WebPreferences(),
html_data,
- placeholderDataUrl)) {
- DCHECK(placeholderDataUrl.is_valid())
- << "Blink requires the placeholder to have a valid URL.";
+ GURL(kPluginPlaceholderDataURL))),
+ hidden_(false) {
}
-PluginPlaceholder::~PluginPlaceholder() {}
+PluginPlaceholderBase::~PluginPlaceholderBase() {
+}
-const blink::WebPluginParams& PluginPlaceholder::GetPluginParams() const {
+const blink::WebPluginParams& PluginPlaceholderBase::GetPluginParams() const {
return plugin_params_;
}
-void PluginPlaceholder::ShowContextMenu(const blink::WebMouseEvent& event) {
+void PluginPlaceholderBase::ShowContextMenu(const blink::WebMouseEvent& event) {
// Does nothing by default. Will be overridden if a specific browser wants
// a context menu.
return;
}
-void PluginPlaceholder::PluginDestroyed() {
+void PluginPlaceholderBase::PluginDestroyed() {
plugin_ = NULL;
}
-v8::Local<v8::Object> PluginPlaceholder::GetV8ScriptableObject(
+v8::Local<v8::Object> PluginPlaceholderBase::GetV8ScriptableObject(
v8::Isolate* isolate) const {
return v8::Local<v8::Object>();
}
-void PluginPlaceholder::OnDestruct() {
+void PluginPlaceholderBase::HidePlugin() {
+ hidden_ = true;
+ if (!plugin())
+ return;
+ blink::WebPluginContainer* container = plugin()->container();
+ blink::WebElement element = container->element();
+ element.setAttribute("style", "display: none;");
+ // If we have a width and height, search for a parent (often <div>) with the
+ // same dimensions. If we find such a parent, hide that as well.
+ // This makes much more uncovered page content usable (including clickable)
+ // as opposed to merely visible.
+ // TODO(cevans) -- it's a foul heuristic but we're going to tolerate it for
+ // now for these reasons:
+ // 1) Makes the user experience better.
+ // 2) Foulness is encapsulated within this single function.
+ // 3) Confidence in no fasle positives.
+ // 4) Seems to have a good / low false negative rate at this time.
+ if (element.hasAttribute("width") && element.hasAttribute("height")) {
+ std::string width_str("width:[\\s]*");
+ width_str += element.getAttribute("width").utf8().data();
+ if (EndsWith(width_str, "px", false)) {
+ width_str = width_str.substr(0, width_str.length() - 2);
+ }
+ base::TrimWhitespace(width_str, base::TRIM_TRAILING, &width_str);
+ width_str += "[\\s]*px";
+ std::string height_str("height:[\\s]*");
+ height_str += element.getAttribute("height").utf8().data();
+ if (EndsWith(height_str, "px", false)) {
+ height_str = height_str.substr(0, height_str.length() - 2);
+ }
+ base::TrimWhitespace(height_str, base::TRIM_TRAILING, &height_str);
+ height_str += "[\\s]*px";
+ blink::WebNode parent = element;
+ while (!parent.parentNode().isNull()) {
+ parent = parent.parentNode();
+ if (!parent.isElementNode())
+ continue;
+ element = parent.toConst<blink::WebElement>();
+ if (element.hasAttribute("style")) {
+ std::string style_str = element.getAttribute("style").utf8();
+ if (RE2::PartialMatch(style_str, width_str) &&
+ RE2::PartialMatch(style_str, height_str))
+ element.setAttribute("style", "display: none;");
+ }
+ }
+ }
+}
+
+void PluginPlaceholderBase::HideCallback() {
+ content::RenderThread::Get()->RecordAction(
+ base::UserMetricsAction("Plugin_Hide_Click"));
+ HidePlugin();
+}
+
+void PluginPlaceholderBase::OnDestruct() {
frame_ = NULL;
}
-blink::WebLocalFrame* PluginPlaceholder::GetFrame() { return frame_; }
+blink::WebLocalFrame* PluginPlaceholderBase::GetFrame() {
+ return frame_;
+}
+
+// static
+gin::WrapperInfo PluginPlaceholder::kWrapperInfo = {gin::kEmbedderNativeGin};
+
+PluginPlaceholder::PluginPlaceholder(content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data)
+ : PluginPlaceholderBase(render_frame, frame, params, html_data) {
+}
+
+PluginPlaceholder::~PluginPlaceholder() {
+}
+
+v8::Local<v8::Value> PluginPlaceholder::GetV8Handle(v8::Isolate* isolate) {
+ return gin::CreateHandle(isolate, this).ToV8();
+}
+
+gin::ObjectTemplateBuilder PluginPlaceholder::GetObjectTemplateBuilder(
+ v8::Isolate* isolate) {
+ return gin::Wrappable<PluginPlaceholder>::GetObjectTemplateBuilder(isolate)
+ .SetMethod<void (plugins::PluginPlaceholder::*)()>(
+ "hide", &PluginPlaceholder::HideCallback);
+}
} // namespace plugins
diff --git a/components/plugins/renderer/plugin_placeholder.h b/components/plugins/renderer/plugin_placeholder.h
index 5d9caa1..63a1d08 100644
--- a/components/plugins/renderer/plugin_placeholder.h
+++ b/components/plugins/renderer/plugin_placeholder.h
@@ -8,30 +8,29 @@
#include "base/memory/weak_ptr.h"
#include "components/plugins/renderer/webview_plugin.h"
#include "content/public/renderer/render_frame_observer.h"
+#include "gin/handle.h"
#include "gin/wrappable.h"
+#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebPluginParams.h"
namespace plugins {
-class PluginPlaceholder : public content::RenderFrameObserver,
- public WebViewPlugin::Delegate,
- public gin::Wrappable<PluginPlaceholder> {
+// This abstract class is the base class of all plugin placeholders.
+class PluginPlaceholderBase : public content::RenderFrameObserver,
+ public WebViewPlugin::Delegate {
public:
- static gin::WrapperInfo kWrapperInfo;
-
- WebViewPlugin* plugin() { return plugin_; }
-
- protected:
// |render_frame| and |frame| are weak pointers. If either one is going away,
// our |plugin_| will be destroyed as well and will notify us.
- PluginPlaceholder(content::RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
- const blink::WebPluginParams& params,
- const std::string& html_data,
- GURL placeholderDataUrl);
+ PluginPlaceholderBase(content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data);
- ~PluginPlaceholder() override;
+ ~PluginPlaceholderBase() override;
+
+ WebViewPlugin* plugin() { return plugin_; }
+ protected:
blink::WebLocalFrame* GetFrame();
const blink::WebPluginParams& GetPluginParams() const;
@@ -41,6 +40,14 @@ class PluginPlaceholder : public content::RenderFrameObserver,
v8::Local<v8::Object> GetV8ScriptableObject(
v8::Isolate* isolate) const override;
+ protected:
+ // Hide this placeholder.
+ void HidePlugin();
+ bool hidden() { return hidden_; }
+
+ // JavaScript callbacks:
+ void HideCallback();
+
private:
// RenderFrameObserver methods:
void OnDestruct() override;
@@ -49,7 +56,30 @@ class PluginPlaceholder : public content::RenderFrameObserver,
blink::WebPluginParams plugin_params_;
WebViewPlugin* plugin_;
- DISALLOW_COPY_AND_ASSIGN(PluginPlaceholder);
+ bool hidden_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginPlaceholderBase);
+};
+
+// A basic placeholder that supports only hiding.
+class PluginPlaceholder final : public PluginPlaceholderBase,
+ public gin::Wrappable<PluginPlaceholder> {
+ public:
+ static gin::WrapperInfo kWrapperInfo;
+
+ PluginPlaceholder(content::RenderFrame* render_frame,
+ blink::WebLocalFrame* frame,
+ const blink::WebPluginParams& params,
+ const std::string& html_data);
+ ~PluginPlaceholder() override;
+
+ private:
+ // WebViewPlugin::Delegate methods:
+ v8::Local<v8::Value> GetV8Handle(v8::Isolate* isolate) final;
+
+ // gin::Wrappable method:
+ gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
+ v8::Isolate* isolate) override;
};
} // namespace plugins
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc
index 43cd43e..0779566 100644
--- a/components/plugins/renderer/webview_plugin.cc
+++ b/components/plugins/renderer/webview_plugin.cc
@@ -9,6 +9,7 @@
#include "base/numerics/safe_conversions.h"
#include "content/public/common/web_preferences.h"
#include "content/public/renderer/render_view.h"
+#include "gin/converter.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/platform/WebURL.h"
@@ -61,6 +62,7 @@ WebViewPlugin* WebViewPlugin::Create(WebViewPlugin::Delegate* delegate,
const WebPreferences& preferences,
const std::string& html_data,
const GURL& url) {
+ DCHECK(url.is_valid()) << "Blink requires the WebView to have a valid URL.";
WebViewPlugin* plugin = new WebViewPlugin(delegate, preferences);
plugin->web_view()->mainFrame()->loadHTMLString(html_data, url);
return plugin;
@@ -264,8 +266,19 @@ void WebViewPlugin::scheduleAnimation() {
}
void WebViewPlugin::didClearWindowObject(WebLocalFrame* frame) {
- if (delegate_)
- delegate_->BindWebFrame(frame);
+ if (!delegate_)
+ return;
+
+ v8::Isolate* isolate = blink::mainThreadIsolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = frame->mainWorldScriptContext();
+ DCHECK(!context.IsEmpty());
+
+ v8::Context::Scope context_scope(context);
+ v8::Local<v8::Object> global = context->Global();
+
+ global->Set(gin::StringToV8(isolate, "plugin"),
+ delegate_->GetV8Handle(isolate));
}
void WebViewPlugin::didReceiveResponse(WebLocalFrame* frame,
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h
index 3286fae..fdb9777 100644
--- a/components/plugins/renderer/webview_plugin.h
+++ b/components/plugins/renderer/webview_plugin.h
@@ -13,6 +13,7 @@
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/web/WebFrameClient.h"
+#include "third_party/WebKit/public/web/WebKit.h"
#include "third_party/WebKit/public/web/WebPlugin.h"
#include "third_party/WebKit/public/web/WebViewClient.h"
@@ -42,10 +43,8 @@ class WebViewPlugin : public blink::WebPlugin,
public:
class Delegate {
public:
- // Bind |frame| to a Javascript object, enabling the delegate to receive
- // callback methods from Javascript inside the WebFrame.
- // This method is called from WebFrameClient::didClearWindowObject.
- virtual void BindWebFrame(blink::WebFrame* frame) = 0;
+ // Called to get the V8 handle used to bind the lifetime to the frame.
+ virtual v8::Local<v8::Value> GetV8Handle(v8::Isolate*) = 0;
// Called upon a context menu event.
virtual void ShowContextMenu(const blink::WebMouseEvent&) = 0;
diff --git a/content/content_shell.gypi b/content/content_shell.gypi
index 2f30de3..5e65727 100644
--- a/content/content_shell.gypi
+++ b/content/content_shell.gypi
@@ -226,8 +226,6 @@
'shell/renderer/layout_test/leak_detector.h',
'shell/renderer/layout_test/test_media_stream_renderer_factory.cc',
'shell/renderer/layout_test/test_media_stream_renderer_factory.h',
- 'shell/renderer/layout_test/test_plugin_placeholder.cc',
- 'shell/renderer/layout_test/test_plugin_placeholder.h',
'shell/renderer/layout_test/test_video_frame_provider.cc',
'shell/renderer/layout_test/test_video_frame_provider.h',
'shell/renderer/shell_content_renderer_client.cc',
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index d505da3..b736942 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -162,8 +162,6 @@ static_library("content_shell_lib") {
"renderer/layout_test/leak_detector.h",
"renderer/layout_test/test_media_stream_renderer_factory.cc",
"renderer/layout_test/test_media_stream_renderer_factory.h",
- "renderer/layout_test/test_plugin_placeholder.cc",
- "renderer/layout_test/test_plugin_placeholder.h",
"renderer/layout_test/test_video_frame_provider.cc",
"renderer/layout_test/test_video_frame_provider.h",
"renderer/shell_content_renderer_client.cc",
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc
index 009f475..ebba115 100644
--- a/content/shell/renderer/layout_test/blink_test_runner.cc
+++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -23,6 +23,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "components/plugins/renderer/plugin_placeholder.h"
#include "components/test_runner/app_banner_client.h"
#include "components/test_runner/gamepad_controller.h"
#include "components/test_runner/mock_screen_orientation_client.h"
@@ -46,7 +47,6 @@
#include "content/shell/renderer/layout_test/gc_controller.h"
#include "content/shell/renderer/layout_test/layout_test_render_process_observer.h"
#include "content/shell/renderer/layout_test/leak_detector.h"
-#include "content/shell/renderer/layout_test/test_plugin_placeholder.h"
#include "net/base/filename_util.h"
#include "net/base/net_errors.h"
#include "skia/ext/platform_canvas.h"
@@ -688,10 +688,13 @@ void BlinkTestRunner::ResolveBeforeInstallPromptPromise(
blink::WebPlugin* BlinkTestRunner::CreatePluginPlaceholder(
blink::WebLocalFrame* frame, const blink::WebPluginParams& params) {
- if (params.mimeType == "application/x-plugin-placeholder-test")
- return (new TestPluginPlaceholder(render_view()->GetMainRenderFrame(),
- frame, params))->plugin();
- return 0;
+ if (params.mimeType != "application/x-plugin-placeholder-test")
+ return nullptr;
+
+ plugins::PluginPlaceholder* placeholder =
+ new plugins::PluginPlaceholder(render_view()->GetMainRenderFrame(), frame,
+ params, "<div>Test content</div>");
+ return placeholder->plugin();
}
// RenderViewObserver --------------------------------------------------------
diff --git a/content/shell/renderer/layout_test/test_plugin_placeholder.cc b/content/shell/renderer/layout_test/test_plugin_placeholder.cc
deleted file mode 100644
index 5b5a071..0000000
--- a/content/shell/renderer/layout_test/test_plugin_placeholder.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/shell/renderer/layout_test/test_plugin_placeholder.h"
-
-#include "gin/handle.h"
-#include "third_party/WebKit/public/web/WebKit.h"
-
-namespace content {
-
-TestPluginPlaceholder::TestPluginPlaceholder(
- RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
- const blink::WebPluginParams& params)
- : PluginPlaceholder(render_frame,
- frame,
- params,
- "<div>Test content</div>",
- GURL("http://www.test.com")) {
-}
-
-void TestPluginPlaceholder::BindWebFrame(blink::WebFrame* frame) {
- v8::Isolate* isolate = blink::mainThreadIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context = frame->mainWorldScriptContext();
- DCHECK(!context.IsEmpty());
-
- v8::Context::Scope context_scope(context);
- v8::Local<v8::Object> global = context->Global();
- global->Set(gin::StringToV8(isolate, "plugin"),
- gin::CreateHandle(isolate, this).ToV8());
-}
-
-} // namespace content
diff --git a/content/shell/renderer/layout_test/test_plugin_placeholder.h b/content/shell/renderer/layout_test/test_plugin_placeholder.h
deleted file mode 100644
index 1424923..0000000
--- a/content/shell/renderer/layout_test/test_plugin_placeholder.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef CONTENT_SHELL_RENDERER_TEST_RUNNER_TEST_PLUGIN_PLACEHOLDER_H_
-#define CONTENT_SHELL_RENDERER_TEST_RUNNER_TEST_PLUGIN_PLACEHOLDER_H_
-
-#include "components/plugins/renderer/plugin_placeholder.h"
-
-namespace content {
-
-// A subclass of PluginPlaceholder for use in Blink layout tests.
-class TestPluginPlaceholder : public plugins::PluginPlaceholder {
- public:
- TestPluginPlaceholder(RenderFrame* render_frame,
- blink::WebLocalFrame* frame,
- const blink::WebPluginParams& params);
-
- void BindWebFrame(blink::WebFrame* frame) override;
-};
-
-} // namespace content
-
-#endif // CONTENT_SHELL_RENDERER_TEST_RUNNER_TEST_PLUGIN_PLACEHOLDER_H_
diff --git a/gin/wrappable.cc b/gin/wrappable.cc
index 27c58df..0fac4e0 100644
--- a/gin/wrappable.cc
+++ b/gin/wrappable.cc
@@ -36,7 +36,7 @@ void WrappableBase::SecondWeakCallback(
}
v8::Local<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
- WrapperInfo* info) {
+ WrapperInfo* info) {
if (!wrapper_.IsEmpty()) {
return v8::Local<v8::Object>::New(isolate, wrapper_);
}
diff --git a/gin/wrappable.h b/gin/wrappable.h
index cd4d30e..f7d82b0 100644
--- a/gin/wrappable.h
+++ b/gin/wrappable.h
@@ -12,15 +12,6 @@
namespace gin {
-namespace internal {
-
-GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
- v8::Local<v8::Value> val,
- WrapperInfo* info);
-
-} // namespace internal
-
-
// Wrappable is a base class for C++ objects that have corresponding v8 wrapper
// objects. To retain a Wrappable object on the stack, use a gin::Handle.
//
@@ -51,8 +42,20 @@ GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
// wrapper for the object. If clients fail to create a wrapper for a wrappable
// object, the object will leak because we use the weak callback from the
// wrapper as the signal to delete the wrapped object.
-template<typename T>
-class Wrappable;
+//
+// Wrappable<T> explicitly does not support further subclassing of T.
+// Subclasses of Wrappable<T> should be declared final. Because Wrappable<T>
+// caches the object template using &T::kWrapperInfo as the key, all subclasses
+// would share a single object template. This will lead to hard to debug crashes
+// that look like use-after-free errors.
+
+namespace internal {
+
+GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
+ v8::Local<v8::Value> val,
+ WrapperInfo* info);
+
+} // namespace internal
class ObjectTemplateBuilder;
@@ -62,6 +65,7 @@ class GIN_EXPORT WrappableBase {
WrappableBase();
virtual ~WrappableBase();
+ // Overrides of this method should be declared final and not overridden again.
virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
v8::Local<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
@@ -83,8 +87,6 @@ template<typename T>
class Wrappable : public WrappableBase {
public:
// Retrieve (or create) the v8 wrapper object cooresponding to this object.
- // To customize the wrapper created for a subclass, override GetWrapperInfo()
- // instead of overriding this function.
v8::Local<v8::Object> GetWrapper(v8::Isolate* isolate) {
return GetWrapperImpl(isolate, &T::kWrapperInfo);
}
diff --git a/gin/wrappable_unittest.cc b/gin/wrappable_unittest.cc
index 70cb224..07d4fb3 100644
--- a/gin/wrappable_unittest.cc
+++ b/gin/wrappable_unittest.cc
@@ -40,38 +40,16 @@ class MyObject : public BaseClass,
protected:
MyObject() : value_(0) {}
- ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
+ ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) final {
+ return Wrappable<MyObject>::GetObjectTemplateBuilder(isolate)
+ .SetProperty("value", &MyObject::value, &MyObject::set_value);
+ }
~MyObject() override {}
private:
int value_;
};
-class MyObjectSubclass : public MyObject {
- public:
- static gin::Handle<MyObjectSubclass> Create(v8::Isolate* isolate) {
- return CreateHandle(isolate, new MyObjectSubclass());
- }
-
- void SayHello(const std::string& name) {
- result = std::string("Hello, ") + name;
- }
-
- std::string result;
-
- private:
- ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override {
- return MyObject::GetObjectTemplateBuilder(isolate)
- .SetMethod("sayHello", &MyObjectSubclass::SayHello);
- }
-
- MyObjectSubclass() {
- }
-
- ~MyObjectSubclass() override {}
-};
-
class MyCallableObject : public Wrappable<MyCallableObject> {
public:
static WrapperInfo kWrapperInfo;
@@ -83,8 +61,7 @@ class MyCallableObject : public Wrappable<MyCallableObject> {
int result() { return result_; }
private:
- ObjectTemplateBuilder GetObjectTemplateBuilder(
- v8::Isolate* isolate) override {
+ ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) final {
return Wrappable<MyCallableObject>::GetObjectTemplateBuilder(isolate)
.SetCallAsFunctionHandler(&MyCallableObject::Call);
}
@@ -109,20 +86,9 @@ class MyObject2 : public Wrappable<MyObject2> {
static WrapperInfo kWrapperInfo;
};
-class MyObjectBlink : public Wrappable<MyObjectBlink> {
- public:
- static WrapperInfo kWrapperInfo;
-};
-
WrapperInfo MyObject::kWrapperInfo = { kEmbedderNativeGin };
-ObjectTemplateBuilder MyObject::GetObjectTemplateBuilder(v8::Isolate* isolate) {
- return Wrappable<MyObject>::GetObjectTemplateBuilder(isolate)
- .SetProperty("value", &MyObject::value, &MyObject::set_value);
-}
-
WrapperInfo MyCallableObject::kWrapperInfo = { kEmbedderNativeGin };
WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin };
-WrapperInfo MyObjectBlink::kWrapperInfo = { kEmbedderNativeGin };
typedef V8Test WrappableTest;
@@ -155,12 +121,6 @@ TEST_F(WrappableTest, UnwrapFailures) {
EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped));
EXPECT_FALSE(unwrapped);
- // An object that's wrapping a C++ object from Blink.
- thing.Clear();
- thing = ConvertToV8(isolate, new MyObjectBlink());
- EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped));
- EXPECT_FALSE(unwrapped);
-
// An object that's wrapping a C++ object of the wrong type.
thing.Clear();
thing = ConvertToV8(isolate, new MyObject2());
@@ -200,28 +160,6 @@ TEST_F(WrappableTest, GetAndSetProperty) {
EXPECT_EQ(191, obj->value());
}
-TEST_F(WrappableTest, WrappableSubclass) {
- v8::Isolate* isolate = instance_->isolate();
- v8::HandleScope handle_scope(isolate);
-
- gin::Handle<MyObjectSubclass> object(MyObjectSubclass::Create(isolate));
- v8::Local<v8::String> source = StringToV8(isolate,
- "(function(obj) {"
- "obj.sayHello('Lily');"
- "})");
- gin::TryCatch try_catch(isolate);
- v8::Local<v8::Script> script = v8::Script::Compile(source);
- v8::Local<v8::Value> val = script->Run();
- v8::Local<v8::Function> func;
- EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
- v8::Local<v8::Value> argv[] = {
- ConvertToV8(isolate, object.get())
- };
- func->Call(v8::Undefined(isolate), 1, argv);
- EXPECT_FALSE(try_catch.HasCaught());
- EXPECT_EQ("Hello, Lily", object->result);
-}
-
TEST_F(WrappableTest, CallAsFunction) {
v8::Isolate* isolate = instance_->isolate();
v8::HandleScope handle_scope(isolate);