diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-15 00:04:01 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-15 00:04:01 +0000 |
commit | 35fa6a20ef621d22e6ba79e7306abad870cab4e4 (patch) | |
tree | d976dc15d9ac13976cb444cce875d5cbb790e102 | |
parent | b7a20d363af744159a2bb85bfe3db027d2d4819e (diff) | |
download | chromium_src-35fa6a20ef621d22e6ba79e7306abad870cab4e4.zip chromium_src-35fa6a20ef621d22e6ba79e7306abad870cab4e4.tar.gz chromium_src-35fa6a20ef621d22e6ba79e7306abad870cab4e4.tar.bz2 |
Ensure we don't load plugins on the IO thread.
I had to move the locks from PluginService to PluginList, so that a lock (which can block other threads) isn't held while loading the plugins.
BUG=17938
TEST=added asserts which crash if plugins loaded on IO thread, current UI tests exercise them
Review URL: http://codereview.chromium.org/164305
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23501 0039d316-1c4b-4281-b951-d872f2087c98
26 files changed, 339 insertions, 297 deletions
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc index ae4330d..71b162c 100644 --- a/chrome/browser/metrics/metrics_service.cc +++ b/chrome/browser/metrics/metrics_service.cc @@ -181,7 +181,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/load_notification_details.h" #include "chrome/browser/memory_details.h" -#include "chrome/browser/plugin_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/search_engines/template_url.h" @@ -197,6 +196,7 @@ #include "chrome/common/render_messages.h" #include "googleurl/src/gurl.h" #include "net/base/load_flags.h" +#include "webkit/glue/plugins/plugin_list.h" #if defined(OS_POSIX) // TODO(port): Move these headers above as they are ported. @@ -288,9 +288,15 @@ class MetricsMemoryDetails : public MemoryDetails { }; class MetricsService::GetPluginListTaskComplete : public Task { + public: + explicit GetPluginListTaskComplete( + const std::vector<WebPluginInfo>& plugins) : plugins_(plugins) { } virtual void Run() { - g_browser_process->metrics_service()->OnGetPluginListTaskComplete(); + g_browser_process->metrics_service()->OnGetPluginListTaskComplete(plugins_); } + + private: + std::vector<WebPluginInfo> plugins_; }; class MetricsService::GetPluginListTask : public Task { @@ -300,9 +306,10 @@ class MetricsService::GetPluginListTask : public Task { virtual void Run() { std::vector<WebPluginInfo> plugins; - PluginService::GetInstance()->GetPlugins(false, &plugins); + NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins); - callback_loop_->PostTask(FROM_HERE, new GetPluginListTaskComplete()); + callback_loop_->PostTask( + FROM_HERE, new GetPluginListTaskComplete(plugins)); } private: @@ -751,8 +758,10 @@ void MetricsService::InitializeMetricsState() { ScheduleNextStateSave(); } -void MetricsService::OnGetPluginListTaskComplete() { +void MetricsService::OnGetPluginListTaskComplete( + const std::vector<WebPluginInfo>& plugins) { DCHECK(state_ == PLUGIN_LIST_REQUESTED); + plugins_ = plugins; if (state_ == PLUGIN_LIST_REQUESTED) state_ = PLUGIN_LIST_ARRIVED; } @@ -1122,11 +1131,9 @@ bool MetricsService::TransmissionPermitted() const { void MetricsService::PrepareInitialLog() { DCHECK(state_ == PLUGIN_LIST_ARRIVED); - std::vector<WebPluginInfo> plugins; - PluginService::GetInstance()->GetPlugins(false, &plugins); MetricsLog* log = new MetricsLog(client_id_, session_id_); - log->RecordEnvironment(plugins, profile_dictionary_.get()); + log->RecordEnvironment(plugins_, profile_dictionary_.get()); // Histograms only get written to current_log_, so setup for the write. MetricsLog* save_log = current_log_; diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h index e173915..76fc303 100644 --- a/chrome/browser/metrics/metrics_service.h +++ b/chrome/browser/metrics/metrics_service.h @@ -21,7 +21,7 @@ #include "chrome/browser/metrics/metrics_log.h" #include "chrome/browser/net/url_fetcher.h" #include "chrome/common/notification_registrar.h" -#include "webkit/glue/webplugin.h" +#include "webkit/glue/webplugininfo.h" #include "testing/gtest/include/gtest/gtest_prod.h" class BookmarkModel; @@ -99,7 +99,7 @@ class MetricsService : public NotificationObserver, void RecordBreakpadHasDebugger(bool has_debugger); // Callback to let us knew that the plugin list is warmed up. - void OnGetPluginListTaskComplete(); + void OnGetPluginListTaskComplete(const std::vector<WebPluginInfo>& plugins); // Save any unsent logs into a persistent store in a pref. We always do this // at shutdown, but we can do it as we reduce the list as well. @@ -402,6 +402,9 @@ class MetricsService : public NotificationObserver, // state. State state_; + // The list of plugins which was retrieved on the file thread. + std::vector<WebPluginInfo> plugins_; + // A log that we are currently transmiting, or about to try to transmit. MetricsLog* pending_log_; diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index d9d3e65..fe6dfa6 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -40,8 +40,10 @@ PluginService::PluginService() // Load the one specified on the command line as well. const CommandLine* command_line = CommandLine::ForCurrentProcess(); std::wstring path = command_line->GetSwitchValue(switches::kLoadPlugin); - if (!path.empty()) - NPAPI::PluginList::AddExtraPluginPath(FilePath::FromWStringHack(path)); + if (!path.empty()) { + NPAPI::PluginList::Singleton()->AddExtraPluginPath( + FilePath::FromWStringHack(path)); + } #if defined(OS_WIN) hkcu_key_.Create( @@ -75,12 +77,6 @@ PluginService::~PluginService() { #endif } -void PluginService::GetPlugins(bool refresh, - std::vector<WebPluginInfo>* plugins) { - AutoLock lock(lock_); - NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); -} - void PluginService::LoadChromePlugins( ResourceDispatcherHost* resource_dispatcher_host) { resource_dispatcher_host_ = resource_dispatcher_host; @@ -88,12 +84,10 @@ void PluginService::LoadChromePlugins( } void PluginService::SetChromePluginDataDir(const FilePath& data_dir) { - AutoLock lock(lock_); chrome_plugin_data_dir_ = data_dir; } const FilePath& PluginService::GetChromePluginDataDir() { - AutoLock lock(lock_); return chrome_plugin_data_dir_; } @@ -132,7 +126,8 @@ PluginProcessHost* PluginService::FindOrStartPluginProcess( return plugin_host; WebPluginInfo info; - if (!GetPluginInfoByPath(plugin_path, &info)) { + if (!NPAPI::PluginList::Singleton()->GetPluginInfoByPath( + plugin_path, &info)) { DCHECK(false); return NULL; } @@ -179,7 +174,6 @@ FilePath PluginService::GetPluginPath(const GURL& url, const std::string& mime_type, const std::string& clsid, std::string* actual_mime_type) { - AutoLock lock(lock_); bool allow_wildcard = true; WebPluginInfo info; if (NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, clsid, @@ -192,23 +186,6 @@ FilePath PluginService::GetPluginPath(const GURL& url, return FilePath(); } -bool PluginService::GetPluginInfoByPath(const FilePath& plugin_path, - WebPluginInfo* info) { - AutoLock lock(lock_); - return NPAPI::PluginList::Singleton()->GetPluginInfoByPath(plugin_path, info); -} - -bool PluginService::HavePluginFor(const std::string& mime_type, - bool allow_wildcard) { - AutoLock lock(lock_); - - GURL url; - WebPluginInfo info; - return NPAPI::PluginList::Singleton()->GetPluginInfo(url, mime_type, "", - allow_wildcard, &info, - NULL); -} - void PluginService::OnWaitableEventSignaled(base::WaitableEvent* waitable_event) { #if defined(OS_WIN) if (waitable_event == hkcu_event_.get()) { @@ -217,8 +194,7 @@ void PluginService::OnWaitableEventSignaled(base::WaitableEvent* waitable_event) hklm_key_.StartWatching(); } - AutoLock lock(lock_); - NPAPI::PluginList::ResetPluginsLoaded(); + NPAPI::PluginList::Singleton()->ResetPluginsLoaded(); for (RenderProcessHost::iterator it = RenderProcessHost::begin(); it != RenderProcessHost::end(); ++it) { @@ -242,9 +218,8 @@ void PluginService::Observe(NotificationType type, extension != extensions->end(); ++extension) { for (size_t i = 0; i < (*extension)->plugins().size(); ++i ) { const Extension::PluginInfo& plugin = (*extension)->plugins()[i]; - AutoLock lock(lock_); - NPAPI::PluginList::ResetPluginsLoaded(); - NPAPI::PluginList::AddExtraPluginPath(plugin.path); + NPAPI::PluginList::Singleton()->ResetPluginsLoaded(); + NPAPI::PluginList::Singleton()->AddExtraPluginPath(plugin.path); if (!plugin.is_public) private_plugins_[plugin.path] = (*extension)->url(); } diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h index 8bcbf7c..6933895 100644 --- a/chrome/browser/plugin_service.h +++ b/chrome/browser/plugin_service.h @@ -12,7 +12,6 @@ #include "base/basictypes.h" #include "base/hash_tables.h" -#include "base/lock.h" #include "base/ref_counted.h" #include "base/singleton.h" #include "base/waitable_event_watcher.h" @@ -36,8 +35,8 @@ class URLRequestContext; class ResourceDispatcherHost; class ResourceMessageFilter; -// This can be called on the main thread and IO thread. However it must -// be created on the main thread. +// This must be created on the main thread but it's only called on the IO/file +// thread. class PluginService : public base::WaitableEventWatcher::Delegate, public NotificationObserver { @@ -45,9 +44,6 @@ class PluginService // Returns the PluginService singleton. static PluginService* GetInstance(); - // Gets the list of available plugins. - void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); - // Load all the plugins that should be loaded for the lifetime of the browser // (ie, with the LoadOnStartup flag set). void LoadChromePlugins(ResourceDispatcherHost* resource_dispatcher_host); @@ -82,8 +78,6 @@ class PluginService const std::wstring& locale, IPC::Message* reply_msg); - bool HavePluginFor(const std::string& mime_type, bool allow_wildcard); - // Get the path to the plugin specified. policy_url is the URL of the page // requesting the plugin, so we can verify whether the plugin is allowed // on that page. @@ -115,9 +109,6 @@ class PluginService virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); - // Get plugin info by matching full path. - bool GetPluginInfoByPath(const FilePath& plugin_path, WebPluginInfo* info); - // Returns true if the given plugin is allowed to be used by a page with // the given URL. bool PluginAllowedForURL(const FilePath& plugin_path, const GURL& url); @@ -143,10 +134,6 @@ class PluginService typedef base::hash_map<FilePath, GURL> PrivatePluginMap; PrivatePluginMap private_plugins_; - // Need synchronization whenever we access the plugin_list singelton through - // webkit_glue since this class is called on the main and IO thread. - Lock lock_; - NotificationRegistrar registrar_; #if defined(OS_WIN) diff --git a/chrome/browser/renderer_host/buffered_resource_handler.cc b/chrome/browser/renderer_host/buffered_resource_handler.cc index b1007fe..35b8b85 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.cc +++ b/chrome/browser/renderer_host/buffered_resource_handler.cc @@ -9,12 +9,15 @@ #include "base/string_util.h" #include "net/base/mime_sniffer.h" #include "net/base/net_errors.h" +#include "chrome/browser/chrome_thread.h" #include "chrome/browser/renderer_host/download_throttling_resource_handler.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/common/url_constants.h" #include "net/base/mime_sniffer.h" +#include "net/base/mime_util.h" #include "net/base/io_buffer.h" #include "net/http/http_response_headers.h" +#include "webkit/glue/plugins/plugin_list.h" namespace { @@ -49,6 +52,7 @@ BufferedResourceHandler::BufferedResourceHandler(ResourceHandler* handler, bytes_read_(0), sniff_content_(false), should_buffer_(false), + wait_for_plugins_(false), buffering_(false), finished_(false) { } @@ -75,7 +79,6 @@ bool BufferedResourceHandler::OnResponseStarted(int request_id, return true; } - bool BufferedResourceHandler::OnResponseCompleted( int request_id, const URLRequestStatus& status, @@ -83,6 +86,11 @@ bool BufferedResourceHandler::OnResponseCompleted( return real_handler_->OnResponseCompleted(request_id, status, security_info); } +void BufferedResourceHandler::OnRequestClosed() { + request_ = NULL; + real_handler_->OnRequestClosed(); +} + // We'll let the original event handler provide a buffer, and reuse it for // subsequent reads until we're done buffering. bool BufferedResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, @@ -118,12 +126,13 @@ bool BufferedResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { return true; LOG(INFO) << "Finished buffering " << request_->url().spec(); - sniff_content_ = should_buffer_ = false; *bytes_read = bytes_read_; // Done buffering, send the pending ResponseStarted event. if (!CompleteResponseStarted(request_id, true)) return false; + } else if (wait_for_plugins_) { + return true; } // Release the reference that we acquired at OnWillRead. @@ -171,6 +180,12 @@ bool BufferedResourceHandler::DelayResponse() { LOG(INFO) << "To buffer: " << request_->url().spec(); return true; } + + if (ShouldWaitForPlugins()) { + wait_for_plugins_ = true; + return true; + } + return false; } @@ -189,6 +204,12 @@ bool BufferedResourceHandler::ShouldBuffer(const GURL& url, return mime_type == "text/html"; } +bool BufferedResourceHandler::DidBufferEnough(int bytes_read) { + const int kRequiredLength = 256; + + return bytes_read >= kRequiredLength; +} + bool BufferedResourceHandler::KeepBuffering(int bytes_read) { DCHECK(read_buffer_); if (my_buffer_) { @@ -219,17 +240,29 @@ bool BufferedResourceHandler::KeepBuffering(int bytes_read) { response_->response_head.mime_type.assign(new_type); // We just sniffed the mime type, maybe there is a doctype to process. - if (ShouldBuffer(request_->url(), new_type)) + if (ShouldBuffer(request_->url(), new_type)) { should_buffer_ = true; + } else if (ShouldWaitForPlugins()) { + wait_for_plugins_ = true; + } } - if (!finished_ && should_buffer_) { - if (!DidBufferEnough(bytes_read_)) { + if (should_buffer_) { + if (!finished_ && !DidBufferEnough(bytes_read_)) { buffering_ = true; return true; } + + should_buffer_ = false; + if (ShouldWaitForPlugins()) + wait_for_plugins_ = true; } + buffering_ = false; + + if (wait_for_plugins_) + return true; + return false; } @@ -238,16 +271,10 @@ bool BufferedResourceHandler::CompleteResponseStarted(int request_id, // Check to see if we should forward the data from this request to the // download thread. // TODO(paulg): Only download if the context from the renderer allows it. - std::string content_disposition; - request_->GetResponseHeaderByName("content-disposition", - &content_disposition); - ResourceDispatcherHost::ExtraRequestInfo* info = ResourceDispatcherHost::ExtraInfoForRequest(request_); - if (info->allow_download && - host_->ShouldDownload(response_->response_head.mime_type, - content_disposition)) { + if (info->allow_download && ShouldDownload(NULL)) { if (response_->response_head.headers && // Can be NULL if FTP. response_->response_head.headers->response_code() / 100 != 2) { // The response code indicates that this is an error page, but we don't @@ -293,8 +320,97 @@ bool BufferedResourceHandler::CompleteResponseStarted(int request_id, return real_handler_->OnResponseStarted(request_id, response_); } -bool BufferedResourceHandler::DidBufferEnough(int bytes_read) { - const int kRequiredLength = 256; +bool BufferedResourceHandler::ShouldWaitForPlugins() { + bool need_plugin_list; + if (!ShouldDownload(&need_plugin_list) || !need_plugin_list) + return false; - return bytes_read >= kRequiredLength; + // We don't want to keep buffering as our buffer will fill up. + ResourceDispatcherHost::ExtraRequestInfo* info = + ResourceDispatcherHost::ExtraInfoForRequest(request_); + host_->PauseRequest(info->process_id, info->request_id, true); + + // Schedule plugin loading on the file thread. + ChromeThread::GetMessageLoop(ChromeThread::FILE)->PostTask(FROM_HERE, + NewRunnableMethod(this, &BufferedResourceHandler::LoadPlugins)); + return true; +} + +// This test mirrors the decision that WebKit makes in +// WebFrameLoaderClient::dispatchDecidePolicyForMIMEType. +bool BufferedResourceHandler::ShouldDownload(bool* need_plugin_list) { + if (need_plugin_list) + *need_plugin_list = false; + std::string type = StringToLowerASCII(response_->response_head.mime_type); + std::string disposition; + request_->GetResponseHeaderByName("content-disposition", &disposition); + disposition = StringToLowerASCII(disposition); + + // First, examine content-disposition. + if (!disposition.empty()) { + bool should_download = true; + + // Some broken sites just send ... + // Content-Disposition: ; filename="file" + // ... screen those out here. + if (disposition[0] == ';') + should_download = false; + + if (disposition.compare(0, 6, "inline") == 0) + should_download = false; + + // Some broken sites just send ... + // Content-Disposition: filename="file" + // ... without a disposition token... Screen those out. + if (disposition.compare(0, 8, "filename") == 0) + should_download = false; + + // Also in use is Content-Disposition: name="file" + if (disposition.compare(0, 4, "name") == 0) + should_download = false; + + // We have a content-disposition of "attachment" or unknown. + // RFC 2183, section 2.8 says that an unknown disposition + // value should be treated as "attachment". + if (should_download) + return true; + } + + // MIME type checking. + if (net::IsSupportedMimeType(type)) + return false; + + if (need_plugin_list) { + if (!NPAPI::PluginList::Singleton()->PluginsLoaded()) { + *need_plugin_list = true; + return true; + } + } else { + DCHECK(NPAPI::PluginList::Singleton()->PluginsLoaded()); + } + + // Finally, check the plugin list. + WebPluginInfo info; + bool allow_wildcard = false; + return !NPAPI::PluginList::Singleton()->GetPluginInfo( + GURL(), type, "", allow_wildcard, &info, NULL); +} + +void BufferedResourceHandler::LoadPlugins() { + std::vector<WebPluginInfo> plugins; + NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins); + ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(FROM_HERE, + NewRunnableMethod(this, &BufferedResourceHandler::OnPluginsLoaded)); +} + +void BufferedResourceHandler::OnPluginsLoaded() { + wait_for_plugins_ = false; + if (!request_) + return; + + ResourceDispatcherHost::ExtraRequestInfo* info = + ResourceDispatcherHost::ExtraInfoForRequest(request_); + host_->PauseRequest(info->process_id, info->request_id, false); + if (!CompleteResponseStarted(info->request_id, false)) + host_->CancelRequest(info->process_id, info->request_id, false); } diff --git a/chrome/browser/renderer_host/buffered_resource_handler.h b/chrome/browser/renderer_host/buffered_resource_handler.h index 3799b99..1a0af52 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.h +++ b/chrome/browser/renderer_host/buffered_resource_handler.h @@ -30,6 +30,7 @@ class BufferedResourceHandler : public ResourceHandler { bool OnResponseCompleted(int request_id, const URLRequestStatus& status, const std::string& security_info); + void OnRequestClosed(); private: // Returns true if we should delay OnResponseStarted forwarding. @@ -49,6 +50,22 @@ class BufferedResourceHandler : public ResourceHandler { // this is invoked from |OnResponseCompleted|. bool CompleteResponseStarted(int request_id, bool in_complete); + // Returns true if we have to wait until the plugin list is generated. + bool ShouldWaitForPlugins(); + + // A test to determining whether the request should be forwarded to the + // download thread. If need_plugin_list was passed in and was set to true, + // that means that the check couldn't be fully done because the plugins aren't + // loaded. The function should be called again after the plugin list is + // loaded. + bool ShouldDownload(bool* need_plugin_list); + + // Called on the file thread to load the list of plugins. + void LoadPlugins(); + + // Called on the IO thread once the list of plugins has been loaded. + void OnPluginsLoaded(); + scoped_refptr<ResourceHandler> real_handler_; scoped_refptr<ResourceResponse> response_; ResourceDispatcherHost* host_; @@ -59,6 +76,7 @@ class BufferedResourceHandler : public ResourceHandler { int bytes_read_; bool sniff_content_; bool should_buffer_; + bool wait_for_plugins_; bool buffering_; bool finished_; diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index b71f64f..9b32684 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -254,7 +254,6 @@ ResourceDispatcherHost::ResourceDispatcherHost(MessageLoop* io_loop) safe_browsing_(new SafeBrowsingService), webkit_thread_(new WebKitThread), request_id_(-1), - plugin_service_(PluginService::GetInstance()), ALLOW_THIS_IN_INITIALIZER_LIST(method_runner_(this)), is_shutdown_(false), max_outstanding_requests_cost_per_process_( @@ -466,7 +465,7 @@ void ResourceDispatcherHost::BeginRequest( // requests. Does nothing if they are already loaded. // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by // starting the load earlier in a BG thread. - plugin_service_->LoadChromePlugins(this); + PluginService::GetInstance()->LoadChromePlugins(this); // Construct the event handler. scoped_refptr<ResourceHandler> handler; @@ -666,7 +665,7 @@ void ResourceDispatcherHost::BeginDownload(const GURL& url, // Ensure the Chrome plugins are loaded, as they may intercept network // requests. Does nothing if they are already loaded. - plugin_service_->LoadChromePlugins(this); + PluginService::GetInstance()->LoadChromePlugins(this); URLRequest* request = new URLRequest(url, this); request_id_--; @@ -732,7 +731,7 @@ void ResourceDispatcherHost::BeginSaveFile(const GURL& url, // Ensure the Chrome plugins are loaded, as they may intercept network // requests. Does nothing if they are already loaded. - plugin_service_->LoadChromePlugins(this); + PluginService::GetInstance()->LoadChromePlugins(this); scoped_refptr<ResourceHandler> handler = new SaveFileResourceHandler(process_id, @@ -1258,53 +1257,6 @@ void ResourceDispatcherHost::BeginRequestInternal(URLRequest* request) { } } -// This test mirrors the decision that WebKit makes in -// WebFrameLoaderClient::dispatchDecidePolicyForMIMEType. -// static. -bool ResourceDispatcherHost::ShouldDownload( - const std::string& mime_type, const std::string& content_disposition) { - std::string type = StringToLowerASCII(mime_type); - std::string disposition = StringToLowerASCII(content_disposition); - - // First, examine content-disposition. - if (!disposition.empty()) { - bool should_download = true; - - // Some broken sites just send ... - // Content-Disposition: ; filename="file" - // ... screen those out here. - if (disposition[0] == ';') - should_download = false; - - if (disposition.compare(0, 6, "inline") == 0) - should_download = false; - - // Some broken sites just send ... - // Content-Disposition: filename="file" - // ... without a disposition token... Screen those out. - if (disposition.compare(0, 8, "filename") == 0) - should_download = false; - - // Also in use is Content-Disposition: name="file" - if (disposition.compare(0, 4, "name") == 0) - should_download = false; - - // We have a content-disposition of "attachment" or unknown. - // RFC 2183, section 2.8 says that an unknown disposition - // value should be treated as "attachment". - if (should_download) - return true; - } - - // MIME type checking. - if (net::IsSupportedMimeType(type)) - return false; - - // Finally, check the plugin service. - bool allow_wildcard = false; - return !plugin_service_->HavePluginFor(type, allow_wildcard); -} - bool ResourceDispatcherHost::PauseRequestIfNeeded(ExtraRequestInfo* info) { if (info->pause_count > 0) info->is_paused = true; diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h index 5353562..e36e97f 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.h +++ b/chrome/browser/renderer_host/resource_dispatcher_host.h @@ -108,6 +108,7 @@ class ResourceDispatcherHost : public URLRequest::Delegate { has_started_reading(false), paused_read_bytes(0) { } + virtual ~ExtraRequestInfo() { resource_handler->OnRequestClosed(); } // Top-level ResourceHandler servicing this request. scoped_refptr<ResourceHandler> resource_handler; @@ -352,11 +353,6 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // Retrieves a URLRequest. Must be called from the IO thread. URLRequest* GetURLRequest(GlobalRequestID request_id) const; - // A test to determining whether a given request should be forwarded to the - // download thread. - bool ShouldDownload(const std::string& mime_type, - const std::string& content_disposition); - // Notifies our observers that a request has been cancelled. void NotifyResponseCompleted(URLRequest* request, int process_id); @@ -551,8 +547,6 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // List of objects observing resource dispatching. ObserverList<Observer> observer_list_; - PluginService* plugin_service_; - // For running tasks. ScopedRunnableMethodFactory<ResourceDispatcherHost> method_runner_; diff --git a/chrome/browser/renderer_host/resource_handler.h b/chrome/browser/renderer_host/resource_handler.h index 76851b6..39a85fa 100644 --- a/chrome/browser/renderer_host/resource_handler.h +++ b/chrome/browser/renderer_host/resource_handler.h @@ -52,7 +52,7 @@ struct ResourceResponse : public base::RefCounted<ResourceResponse> { // The resource dispatcher host uses this interface to push load events to the // renderer, allowing for differences in the types of IPC messages generated. // See the implementations of this interface defined below. -class ResourceHandler : public base::RefCounted<ResourceHandler> { +class ResourceHandler : public base::RefCountedThreadSafe<ResourceHandler> { public: virtual ~ResourceHandler() {} @@ -93,6 +93,10 @@ class ResourceHandler : public base::RefCounted<ResourceHandler> { virtual bool OnResponseCompleted(int request_id, const URLRequestStatus& status, const std::string& security_info) = 0; + + // Signals that the request is closed (i.e. finished successfully, cancelled). + // This is a signal that the associated URLRequest isn't valid anymore. + virtual void OnRequestClosed() { } }; #endif // CHROME_BROWSER_RENDERER_HOST_RESOURCE_HANDLER_H_ diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index d817aa7..f47db7d 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -44,6 +44,7 @@ #include "net/http/http_cache.h" #include "net/http/http_transaction_factory.h" #include "net/url_request/url_request_context.h" +#include "webkit/glue/plugins/plugin_list.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/webplugin.h" @@ -282,13 +283,12 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnMsgCreateWidget) IPC_MESSAGE_HANDLER(ViewHostMsg_SetCookie, OnSetCookie) IPC_MESSAGE_HANDLER(ViewHostMsg_GetCookies, OnGetCookies) - IPC_MESSAGE_HANDLER(ViewHostMsg_GetDataDir, OnGetDataDir) IPC_MESSAGE_HANDLER(ViewHostMsg_PluginMessage, OnPluginMessage) IPC_MESSAGE_HANDLER(ViewHostMsg_PluginSyncMessage, OnPluginSyncMessage) #if defined(OS_WIN) // This hack is Windows-specific. IPC_MESSAGE_HANDLER(ViewHostMsg_LoadFont, OnLoadFont) #endif - IPC_MESSAGE_HANDLER(ViewHostMsg_GetPlugins, OnGetPlugins) + IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetPlugins, OnGetPlugins) IPC_MESSAGE_HANDLER(ViewHostMsg_GetPluginPath, OnGetPluginPath) IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl) IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_ContextMenu, @@ -463,10 +463,6 @@ void ResourceMessageFilter::OnGetCookies(const GURL& url, *cookies = context->cookie_store()->GetCookies(url); } -void ResourceMessageFilter::OnGetDataDir(std::wstring* data_dir) { - *data_dir = plugin_service_->GetChromePluginDataDir().ToWStringHack(); -} - void ResourceMessageFilter::OnPluginMessage(const FilePath& plugin_path, const std::vector<uint8>& data) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); @@ -545,8 +541,20 @@ void ResourceMessageFilter::OnLoadFont(LOGFONT font) { #endif void ResourceMessageFilter::OnGetPlugins(bool refresh, - std::vector<WebPluginInfo>* plugins) { - plugin_service_->GetPlugins(refresh, plugins); + IPC::Message* reply_msg) { + ChromeThread::GetMessageLoop(ChromeThread::FILE)->PostTask(FROM_HERE, + NewRunnableMethod(this, &ResourceMessageFilter::OnGetPluginsOnFileThread, + refresh, reply_msg)); +} + +void ResourceMessageFilter::OnGetPluginsOnFileThread(bool refresh, + IPC::Message* reply_msg) { + std::vector<WebPluginInfo> plugins; + NPAPI::PluginList::Singleton()->GetPlugins(refresh, &plugins); + + ViewHostMsg_GetPlugins::WriteReplyParams(reply_msg, plugins); + ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(FROM_HERE, + NewRunnableMethod(this, &ResourceMessageFilter::Send, reply_msg)); } void ResourceMessageFilter::OnGetPluginPath(const GURL& url, diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index e435bac..40209a9 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -119,7 +119,6 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, void OnGetCookies(const GURL& url, const GURL& first_party_for_cookies, std::string* cookies); - void OnGetDataDir(std::wstring* data_dir); void OnPluginMessage(const FilePath& plugin_path, const std::vector<uint8>& message); void OnPluginSyncMessage(const FilePath& plugin_path, @@ -141,7 +140,8 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, // Not handled in the IO thread on Mac. void OnGetScreenInfo(gfx::NativeViewId window, IPC::Message* reply); #endif - void OnGetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); + void OnGetPlugins(bool refresh, IPC::Message* reply_msg); + void OnGetPluginsOnFileThread(bool refresh, IPC::Message* reply_msg); void OnGetPluginPath(const GURL& url, const GURL& policy_url, const std::string& mime_type, diff --git a/chrome/common/chrome_plugin_lib.cc b/chrome/common/chrome_plugin_lib.cc index 947527f..86789a4 100644 --- a/chrome/common/chrome_plugin_lib.cc +++ b/chrome/common/chrome_plugin_lib.cc @@ -42,12 +42,6 @@ static PluginMap* g_loaded_libs; static PlatformThreadId g_plugin_thread_id = 0; static MessageLoop* g_plugin_thread_loop = NULL; -#ifdef GEARS_STATIC_LIB -// defined in gears/base/chrome/module_cr.cc -CPError STDCALL Gears_CP_Initialize(CPID id, const CPBrowserFuncs *bfuncs, - CPPluginFuncs *pfuncs); -#endif - static bool IsSingleProcessMode() { // We don't support ChromePlugins in single-process mode. return CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); @@ -120,9 +114,7 @@ void ChromePluginLib::RegisterPluginsWithNPAPI() { FilePath path; if (!PathService::Get(chrome::FILE_GEARS_PLUGIN, &path)) return; - // Note: we can only access the NPAPI list because the PluginService has done - // the locking for us. We should not touch it anywhere else. - NPAPI::PluginList::AddExtraPluginPath(path); + NPAPI::PluginList::Singleton()->AddExtraPluginPath(path); } static void LogPluginLoadTime(const TimeDelta &time) { @@ -253,13 +245,6 @@ bool ChromePluginLib::Load() { return false; #else DCHECK(module_ == 0); -#ifdef GEARS_STATIC_LIB - FilePath path; - if (filename_.BaseName().value().find(FILE_PATH_LITERAL("gears")) == 0) { - CP_Initialize_ = &Gears_CP_Initialize; - return true; - } -#endif module_ = LoadLibrary(filename_.value().c_str()); if (module_ == 0) diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 2ab7397..80e5510 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -905,10 +905,6 @@ IPC_BEGIN_MESSAGES(ViewHost) FilePath /* filename */, std::string /* actual mime type for url */) - // Retrieve the data directory associated with the renderer's profile. - IPC_SYNC_MESSAGE_CONTROL0_1(ViewHostMsg_GetDataDir, - std::wstring /* data_dir_retval */) - // Allows a chrome plugin loaded in a renderer process to send arbitrary // data to an instance of the same plugin loaded in the browser process. IPC_MESSAGE_CONTROL2(ViewHostMsg_PluginMessage, diff --git a/chrome/renderer/renderer_glue.cc b/chrome/renderer/renderer_glue.cc index 12ec6fa..affb348 100644 --- a/chrome/renderer/renderer_glue.cc +++ b/chrome/renderer/renderer_glue.cc @@ -202,11 +202,10 @@ std::string GetUIResourceProtocol() { return "chrome"; } -bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { +void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { if (!RenderThread::current()->plugin_refresh_allowed()) refresh = false; - return RenderThread::current()->Send(new ViewHostMsg_GetPlugins( - refresh, plugins)); + RenderThread::current()->Send(new ViewHostMsg_GetPlugins(refresh, plugins)); } // static factory function diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc index 9e8a681..11f8675 100644 --- a/webkit/glue/plugins/plugin_lib.cc +++ b/webkit/glue/plugins/plugin_lib.cc @@ -36,7 +36,7 @@ PluginLib* PluginLib::CreatePluginLib(const FilePath& filename) { WebPluginInfo info; const PluginEntryPoints* entry_points = NULL; - if (!PluginList::ReadPluginInfo(filename, &info, &entry_points)) + if (!PluginList::Singleton()->ReadPluginInfo(filename, &info, &entry_points)) return NULL; return new PluginLib(info, entry_points); diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc index f443364..44f7428 100644 --- a/webkit/glue/plugins/plugin_list.cc +++ b/webkit/glue/plugins/plugin_list.cc @@ -25,49 +25,44 @@ base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED); // static PluginList* PluginList::Singleton() { - PluginList* singleton = g_singleton.Pointer(); - if (!singleton->plugins_loaded_) { - singleton->LoadPlugins(false); - DCHECK(singleton->plugins_loaded_); - } - return singleton; + return g_singleton.Pointer(); +} + +bool PluginList::PluginsLoaded() { + AutoLock lock(lock_); + return plugins_loaded_; } -// static void PluginList::ResetPluginsLoaded() { - // We access the singleton directly, and not through Singleton(), since - // we don't want LoadPlugins() to be called. - g_singleton.Pointer()->plugins_loaded_ = false; + AutoLock lock(lock_); + plugins_loaded_ = false; } -// static void PluginList::AddExtraPluginPath(const FilePath& plugin_path) { - DCHECK(!g_singleton.Pointer()->plugins_loaded_); - g_singleton.Pointer()->extra_plugin_paths_.push_back(plugin_path); + AutoLock lock(lock_); + extra_plugin_paths_.push_back(plugin_path); } -// static void PluginList::AddExtraPluginDir(const FilePath& plugin_dir) { - DCHECK(!g_singleton.Pointer()->plugins_loaded_); - g_singleton.Pointer()->extra_plugin_dirs_.push_back(plugin_dir); + AutoLock lock(lock_); + extra_plugin_dirs_.push_back(plugin_dir); } void PluginList::RegisterInternalPlugin(const PluginVersionInfo& info) { - DCHECK(!g_singleton.Pointer()->plugins_loaded_); - g_singleton.Pointer()->internal_plugins_.push_back(info); + AutoLock lock(lock_); + internal_plugins_.push_back(info); } bool PluginList::ReadPluginInfo(const FilePath &filename, WebPluginInfo* info, const PluginEntryPoints** entry_points) { - // We access the singleton directly, and not through Singleton(), since - // we might be in a LoadPlugins call and don't want to call it recursively! - const std::vector<PluginVersionInfo>& internal_plugins = - g_singleton.Pointer()->internal_plugins_; - for (size_t i = 0; i < internal_plugins.size(); ++i) { - if (filename == internal_plugins[i].path) { - *entry_points = &internal_plugins[i].entry_points; - return CreateWebPluginInfo(internal_plugins[i], info); + { + AutoLock lock(lock_); + for (size_t i = 0; i < internal_plugins_.size(); ++i) { + if (filename == internal_plugins_[i].path) { + *entry_points = &internal_plugins_[i].entry_points; + return CreateWebPluginInfo(internal_plugins_[i], info); + } } } @@ -146,46 +141,60 @@ PluginList::PluginList() : plugins_loaded_(false) { } void PluginList::LoadPlugins(bool refresh) { - if (plugins_loaded_ && !refresh) - return; - - plugins_.clear(); - plugins_loaded_ = true; + // Don't want to hold the lock while loading new plugins, so we don't block + // other methods if they're called on other threads. + std::vector<FilePath> extra_plugin_paths; + std::vector<FilePath> extra_plugin_dirs; + { + AutoLock lock(lock_); + if (plugins_loaded_ && !refresh) + return; + + extra_plugin_paths = extra_plugin_paths_; + extra_plugin_dirs = extra_plugin_dirs_; + } base::TimeTicks start_time = base::TimeTicks::Now(); + std::vector<WebPluginInfo> new_plugins; + std::vector<FilePath> directories_to_scan; GetPluginDirectories(&directories_to_scan); - for (size_t i = 0; i < extra_plugin_paths_.size(); ++i) - LoadPlugin(extra_plugin_paths_[i]); + for (size_t i = 0; i < extra_plugin_paths.size(); ++i) + LoadPlugin(extra_plugin_paths[i], &new_plugins); - for (size_t i = 0; i < extra_plugin_dirs_.size(); ++i) { - LoadPluginsFromDir(extra_plugin_dirs_[i]); + for (size_t i = 0; i < extra_plugin_dirs.size(); ++i) { + LoadPluginsFromDir(extra_plugin_dirs[i], &new_plugins); } for (size_t i = 0; i < directories_to_scan.size(); ++i) { - LoadPluginsFromDir(directories_to_scan[i]); + LoadPluginsFromDir(directories_to_scan[i], &new_plugins); } - LoadInternalPlugins(); + LoadInternalPlugins(&new_plugins); if (webkit_glue::IsDefaultPluginEnabled()) - LoadPlugin(FilePath(kDefaultPluginLibraryName)); + LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins); base::TimeTicks end_time = base::TimeTicks::Now(); base::TimeDelta elapsed = end_time - start_time; DLOG(INFO) << "Loaded plugin list in " << elapsed.InMilliseconds() << " ms."; + + AutoLock lock(lock_); + plugins_ = new_plugins; + plugins_loaded_ = true; } -void PluginList::LoadPlugin(const FilePath &path) { +void PluginList::LoadPlugin(const FilePath &path, + std::vector<WebPluginInfo>* plugins) { WebPluginInfo plugin_info; const PluginEntryPoints* entry_points; if (!ReadPluginInfo(path, &plugin_info, &entry_points)) return; - if (!ShouldLoadPlugin(plugin_info)) + if (!ShouldLoadPlugin(plugin_info, plugins)) return; if (path.value() != kDefaultPluginLibraryName @@ -203,7 +212,7 @@ void PluginList::LoadPlugin(const FilePath &path) { } } - plugins_.push_back(plugin_info); + plugins->push_back(plugin_info); } bool PluginList::FindPlugin(const std::string& mime_type, @@ -212,6 +221,8 @@ bool PluginList::FindPlugin(const std::string& mime_type, WebPluginInfo* info) { DCHECK(mime_type == StringToLowerASCII(mime_type)); + LoadPlugins(false); + AutoLock lock(lock_); for (size_t i = 0; i < plugins_.size(); ++i) { if (SupportsType(plugins_[i], mime_type, allow_wildcard)) { #if defined(OS_WIN) @@ -232,6 +243,8 @@ bool PluginList::FindPlugin(const std::string& mime_type, bool PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type, WebPluginInfo* info) { + LoadPlugins(false); + AutoLock lock(lock_); std::string path = url.path(); std::string::size_type last_dot = path.rfind('.'); if (last_dot == std::string::npos) @@ -286,13 +299,11 @@ bool PluginList::SupportsExtension(const WebPluginInfo& info, } -bool PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { - if (refresh) - LoadPlugins(true); +void PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { + LoadPlugins(refresh); + AutoLock lock(lock_); *plugins = plugins_; - - return true; } bool PluginList::GetPluginInfo(const GURL& url, @@ -322,6 +333,8 @@ bool PluginList::GetPluginInfo(const GURL& url, bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, WebPluginInfo* info) { + LoadPlugins(false); + AutoLock lock(lock_); for (size_t i = 0; i < plugins_.size(); ++i) { if (plugins_[i].path == plugin_path) { *info = plugins_[i]; diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h index 9faf899..4c103c0 100644 --- a/webkit/glue/plugins/plugin_list.h +++ b/webkit/glue/plugins/plugin_list.h @@ -11,6 +11,7 @@ #include "base/basictypes.h" #include "base/file_path.h" +#include "base/lock.h" #include "webkit/glue/webplugininfo.h" #include "webkit/glue/plugins/nphostapi.h" @@ -66,39 +67,39 @@ struct PluginVersionInfo { // the machine-wide and user plugin directories and loads anything that has // the correct types. On Linux, it walks the plugin directories as well // (e.g. /usr/lib/browser-plugins/). +// This object is thread safe. class PluginList { public: - // Gets the one instance of the PluginList. Accessing the singleton causes - // the PluginList to look on disk for existing plugins. It does not actually - // load libraries, that will only happen when you initialize the plugin for - // the first time. + // Gets the one instance of the PluginList. static PluginList* Singleton(); + // Returns true iff the plugin list has been loaded already. + bool PluginsLoaded(); + // Clear the plugins_loaded_ bit to force a refresh next time we retrieve // plugins. - static void ResetPluginsLoaded(); + void ResetPluginsLoaded(); - // Add an extra plugin to load when we actually do the loading. This is - // static because we want to be able to add to it without searching the disk - // for plugins. Must be called before the plugins have been loaded. - static void AddExtraPluginPath(const FilePath& plugin_path); + // Add an extra plugin to load when we actually do the loading. Must be + // called before the plugins have been loaded. + void AddExtraPluginPath(const FilePath& plugin_path); // Same as above, but specifies a directory in which to search for plugins. - static void AddExtraPluginDir(const FilePath& plugin_dir); + void AddExtraPluginDir(const FilePath& plugin_dir); // Register an internal plugin with the specified plugin information and // function pointers. An internal plugin must be registered before it can // be loaded using PluginList::LoadPlugin(). - static void RegisterInternalPlugin(const PluginVersionInfo& info); + void RegisterInternalPlugin(const PluginVersionInfo& info); // Creates a WebPluginInfo structure given a plugin's path. On success // returns true, with the information being put into "info". If it's an // internal plugin, "entry_points" is filled in as well with a // internally-owned PluginEntryPoints pointer. // Returns false if the library couldn't be found, or if it's not a plugin. - static bool ReadPluginInfo(const FilePath& filename, - WebPluginInfo* info, - const PluginEntryPoints** entry_points); + bool ReadPluginInfo(const FilePath& filename, + WebPluginInfo* info, + const PluginEntryPoints** entry_points); // Populate a WebPluginInfo from a PluginVersionInfo. static bool CreateWebPluginInfo(const PluginVersionInfo& pvi, @@ -108,7 +109,7 @@ class PluginList { void Shutdown(); // Get all the plugins - bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); + void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); // Returns true if a plugin is found for the given url and mime type. // The mime type which corresponds to the URL is optionally returned @@ -128,7 +129,8 @@ class PluginList { WebPluginInfo* info); // Load a specific plugin with full path. - void LoadPlugin(const FilePath& filename); + void LoadPlugin(const FilePath& filename, + std::vector<WebPluginInfo>* plugins); private: // Constructors are private for singletons @@ -138,13 +140,17 @@ class PluginList { void LoadPlugins(bool refresh); // Load all plugins from a specific directory - void LoadPluginsFromDir(const FilePath& path); + void LoadPluginsFromDir(const FilePath& path, + std::vector<WebPluginInfo>* plugins); // Returns true if we should load the given plugin, or false otherwise. - bool ShouldLoadPlugin(const WebPluginInfo& info); + // plugins is the list of plugins we have crawled in the current plugin + // loading run. + bool ShouldLoadPlugin(const WebPluginInfo& info, + std::vector<WebPluginInfo>* plugins); // Load internal plugins. - void LoadInternalPlugins(); + void LoadInternalPlugins(std::vector<WebPluginInfo>* plugins); // Find a plugin by mime type, and clsid. // If clsid is empty, we will just find the plugin that supports mime type. @@ -216,9 +222,13 @@ class PluginList { // Holds information about internal plugins. std::vector<PluginVersionInfo> internal_plugins_; + // Need synchronization for the above members since this object can be + // accessed on multiple threads. + Lock lock_; + friend struct base::DefaultLazyInstanceTraits<PluginList>; - DISALLOW_EVIL_CONSTRUCTORS(PluginList); + DISALLOW_COPY_AND_ASSIGN(PluginList); }; } // namespace NPAPI diff --git a/webkit/glue/plugins/plugin_list_linux.cc b/webkit/glue/plugins/plugin_list_linux.cc index 0d9b577..2a92bbd 100644 --- a/webkit/glue/plugins/plugin_list_linux.cc +++ b/webkit/glue/plugins/plugin_list_linux.cc @@ -44,7 +44,8 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) { plugin_dirs->push_back(FilePath("/usr/lib/mozilla/plugins")); } -void PluginList::LoadPluginsFromDir(const FilePath& path) { +void PluginList::LoadPluginsFromDir(const FilePath& path, + std::vector<WebPluginInfo>* plugins) { file_util::FileEnumerator enumerator(path, false, // not recursive file_util::FileEnumerator::FILES); @@ -52,11 +53,12 @@ void PluginList::LoadPluginsFromDir(const FilePath& path) { path = enumerator.Next()) { // Skip over Mozilla .xpt files. if (!path.MatchesExtension(FILE_PATH_LITERAL(".xpt"))) - LoadPlugin(path); + LoadPlugin(path, plugins); } } -bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) { +bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, + std::vector<WebPluginInfo>* plugins) { // The equivalent Windows code verifies we haven't loaded a newer version // of the same plugin, and then blacklists some known bad plugins. // The equivalent Mac code verifies that plugins encountered first in the @@ -66,7 +68,7 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) { return true; } -void PluginList::LoadInternalPlugins() { +void PluginList::LoadInternalPlugins(std::vector<WebPluginInfo>* plugins) { // none for now } diff --git a/webkit/glue/plugins/plugin_list_mac.mm b/webkit/glue/plugins/plugin_list_mac.mm index 5e8d250..c3d216f 100644 --- a/webkit/glue/plugins/plugin_list_mac.mm +++ b/webkit/glue/plugins/plugin_list_mac.mm @@ -56,17 +56,19 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) { GetPluginPrivateDirectory(plugin_dirs); } -void PluginList::LoadPluginsFromDir(const FilePath &path) { +void PluginList::LoadPluginsFromDir(const FilePath &path, + std::vector<WebPluginInfo>* plugins) { file_util::FileEnumerator enumerator(path, false, // not recursive file_util::FileEnumerator::DIRECTORIES); for (FilePath path = enumerator.Next(); !path.value().empty(); path = enumerator.Next()) { - LoadPlugin(path); + LoadPlugin(path, plugins); } } -bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) { +bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, + std::vector<WebPluginInfo>* plugins) { // The Gears plugin is Safari-specific, and causes crashes, so don't load it. for (std::vector<WebPluginMimeType>::const_iterator i = info.mime_types.begin(); i != info.mime_types.end(); ++i) { @@ -87,8 +89,8 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) { // Hierarchy check // (we're loading plugins hierarchically from Library folders, so plugins we // encounter earlier must override plugins we encounter later) - for (size_t i = 0; i < plugins_.size(); ++i) { - if (plugins_[i].path.BaseName() == info.path.BaseName()) { + for (size_t i = 0; i < plugins->size(); ++i) { + if ((*plugins)[i].path.BaseName() == info.path.BaseName()) { return false; // We already have a loaded plugin higher in the hierarchy. } } @@ -96,7 +98,7 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) { return true; } -void PluginList::LoadInternalPlugins() { +void PluginList::LoadInternalPlugins(std::vector<WebPluginInfo>* plugins) { // none for now } diff --git a/webkit/glue/plugins/plugin_list_win.cc b/webkit/glue/plugins/plugin_list_win.cc index 94104c8..b92e2f2 100644 --- a/webkit/glue/plugins/plugin_list_win.cc +++ b/webkit/glue/plugins/plugin_list_win.cc @@ -39,13 +39,6 @@ const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion"); const TCHAR kRegistryCurrentJavaVersion[] = _T("CurrentVersion"); const TCHAR kRegistryJavaHome[] = _T("JavaHome"); -#ifdef GEARS_STATIC_LIB -// defined in gears/base/common/module.cc -NPError API_CALL Gears_NP_GetEntryPoints(NPPluginFuncs* funcs); -NPError API_CALL Gears_NP_Initialize(NPNetscapeFuncs* funcs); -NPError API_CALL Gears_NP_Shutdown(void); -#endif - // The application path where we expect to find plugins. void GetAppDirectory(std::set<FilePath>* plugin_dirs) { std::wstring app_path; @@ -226,22 +219,6 @@ void PluginList::PlatformInit() { activex_shim::ActiveX_Shim_NP_Shutdown } }, -#ifdef GEARS_STATIC_LIB - { - FilePath(kGearsPluginLibraryName), - L"Gears", - L"Statically linked Gears", - L"1, 0, 0, 1", - L"application/x-googlegears", - L"", - L"", - { - Gears_NP_GetEntryPoints, - Gears_NP_Initialize, - Gears_NP_Shutdown - } - }, -#endif }; for (int i = 0; i < arraysize(builtin_plugins); ++i) @@ -275,7 +252,8 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) { plugin_dirs->push_back(*i); } -void PluginList::LoadPluginsFromDir(const FilePath &path) { +void PluginList::LoadPluginsFromDir(const FilePath &path, + std::vector<WebPluginInfo>* plugins) { WIN32_FIND_DATA find_file_data; HANDLE find_handle; @@ -290,7 +268,7 @@ void PluginList::LoadPluginsFromDir(const FilePath &path) { do { if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { FilePath filename = path.Append(find_file_data.cFileName); - LoadPlugin(filename); + LoadPlugin(filename, plugins); } } while (FindNextFile(find_handle, &find_file_data) != 0); @@ -317,13 +295,13 @@ bool IsNewerVersion(const std::wstring& a, const std::wstring& b) { return false; } -bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) { - +bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, + std::vector<WebPluginInfo>* plugins) { // Version check - for (size_t i = 0; i < plugins_.size(); ++i) { - if (plugins_[i].path.BaseName() == info.path.BaseName() && - !IsNewerVersion(plugins_[i].version, info.version)) { + for (size_t i = 0; i < plugins->size(); ++i) { + if ((*plugins)[i].path.BaseName() == info.path.BaseName() && + !IsNewerVersion((*plugins)[i].version, info.version)) { return false; // We already have a loaded plugin whose version is newer. } } @@ -360,15 +338,15 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) { if (dont_load_new_wmp_) return false; - for (size_t i = 0; i < plugins_.size(); ++i) { - if (plugins_[i].path.BaseName().value() == kOldWMPPlugin) { - plugins_.erase(plugins_.begin() + i); + for (size_t i = 0; i < plugins->size(); ++i) { + if ((*plugins)[i].path.BaseName().value() == kOldWMPPlugin) { + plugins->erase(plugins->begin() + i); break; } } } else if (filename == kOldWMPPlugin) { - for (size_t i = 0; i < plugins_.size(); ++i) { - if (plugins_[i].path.BaseName().value() == kNewWMPPlugin) + for (size_t i = 0; i < plugins->size(); ++i) { + if ((*plugins)[i].path.BaseName().value() == kNewWMPPlugin) return false; } } @@ -377,16 +355,11 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info) { return true; } -void PluginList::LoadInternalPlugins() { -#ifdef GEARS_STATIC_LIB - LoadPlugin(FilePath(kGearsPluginLibraryName)); -#endif - +void PluginList::LoadInternalPlugins(std::vector<WebPluginInfo>* plugins) { if (!use_internal_activex_shim_) - return; - LoadPlugin(FilePath(kActiveXShimFileName)); - LoadPlugin(FilePath(kActiveXShimFileNameForMediaPlayer)); + LoadPlugin(FilePath(kActiveXShimFileName), plugins); + LoadPlugin(FilePath(kActiveXShimFileNameForMediaPlayer), plugins); } } // namespace NPAPI diff --git a/webkit/glue/webkit_glue.h b/webkit/glue/webkit_glue.h index 998fbce..686e676 100644 --- a/webkit/glue/webkit_glue.h +++ b/webkit/glue/webkit_glue.h @@ -174,7 +174,7 @@ std::string GetUIResourceProtocol(); bool GetExeDirectory(std::wstring* path); // Embedders implement this function to return the list of plugins to Webkit. -bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); +void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); // Returns true if the plugins run in the same process as the renderer, and // false otherwise. diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index afc4f80..d257d53 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -108,8 +108,7 @@ WebURLLoader* WebKitClientImpl::createURLLoader() { void WebKitClientImpl::getPluginList(bool refresh, WebPluginListBuilder* builder) { std::vector<WebPluginInfo> plugins; - if (!GetPlugins(refresh, &plugins)) - return; + GetPlugins(refresh, &plugins); for (size_t i = 0; i < plugins.size(); ++i) { const WebPluginInfo& plugin = plugins[i]; diff --git a/webkit/tools/test_shell/test_shell_gtk.cc b/webkit/tools/test_shell/test_shell_gtk.cc index 2659f7b..cf35788 100644 --- a/webkit/tools/test_shell/test_shell_gtk.cc +++ b/webkit/tools/test_shell/test_shell_gtk.cc @@ -692,8 +692,8 @@ StringPiece GetDataResource(int resource_id) { return TestShell::NetResourceProvider(resource_id); } -bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { - return NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); +void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { + NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); } } // namespace webkit_glue diff --git a/webkit/tools/test_shell/test_shell_mac.mm b/webkit/tools/test_shell/test_shell_mac.mm index dff44c9..e2a9139 100644 --- a/webkit/tools/test_shell/test_shell_mac.mm +++ b/webkit/tools/test_shell/test_shell_mac.mm @@ -700,8 +700,8 @@ StringPiece GetDataResource(int resource_id) { return StringPiece(); } -bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { - return NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); +void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { + NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); } bool DownloadUrl(const std::string& url, NSWindow* caller_window) { diff --git a/webkit/tools/test_shell/test_shell_win.cc b/webkit/tools/test_shell/test_shell_win.cc index 7c682b2..0a9e141 100644 --- a/webkit/tools/test_shell/test_shell_win.cc +++ b/webkit/tools/test_shell/test_shell_win.cc @@ -758,8 +758,8 @@ HCURSOR LoadCursor(int cursor_id) { return NULL; } -bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { - return NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); +void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { + NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins); } bool EnsureFontLoaded(HFONT font) { diff --git a/webkit/tools/test_shell/test_worker/test_worker_main.cc b/webkit/tools/test_shell/test_worker/test_worker_main.cc index e20f772..aefbccb 100644 --- a/webkit/tools/test_shell/test_worker/test_worker_main.cc +++ b/webkit/tools/test_shell/test_worker/test_worker_main.cc @@ -208,8 +208,7 @@ bool SpellCheckWord(const wchar_t* word, int word_len, return true; } -bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { - return false; +void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { } bool IsPluginRunningInRendererProcess() { |