diff options
author | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-14 14:38:00 +0000 |
---|---|---|
committer | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-14 14:38:00 +0000 |
commit | a40996367757f82fb2e22035ac65c9d0510e1651 (patch) | |
tree | b4676838b8c03991dc09736ea0046cd61a27442c /chrome | |
parent | d90bcafafdccbef95760c2d9c1b4ce8206d46b7b (diff) | |
download | chromium_src-a40996367757f82fb2e22035ac65c9d0510e1651.zip chromium_src-a40996367757f82fb2e22035ac65c9d0510e1651.tar.gz chromium_src-a40996367757f82fb2e22035ac65c9d0510e1651.tar.bz2 |
Reverting 23420. It caused a reliability regression.
TBR=jam
BUG=none
TEST=reliability
Review URL: http://codereview.chromium.org/165532
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23437 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/metrics/metrics_service.cc | 23 | ||||
-rw-r--r-- | chrome/browser/metrics/metrics_service.h | 7 | ||||
-rw-r--r-- | chrome/browser/plugin_service.cc | 43 | ||||
-rw-r--r-- | chrome/browser/plugin_service.h | 17 | ||||
-rw-r--r-- | chrome/browser/renderer_host/buffered_resource_handler.cc | 146 | ||||
-rw-r--r-- | chrome/browser/renderer_host/buffered_resource_handler.h | 18 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_dispatcher_host.cc | 54 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_dispatcher_host.h | 8 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_handler.h | 6 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.cc | 24 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_message_filter.h | 4 | ||||
-rw-r--r-- | chrome/common/chrome_plugin_lib.cc | 17 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 4 | ||||
-rw-r--r-- | chrome/renderer/renderer_glue.cc | 5 |
14 files changed, 166 insertions, 210 deletions
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc index 71b162c..ae4330d 100644 --- a/chrome/browser/metrics/metrics_service.cc +++ b/chrome/browser/metrics/metrics_service.cc @@ -181,6 +181,7 @@ #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" @@ -196,7 +197,6 @@ #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,15 +288,9 @@ 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(plugins_); + g_browser_process->metrics_service()->OnGetPluginListTaskComplete(); } - - private: - std::vector<WebPluginInfo> plugins_; }; class MetricsService::GetPluginListTask : public Task { @@ -306,10 +300,9 @@ class MetricsService::GetPluginListTask : public Task { virtual void Run() { std::vector<WebPluginInfo> plugins; - NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins); + PluginService::GetInstance()->GetPlugins(false, &plugins); - callback_loop_->PostTask( - FROM_HERE, new GetPluginListTaskComplete(plugins)); + callback_loop_->PostTask(FROM_HERE, new GetPluginListTaskComplete()); } private: @@ -758,10 +751,8 @@ void MetricsService::InitializeMetricsState() { ScheduleNextStateSave(); } -void MetricsService::OnGetPluginListTaskComplete( - const std::vector<WebPluginInfo>& plugins) { +void MetricsService::OnGetPluginListTaskComplete() { DCHECK(state_ == PLUGIN_LIST_REQUESTED); - plugins_ = plugins; if (state_ == PLUGIN_LIST_REQUESTED) state_ = PLUGIN_LIST_ARRIVED; } @@ -1131,9 +1122,11 @@ 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 76fc303..e173915 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/webplugininfo.h" +#include "webkit/glue/webplugin.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(const std::vector<WebPluginInfo>& plugins); + void OnGetPluginListTaskComplete(); // 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,9 +402,6 @@ 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 fe6dfa6..d9d3e65 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -40,10 +40,8 @@ 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::Singleton()->AddExtraPluginPath( - FilePath::FromWStringHack(path)); - } + if (!path.empty()) + NPAPI::PluginList::AddExtraPluginPath(FilePath::FromWStringHack(path)); #if defined(OS_WIN) hkcu_key_.Create( @@ -77,6 +75,12 @@ 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; @@ -84,10 +88,12 @@ 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_; } @@ -126,8 +132,7 @@ PluginProcessHost* PluginService::FindOrStartPluginProcess( return plugin_host; WebPluginInfo info; - if (!NPAPI::PluginList::Singleton()->GetPluginInfoByPath( - plugin_path, &info)) { + if (!GetPluginInfoByPath(plugin_path, &info)) { DCHECK(false); return NULL; } @@ -174,6 +179,7 @@ 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, @@ -186,6 +192,23 @@ 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()) { @@ -194,7 +217,8 @@ void PluginService::OnWaitableEventSignaled(base::WaitableEvent* waitable_event) hklm_key_.StartWatching(); } - NPAPI::PluginList::Singleton()->ResetPluginsLoaded(); + AutoLock lock(lock_); + NPAPI::PluginList::ResetPluginsLoaded(); for (RenderProcessHost::iterator it = RenderProcessHost::begin(); it != RenderProcessHost::end(); ++it) { @@ -218,8 +242,9 @@ 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]; - NPAPI::PluginList::Singleton()->ResetPluginsLoaded(); - NPAPI::PluginList::Singleton()->AddExtraPluginPath(plugin.path); + AutoLock lock(lock_); + NPAPI::PluginList::ResetPluginsLoaded(); + NPAPI::PluginList::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 6933895..8bcbf7c 100644 --- a/chrome/browser/plugin_service.h +++ b/chrome/browser/plugin_service.h @@ -12,6 +12,7 @@ #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" @@ -35,8 +36,8 @@ class URLRequestContext; class ResourceDispatcherHost; class ResourceMessageFilter; -// This must be created on the main thread but it's only called on the IO/file -// thread. +// This can be called on the main thread and IO thread. However it must +// be created on the main thread. class PluginService : public base::WaitableEventWatcher::Delegate, public NotificationObserver { @@ -44,6 +45,9 @@ 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); @@ -78,6 +82,8 @@ 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. @@ -109,6 +115,9 @@ 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); @@ -134,6 +143,10 @@ 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 5f04df8..b1007fe 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.cc +++ b/chrome/browser/renderer_host/buffered_resource_handler.cc @@ -9,15 +9,12 @@ #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 { @@ -52,7 +49,6 @@ BufferedResourceHandler::BufferedResourceHandler(ResourceHandler* handler, bytes_read_(0), sniff_content_(false), should_buffer_(false), - wait_for_plugins_(false), buffering_(false), finished_(false) { } @@ -79,6 +75,7 @@ bool BufferedResourceHandler::OnResponseStarted(int request_id, return true; } + bool BufferedResourceHandler::OnResponseCompleted( int request_id, const URLRequestStatus& status, @@ -86,11 +83,6 @@ 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, @@ -126,13 +118,12 @@ 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. @@ -180,12 +171,6 @@ bool BufferedResourceHandler::DelayResponse() { LOG(INFO) << "To buffer: " << request_->url().spec(); return true; } - - if (ShouldWaitForPlugins()) { - wait_for_plugins_ = true; - return true; - } - return false; } @@ -204,12 +189,6 @@ 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_) { @@ -240,34 +219,17 @@ 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 (should_buffer_) { - if (!finished_ && !DidBufferEnough(bytes_read_)) { + if (!finished_ && should_buffer_) { + if (!DidBufferEnough(bytes_read_)) { buffering_ = true; return true; } - - should_buffer_ = false; - if (ShouldWaitForPlugins()) - wait_for_plugins_ = true; } - buffering_ = false; - - if (wait_for_plugins_) { - // 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); - return true; - } - return false; } @@ -276,10 +238,16 @@ 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 && ShouldDownload(NULL)) { + if (info->allow_download && + host_->ShouldDownload(response_->response_head.mime_type, + content_disposition)) { 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 @@ -325,92 +293,8 @@ bool BufferedResourceHandler::CompleteResponseStarted(int request_id, return real_handler_->OnResponseStarted(request_id, response_); } -bool BufferedResourceHandler::ShouldWaitForPlugins() { - bool need_plugin_list; - if (!ShouldDownload(&need_plugin_list) || !need_plugin_list) - return false; - - // 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; +bool BufferedResourceHandler::DidBufferEnough(int bytes_read) { + const int kRequiredLength = 256; - 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); + return bytes_read >= kRequiredLength; } diff --git a/chrome/browser/renderer_host/buffered_resource_handler.h b/chrome/browser/renderer_host/buffered_resource_handler.h index 1a0af52..3799b99 100644 --- a/chrome/browser/renderer_host/buffered_resource_handler.h +++ b/chrome/browser/renderer_host/buffered_resource_handler.h @@ -30,7 +30,6 @@ 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. @@ -50,22 +49,6 @@ 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_; @@ -76,7 +59,6 @@ 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 9b32684..b71f64f 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -254,6 +254,7 @@ 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_( @@ -465,7 +466,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. - PluginService::GetInstance()->LoadChromePlugins(this); + plugin_service_->LoadChromePlugins(this); // Construct the event handler. scoped_refptr<ResourceHandler> handler; @@ -665,7 +666,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. - PluginService::GetInstance()->LoadChromePlugins(this); + plugin_service_->LoadChromePlugins(this); URLRequest* request = new URLRequest(url, this); request_id_--; @@ -731,7 +732,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. - PluginService::GetInstance()->LoadChromePlugins(this); + plugin_service_->LoadChromePlugins(this); scoped_refptr<ResourceHandler> handler = new SaveFileResourceHandler(process_id, @@ -1257,6 +1258,53 @@ 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 e36e97f..5353562 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.h +++ b/chrome/browser/renderer_host/resource_dispatcher_host.h @@ -108,7 +108,6 @@ 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; @@ -353,6 +352,11 @@ 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); @@ -547,6 +551,8 @@ 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 39a85fa..76851b6 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::RefCountedThreadSafe<ResourceHandler> { +class ResourceHandler : public base::RefCounted<ResourceHandler> { public: virtual ~ResourceHandler() {} @@ -93,10 +93,6 @@ class ResourceHandler : public base::RefCountedThreadSafe<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 f47db7d..d817aa7 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -44,7 +44,6 @@ #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" @@ -283,12 +282,13 @@ 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_DELAY_REPLY(ViewHostMsg_GetPlugins, OnGetPlugins) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetPlugins, OnGetPlugins) IPC_MESSAGE_HANDLER(ViewHostMsg_GetPluginPath, OnGetPluginPath) IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl) IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_ContextMenu, @@ -463,6 +463,10 @@ 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)); @@ -541,20 +545,8 @@ void ResourceMessageFilter::OnLoadFont(LOGFONT font) { #endif void ResourceMessageFilter::OnGetPlugins(bool refresh, - 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)); + std::vector<WebPluginInfo>* plugins) { + plugin_service_->GetPlugins(refresh, plugins); } 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 40209a9..e435bac 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -119,6 +119,7 @@ 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, @@ -140,8 +141,7 @@ 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, IPC::Message* reply_msg); - void OnGetPluginsOnFileThread(bool refresh, IPC::Message* reply_msg); + void OnGetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); 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 86789a4..947527f 100644 --- a/chrome/common/chrome_plugin_lib.cc +++ b/chrome/common/chrome_plugin_lib.cc @@ -42,6 +42,12 @@ 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); @@ -114,7 +120,9 @@ void ChromePluginLib::RegisterPluginsWithNPAPI() { FilePath path; if (!PathService::Get(chrome::FILE_GEARS_PLUGIN, &path)) return; - NPAPI::PluginList::Singleton()->AddExtraPluginPath(path); + // 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); } static void LogPluginLoadTime(const TimeDelta &time) { @@ -245,6 +253,13 @@ 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 80e5510..2ab7397 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -905,6 +905,10 @@ 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 affb348..12ec6fa 100644 --- a/chrome/renderer/renderer_glue.cc +++ b/chrome/renderer/renderer_glue.cc @@ -202,10 +202,11 @@ std::string GetUIResourceProtocol() { return "chrome"; } -void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { +bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { if (!RenderThread::current()->plugin_refresh_allowed()) refresh = false; - RenderThread::current()->Send(new ViewHostMsg_GetPlugins(refresh, plugins)); + return RenderThread::current()->Send(new ViewHostMsg_GetPlugins( + refresh, plugins)); } // static factory function |