diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 16:34:17 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 16:34:17 +0000 |
commit | 3b48dbc794dd45719eb6047968eb1946d39fe59e (patch) | |
tree | 61cdc08668739748a0a2de3aa5e582b2b7c4a92c | |
parent | 67edf3b5a450c34ded10e67783500376248ba85e (diff) | |
download | chromium_src-3b48dbc794dd45719eb6047968eb1946d39fe59e.zip chromium_src-3b48dbc794dd45719eb6047968eb1946d39fe59e.tar.gz chromium_src-3b48dbc794dd45719eb6047968eb1946d39fe59e.tar.bz2 |
Automatically load newly installed plug-ins if they are missing on a page.
To enable this on Mac OS, we also enable plug-in directory watching there. There shouldn't be any false positives causing unnecessary disk hits anymore.
BUG=62079
TEST=go to http://www.corp.google.com/~bauerb/no_crawl/test/install_plugin.html, install the missing plug-in. It should automatically load.
Review URL: http://codereview.chromium.org/9015025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@116671 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/renderer/chrome_content_renderer_client.cc | 24 | ||||
-rw-r--r-- | chrome/renderer/chrome_content_renderer_client.h | 9 | ||||
-rw-r--r-- | chrome/renderer/plugins/blocked_plugin.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/plugins/missing_plugin.cc | 28 | ||||
-rw-r--r-- | chrome/renderer/plugins/missing_plugin.h | 23 | ||||
-rw-r--r-- | chrome/renderer/plugins/plugin_placeholder.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/plugins/plugin_placeholder.h | 9 | ||||
-rw-r--r-- | content/browser/plugin_service_impl.cc | 13 | ||||
-rw-r--r-- | content/browser/plugin_service_impl.h | 8 | ||||
-rw-r--r-- | content/public/renderer/render_process_observer.h | 5 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.cc | 2 |
11 files changed, 86 insertions, 47 deletions
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index de52237..447dd4f 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -285,8 +285,16 @@ bool ChromeContentRendererClient::OverrideCreatePlugin( content::RenderView* render_view, WebFrame* frame, const WebPluginParams& params, - WebKit::WebPlugin** plugin) { - *plugin = CreatePlugin(render_view, frame, params); + WebPlugin** plugin) { + ChromeViewHostMsg_GetPluginInfo_Status status; + webkit::WebPluginInfo plugin_info; + std::string actual_mime_type; + render_view->Send(new ChromeViewHostMsg_GetPluginInfo( + render_view->GetRoutingId(), GURL(params.url), + frame->top()->document().url(), params.mimeType.utf8(), + &status, &plugin_info, &actual_mime_type)); + *plugin = CreatePlugin(render_view, frame, params, + status, plugin_info, actual_mime_type); return true; } @@ -311,17 +319,13 @@ bool ChromeContentRendererClient::OverrideCreateWebMediaPlayer( WebPlugin* ChromeContentRendererClient::CreatePlugin( content::RenderView* render_view, WebFrame* frame, - const WebPluginParams& original_params) { + const WebPluginParams& original_params, + const ChromeViewHostMsg_GetPluginInfo_Status& status, + const webkit::WebPluginInfo& plugin, + const std::string& actual_mime_type) { CommandLine* cmd = CommandLine::ForCurrentProcess(); GURL url(original_params.url); std::string orig_mime_type = original_params.mimeType.utf8(); - ChromeViewHostMsg_GetPluginInfo_Status status; - webkit::WebPluginInfo plugin; - std::string actual_mime_type; - render_view->Send(new ChromeViewHostMsg_GetPluginInfo( - render_view->GetRoutingId(), url, frame->top()->document().url(), - orig_mime_type, &status, &plugin, &actual_mime_type)); - if (status.value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound) { MissingPluginReporter::GetInstance()->ReportPluginMissing( orig_mime_type, url); diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index 1029e4e..3b98e8f 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h @@ -24,6 +24,8 @@ class SpellCheck; class SpellCheckProvider; class VisitedLinkSlave; +struct ChromeViewHostMsg_GetPluginInfo_Status; + namespace safe_browsing { class PhishingClassifierFilter; } @@ -123,12 +125,15 @@ class ChromeContentRendererClient : public content::ContentRendererClient { SpellCheck* spellcheck() const { return spellcheck_.get(); } - private: WebKit::WebPlugin* CreatePlugin( content::RenderView* render_view, WebKit::WebFrame* frame, - const WebKit::WebPluginParams& params); + const WebKit::WebPluginParams& params, + const ChromeViewHostMsg_GetPluginInfo_Status& status, + const webkit::WebPluginInfo& plugin, + const std::string& actual_mime_type); + private: // Returns true if the frame is navigating to an URL either into or out of an // extension app's extent. bool CrossesExtensionExtents(WebKit::WebFrame* frame, diff --git a/chrome/renderer/plugins/blocked_plugin.cc b/chrome/renderer/plugins/blocked_plugin.cc index 2438de6..3ae7cf2 100644 --- a/chrome/renderer/plugins/blocked_plugin.cc +++ b/chrome/renderer/plugins/blocked_plugin.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -202,7 +202,9 @@ void BlockedPlugin::LoadPlugin() { return; if (!allow_loading_) return; - LoadPluginInternal(plugin_info_); + WebPlugin* plugin = + render_view()->CreatePlugin(frame(), plugin_info_, plugin_params()); + LoadPluginInternal(plugin); } void BlockedPlugin::LoadCallback(const CppArgumentList& args, diff --git a/chrome/renderer/plugins/missing_plugin.cc b/chrome/renderer/plugins/missing_plugin.cc index 842817d..2484944 100644 --- a/chrome/renderer/plugins/missing_plugin.cc +++ b/chrome/renderer/plugins/missing_plugin.cc @@ -13,11 +13,13 @@ #include "chrome/common/jstemplate_builder.h" #include "chrome/common/render_messages.h" #include "chrome/renderer/custom_menu_commands.h" +#include "chrome/renderer/chrome_content_renderer_client.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "grit/generated_resources.h" #include "grit/renderer_resources.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebMenuItemInfo.h" @@ -72,15 +74,16 @@ MissingPlugin::MissingPlugin(RenderView* render_view, const WebPluginParams& params, const std::string& html_data) : PluginPlaceholder(render_view, frame, params, html_data), - mime_type_(params.mimeType), placeholder_routing_id_(RenderThread::Get()->GenerateRoutingID()) { + RenderThread::Get()->AddObserver(this); RenderThread::Get()->AddRoute(placeholder_routing_id_, this); RenderThread::Get()->Send(new ChromeViewHostMsg_FindMissingPlugin( - routing_id(), placeholder_routing_id_, mime_type_.utf8())); + routing_id(), placeholder_routing_id_, params.mimeType.utf8())); } MissingPlugin::~MissingPlugin() { RenderThread::Get()->RemoveRoute(placeholder_routing_id_); + RenderThread::Get()->RemoveObserver(this); } void MissingPlugin::BindWebFrame(WebFrame* frame) { @@ -102,7 +105,7 @@ void MissingPlugin::ShowContextMenu(const WebKit::WebMouseEvent& event) { size_t i = 0; WebMenuItemInfo mime_type_item; - mime_type_item.label = mime_type_; + mime_type_item.label = plugin_params().mimeType; mime_type_item.hasTextDirectionOverride = false; mime_type_item.textDirection = WebKit::WebTextDirectionDefault; custom_items[i++] = mime_type_item; @@ -159,6 +162,25 @@ void MissingPlugin::OnFinishedDownloadingPlugin() { SetMessage(l10n_util::GetStringUTF16(IDS_PLUGIN_INSTALLING)); } +void MissingPlugin::PluginListChanged() { + ChromeViewHostMsg_GetPluginInfo_Status status; + webkit::WebPluginInfo plugin_info; + std::string mime_type(plugin_params().mimeType.utf8()); + std::string actual_mime_type; + render_view()->Send(new ChromeViewHostMsg_GetPluginInfo( + routing_id(), GURL(plugin_params().url), frame()->top()->document().url(), + mime_type, &status, &plugin_info, &actual_mime_type)); + if (status.value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound) + return; + chrome::ChromeContentRendererClient* client = + static_cast<chrome::ChromeContentRendererClient*>( + content::GetContentClient()->renderer()); + WebPlugin* new_plugin = + client->CreatePlugin(render_view(), frame(), plugin_params(), + status, plugin_info, actual_mime_type); + LoadPluginInternal(new_plugin); +} + void MissingPlugin::SetMessage(const string16& message) { message_ = message; if (!plugin()->web_view()->mainFrame()->isLoading()) diff --git a/chrome/renderer/plugins/missing_plugin.h b/chrome/renderer/plugins/missing_plugin.h index bcce19f..93ee8be 100644 --- a/chrome/renderer/plugins/missing_plugin.h +++ b/chrome/renderer/plugins/missing_plugin.h @@ -8,13 +8,15 @@ #include "base/string16.h" #include "chrome/renderer/plugins/plugin_placeholder.h" +#include "content/public/renderer/render_process_observer.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" namespace content { class RenderThread; } -class MissingPlugin : public PluginPlaceholder { +class MissingPlugin : public PluginPlaceholder, + public content::RenderProcessObserver { public: // Creates a new WebViewPlugin with a MissingPlugin as a delegate. static webkit::WebViewPlugin* Create( @@ -22,13 +24,6 @@ class MissingPlugin : public PluginPlaceholder { WebKit::WebFrame* frame, const WebKit::WebPluginParams& params); - private: - MissingPlugin(content::RenderView* render_view, - WebKit::WebFrame* frame, - const WebKit::WebPluginParams& params, - const std::string& html_data); - virtual ~MissingPlugin(); - // WebViewPlugin::Delegate methods: virtual void BindWebFrame(WebKit::WebFrame* frame) OVERRIDE; virtual void ShowContextMenu(const WebKit::WebMouseEvent&) OVERRIDE; @@ -40,6 +35,16 @@ class MissingPlugin : public PluginPlaceholder { // content::RenderViewObserver methods: virtual void ContextMenuAction(unsigned id) OVERRIDE; + // content::RenderProcessObserver methods: + virtual void PluginListChanged() OVERRIDE; + + private: + MissingPlugin(content::RenderView* render_view, + WebKit::WebFrame* frame, + const WebKit::WebPluginParams& params, + const std::string& html_data); + virtual ~MissingPlugin(); + void HideCallback(const CppArgumentList& args, CppVariant* result); void OnFoundMissingPlugin(const string16& plugin_name); @@ -50,8 +55,6 @@ class MissingPlugin : public PluginPlaceholder { void SetMessage(const string16& message); void UpdateMessage(); - WebKit::WebString mime_type_; - // |routing_id()| is the routing ID of our associated RenderView, but we have // a separate routing ID for messages specific to this placeholder. int32 placeholder_routing_id_; diff --git a/chrome/renderer/plugins/plugin_placeholder.cc b/chrome/renderer/plugins/plugin_placeholder.cc index a483485..bb7cc03 100644 --- a/chrome/renderer/plugins/plugin_placeholder.cc +++ b/chrome/renderer/plugins/plugin_placeholder.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -50,11 +50,9 @@ void PluginPlaceholder::BindWebFrame(WebFrame* frame) { BindToJavascript(frame, "plugin"); } -void PluginPlaceholder::LoadPluginInternal(const WebPluginInfo& plugin_info) { +void PluginPlaceholder::LoadPluginInternal(WebPlugin* new_plugin) { CHECK(plugin_); WebPluginContainer* container = plugin_->container(); - WebPlugin* new_plugin = - render_view()->CreatePlugin(frame_, plugin_info, plugin_params_); if (new_plugin && new_plugin->initialize(container)) { plugin_->RestoreTitleText(); container->setPlugin(new_plugin); diff --git a/chrome/renderer/plugins/plugin_placeholder.h b/chrome/renderer/plugins/plugin_placeholder.h index fde0c47..1cf2fbe 100644 --- a/chrome/renderer/plugins/plugin_placeholder.h +++ b/chrome/renderer/plugins/plugin_placeholder.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -32,10 +32,11 @@ class PluginPlaceholder : public content::RenderViewObserver, webkit::WebViewPlugin* plugin() { return plugin_; } WebKit::WebFrame* frame() { return frame_; } + const WebKit::WebPluginParams& plugin_params() { return plugin_params_; } - // Can be called by a subclass to replace this placeholder with an actual - // plugin from |plugin_info|. - void LoadPluginInternal(const webkit::WebPluginInfo& plugin_info); + // Can be called by a subclass to replace this placeholder with a different + // plugin (which could be a placeholder again). + void LoadPluginInternal(WebKit::WebPlugin* new_plugin); // WebViewPlugin::Delegate methods: // Can be called by a subclass to hide this placeholder. diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc index fd1f0bd..8cd4cbc 100644 --- a/content/browser/plugin_service_impl.cc +++ b/content/browser/plugin_service_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -38,7 +38,7 @@ #include "webkit/plugins/npapi/plugin_list.h" #include "webkit/plugins/webplugininfo.h" -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) +#if defined(OS_POSIX) && !defined(OS_OPENBSD) using ::base::files::FilePathWatcher; #endif @@ -89,7 +89,8 @@ static void NotifyPluginsOfActivation() { plugin->OnAppActivation(); } } -#elif defined(OS_POSIX) && !defined(OS_OPENBSD) +#endif +#if defined(OS_POSIX) && !defined(OS_OPENBSD) // Delegate class for monitoring directories. class PluginDirWatcherDelegate : public FilePathWatcher::Delegate { virtual void OnFilePathChanged(const FilePath& path) OVERRIDE { @@ -203,9 +204,7 @@ void PluginServiceImpl::StartWatchingPlugins() { hklm_watcher_.StartWatching(hklm_event_.get(), this); } } -#elif defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) -// The FilePathWatcher produces too many false positives on MacOS (access time -// updates?) which will lead to enforcing updates of the plugins way too often. +#elif defined(OS_POSIX) && !defined(OS_OPENBSD) // On ChromeOS the user can't install plugins anyway and on Windows all // important plugins register themselves in the registry so no need to do that. file_watcher_delegate_ = new PluginDirWatcherDelegate(); @@ -629,7 +628,7 @@ content::PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo( return &ppapi_plugins_[ppapi_plugins_.size() - 1]; } -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) +#if defined(OS_POSIX) && !defined(OS_OPENBSD) // static void PluginServiceImpl::RegisterFilePathWatcher( FilePathWatcher *watcher, diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h index b106edd..4a2c203 100644 --- a/content/browser/plugin_service_impl.h +++ b/content/browser/plugin_service_impl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -31,7 +31,7 @@ #include "base/win/registry.h" #endif -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) +#if defined(OS_POSIX) && !defined(OS_OPENBSD) #include "base/files/file_path_watcher.h" #endif @@ -189,7 +189,7 @@ class CONTENT_EXPORT PluginServiceImpl const FilePath& plugin_path, PluginProcessHost::Client* client); -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) +#if defined(OS_POSIX) && !defined(OS_OPENBSD) // Registers a new FilePathWatcher for a given path. static void RegisterFilePathWatcher( base::files::FilePathWatcher* watcher, @@ -215,7 +215,7 @@ class CONTENT_EXPORT PluginServiceImpl base::WaitableEventWatcher hklm_watcher_; #endif -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) +#if defined(OS_POSIX) && !defined(OS_OPENBSD) ScopedVector<base::files::FilePathWatcher> file_watchers_; scoped_refptr<PluginDirWatcherDelegate> file_watcher_delegate_; #endif diff --git a/content/public/renderer/render_process_observer.h b/content/public/renderer/render_process_observer.h index 74391fd..65137cd 100644 --- a/content/public/renderer/render_process_observer.h +++ b/content/public/renderer/render_process_observer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -31,6 +31,9 @@ class CONTENT_EXPORT RenderProcessObserver { // Called right after the WebKit API is initialized. virtual void WebKitInitialized() {} + // Called when the renderer cache of the plug-in list has changed. + virtual void PluginListChanged() {} + virtual void IdleNotification() {} private: diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 68bce89..c188d1e 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -831,6 +831,8 @@ void RenderThreadImpl::OnPurgePluginListCache(bool reload_pages) { plugin_refresh_allowed_ = false; WebKit::resetPluginCache(reload_pages); plugin_refresh_allowed_ = true; + + FOR_EACH_OBSERVER(RenderProcessObserver, observers_, PluginListChanged()); } void RenderThreadImpl::OnNetworkStateChanged(bool online) { |