diff options
20 files changed, 208 insertions, 125 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 69974ad..3761e220 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/callback.h" #include "base/command_line.h" #include "base/file_util.h" #include "base/i18n/number_formatting.h" @@ -47,6 +48,7 @@ #include "chrome/common/url_constants.h" #include "content/browser/browser_thread.h" #include "content/browser/gpu/gpu_process_host.h" +#include "content/browser/plugin_service.h" #include "content/browser/renderer_host/render_process_host.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/sensors/sensors_provider.h" @@ -64,7 +66,6 @@ #include "v8/include/v8.h" #include "webkit/glue/user_agent.h" #include "webkit/glue/webkit_glue.h" -#include "webkit/plugins/npapi/plugin_list.h" #include "webkit/plugins/webplugininfo.h" #if defined(OS_WIN) @@ -1167,8 +1168,8 @@ std::string AboutVersionStrings(DictionaryValue* localized_strings, // Obtain the version of the first enabled Flash plugin. std::vector<webkit::WebPluginInfo> info_array; - webkit::npapi::PluginList::Singleton()->GetPluginInfoArray( - GURL(), "application/x-shockwave-flash", false, NULL, &info_array, NULL); + PluginService::GetInstance()->GetPluginInfoArray( + GURL(), "application/x-shockwave-flash", false, &info_array, NULL); string16 flash_version = l10n_util::GetStringUTF16(IDS_PLUGINS_DISABLED_PLUGIN); PluginPrefs* plugin_prefs = PluginPrefs::GetForProfile(profile); @@ -1241,6 +1242,21 @@ std::string AboutVersionStrings(DictionaryValue* localized_strings, return data; } +// Used as a callback for PluginService::GetPlugins(). +void HandleAboutVersionStrings(AboutSource* source, + int request_id, + const std::vector<webkit::WebPluginInfo>&) { +#if defined(OS_CHROMEOS) + new ChromeOSAboutVersionHandler(source, request_id); +#else + DictionaryValue localized_strings; + localized_strings.SetString("os_version", ""); + source->FinishDataRequest( + AboutVersionStrings(&localized_strings, source->profile()), + request_id); +#endif +} + // AboutMemoryHandler ---------------------------------------------------------- // Helper for AboutMemory to bind results from a ProcessMetrics object @@ -1471,14 +1487,12 @@ void AboutSource::StartDataRequest(const std::string& path, #endif } else if (host == chrome::kChromeUIVersionHost) { if (path == kStringsJsPath) { -#if defined(OS_CHROMEOS) - new ChromeOSAboutVersionHandler(this, request_id); + // The Flash version information is needed on this page, so make sure + // the plugins are loaded. + PluginService::GetInstance()->GetPlugins( + base::Bind(&HandleAboutVersionStrings, + make_scoped_refptr(this), request_id)); return; -#else - DictionaryValue localized_strings; - localized_strings.SetString("os_version", ""); - response = AboutVersionStrings(&localized_strings, profile_); -#endif } else { response = AboutVersionStaticContent(path); } diff --git a/chrome/browser/chromeos/gview_request_interceptor.cc b/chrome/browser/chromeos/gview_request_interceptor.cc index 730767f..70fa026 100644 --- a/chrome/browser/chromeos/gview_request_interceptor.cc +++ b/chrome/browser/chromeos/gview_request_interceptor.cc @@ -8,6 +8,7 @@ #include "base/path_service.h" #include "chrome/browser/chrome_plugin_service_filter.h" #include "chrome/common/chrome_paths.h" +#include "content/browser/plugin_service.h" #include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" #include "googleurl/src/gurl.h" @@ -15,7 +16,7 @@ #include "net/base/load_flags.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_redirect_job.h" -#include "webkit/plugins/npapi/plugin_list.h" +#include "webkit/plugins/webplugininfo.h" namespace chromeos { @@ -65,8 +66,7 @@ bool GViewRequestInterceptor::ShouldUsePdfPlugin( return false; webkit::WebPluginInfo plugin; - if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( - pdf_path, &plugin)) { + if (!PluginService::GetInstance()->GetPluginInfoByPath(pdf_path, &plugin)) { return false; } diff --git a/chrome/browser/chromeos/gview_request_interceptor_unittest.cc b/chrome/browser/chromeos/gview_request_interceptor_unittest.cc index c529f2e..902305b 100644 --- a/chrome/browser/chromeos/gview_request_interceptor_unittest.cc +++ b/chrome/browser/chromeos/gview_request_interceptor_unittest.cc @@ -4,6 +4,7 @@ #include <string> +#include "base/bind.h" #include "base/message_loop.h" #include "chrome/browser/chrome_plugin_service_filter.h" #include "chrome/browser/chromeos/gview_request_interceptor.h" @@ -68,6 +69,10 @@ class GViewRequestProtocolFactory } }; +void QuitMessageLoop(const std::vector<webkit::WebPluginInfo>&) { + MessageLoop::current()->Quit(); +} + class GViewRequestInterceptorTest : public testing::Test { public: GViewRequestInterceptorTest() @@ -110,33 +115,41 @@ class GViewRequestInterceptorTest : public testing::Test { PluginService::GetInstance()->set_filter(NULL); } + // GetPluginInfoByPath() will only use stale information. Because plugin + // refresh is asynchronous, spin a MessageLoop until the callback is run, + // after which, the test will continue. void RegisterPDFPlugin() { webkit::WebPluginInfo info; info.path = pdf_path_; webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(info); - webkit::npapi::PluginList::Singleton()->RefreshPlugins(); + + PluginService::GetInstance()->RefreshPluginList(); + PluginService::GetInstance()->GetPlugins(base::Bind(&QuitMessageLoop)); + MessageLoop::current()->Run(); } void UnregisterPDFPlugin() { webkit::npapi::PluginList::Singleton()->UnregisterInternalPlugin(pdf_path_); - webkit::npapi::PluginList::Singleton()->RefreshPlugins(); + + PluginService::GetInstance()->RefreshPluginList(); + PluginService::GetInstance()->GetPlugins(base::Bind(&QuitMessageLoop)); + MessageLoop::current()->Run(); } void SetPDFPluginLoadedState(bool want_loaded) { webkit::WebPluginInfo info; - bool is_loaded = - webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( - pdf_path_, &info); + bool is_loaded = PluginService::GetInstance()->GetPluginInfoByPath( + pdf_path_, &info); if (is_loaded && !want_loaded) { UnregisterPDFPlugin(); - is_loaded = webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( + is_loaded = PluginService::GetInstance()->GetPluginInfoByPath( pdf_path_, &info); } else if (!is_loaded && want_loaded) { // This "loads" the plug-in even if it's not present on the // system - which is OK since we don't actually use it, just // need it to be "enabled" for the test. RegisterPDFPlugin(); - is_loaded = webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( + is_loaded = PluginService::GetInstance()->GetPluginInfoByPath( pdf_path_, &info); } EXPECT_EQ(want_loaded, is_loaded); diff --git a/chrome/browser/component_updater/npapi_flash_component_installer.cc b/chrome/browser/component_updater/npapi_flash_component_installer.cc index fd0be60..b817b84 100644 --- a/chrome/browser/component_updater/npapi_flash_component_installer.cc +++ b/chrome/browser/component_updater/npapi_flash_component_installer.cc @@ -4,6 +4,7 @@ #include "chrome/browser/component_updater/flash_component_installer.h" +#include "base/bind.h" #include "base/base_paths.h" #include "base/compiler_specific.h" #include "base/file_path.h" @@ -16,7 +17,9 @@ #include "chrome/browser/plugin_prefs.h" #include "chrome/common/chrome_paths.h" #include "content/browser/browser_thread.h" +#include "content/browser/plugin_service.h" #include "webkit/plugins/npapi/plugin_list.h" +#include "webkit/plugins/webplugininfo.h" namespace { @@ -133,9 +136,8 @@ void FinishFlashUpdateRegistration(ComponentUpdateService* cus, // chrome is using and what is its version. This will determine if we register // for component update or not. Read the comments on RegisterNPAPIFlashComponent // for more background. -void StartFlashUpdateRegistration(ComponentUpdateService* cus) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - +void StartFlashUpdateRegistration(ComponentUpdateService* cus, + const std::vector<webkit::WebPluginInfo>&) { FilePath builtin_plugin_path; if (!PathService::Get(chrome::FILE_FLASH_PLUGIN, &builtin_plugin_path)) return; @@ -143,7 +145,7 @@ void StartFlashUpdateRegistration(ComponentUpdateService* cus) { FilePath updated_plugin_path = GetNPAPIFlashBaseDirectory().Append(kFlashPluginFileName); - webkit::npapi::PluginList* plugins = webkit::npapi::PluginList::Singleton(); + PluginService* plugins = PluginService::GetInstance(); webkit::WebPluginInfo plugin_info; if (plugins->GetPluginInfoByPath(updated_plugin_path, &plugin_info)) { @@ -165,7 +167,7 @@ void StartFlashUpdateRegistration(ComponentUpdateService* cus) { } BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - NewRunnableFunction(&FinishFlashUpdateRegistration, cus, plugin_info)); + base::Bind(&FinishFlashUpdateRegistration, cus, plugin_info)); } // Here is the general plan of action: we are going to update flash and we have @@ -205,7 +207,12 @@ void RegisterNPAPIFlashComponent(ComponentUpdateService* cus) { plugins->AddExtraPluginPath(path); plugins->RefreshPlugins(); + // Post the task to the FILE thread because IO may be done once the plugins + // are loaded. BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, - NewRunnableFunction(&StartFlashUpdateRegistration, cus), 8000); + base::Bind(&PluginService::GetPlugins, + base::Unretained(PluginService::GetInstance()), + base::Bind(&StartFlashUpdateRegistration, cus)), + 8000); #endif } diff --git a/chrome/browser/plugin_data_remover.cc b/chrome/browser/plugin_data_remover.cc index 32602b7..9303e42 100644 --- a/chrome/browser/plugin_data_remover.cc +++ b/chrome/browser/plugin_data_remover.cc @@ -17,7 +17,6 @@ #include "content/browser/plugin_service.h" #include "content/common/plugin_messages.h" #include "webkit/plugins/npapi/plugin_group.h" -#include "webkit/plugins/npapi/plugin_list.h" #if defined(OS_POSIX) #include "ipc/ipc_channel_posix.h" @@ -179,11 +178,10 @@ void PluginDataRemover::SignalDone() { // static bool PluginDataRemover::IsSupported(PluginPrefs* plugin_prefs) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); bool allow_wildcard = false; std::vector<webkit::WebPluginInfo> plugins; - webkit::npapi::PluginList::Singleton()->GetPluginInfoArray( - GURL(), kFlashMimeType, allow_wildcard, NULL, &plugins, NULL); + PluginService::GetInstance()->GetPluginInfoArray( + GURL(), kFlashMimeType, allow_wildcard, &plugins, NULL); std::vector<webkit::WebPluginInfo>::iterator plugin = plugins.begin(); if (plugin == plugins.end()) return false; diff --git a/chrome/browser/plugin_data_remover.h b/chrome/browser/plugin_data_remover.h index 2b15e08..f36e0ff 100644 --- a/chrome/browser/plugin_data_remover.h +++ b/chrome/browser/plugin_data_remover.h @@ -34,8 +34,8 @@ class PluginDataRemover : public base::RefCountedThreadSafe<PluginDataRemover>, base::WaitableEvent* StartRemoving(base::Time begin_time); // Returns whether there is a plug-in installed that supports removing - // LSO data. Because this method possibly has to load the plug-in list, it - // should only be called on the FILE thread. + // LSO data. This method will use cached plugin data. Call + // PluginService::GetPlugins() if the latest data is needed. static bool IsSupported(PluginPrefs* plugin_prefs); // Indicates whether we are still in the process of removing plug-in data. diff --git a/chrome/browser/plugin_data_remover_helper.cc b/chrome/browser/plugin_data_remover_helper.cc index 9acaa16..2be7062 100644 --- a/chrome/browser/plugin_data_remover_helper.cc +++ b/chrome/browser/plugin_data_remover_helper.cc @@ -7,6 +7,7 @@ #include <string> #include "base/bind.h" +#include "base/callback.h" #include "base/memory/ref_counted.h" #include "chrome/browser/plugin_data_remover.h" #include "chrome/browser/plugin_prefs.h" @@ -14,9 +15,12 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_notification_types.h" #include "content/browser/browser_thread.h" +#include "content/browser/plugin_service.h" #include "content/common/notification_service.h" // The internal class is refcounted so it can outlive PluginDataRemoverHelper. +// TODO(bauerb): Replace with a WeakPtrFactory now that plugin callbacks run on +// the UI thread. class PluginDataRemoverHelper::Internal : public base::RefCountedThreadSafe<PluginDataRemoverHelper::Internal> { public: @@ -24,12 +28,9 @@ class PluginDataRemoverHelper::Internal : pref_name_(pref_name), profile_(profile) {} void StartUpdate() { - BrowserThread::PostTask( - BrowserThread::FILE, - FROM_HERE, - base::Bind(&PluginDataRemoverHelper::Internal::UpdateOnFileThread, - this, - make_scoped_refptr(PluginPrefs::GetForProfile(profile_)))); + PluginService::GetInstance()->GetPlugins( + base::Bind(&PluginDataRemoverHelper::Internal::GotPlugins, this, + make_scoped_refptr(PluginPrefs::GetForProfile(profile_)))); } void Invalidate() { @@ -41,8 +42,8 @@ class PluginDataRemoverHelper::Internal ~Internal() {} - void UpdateOnFileThread(scoped_refptr<PluginPrefs> plugin_prefs) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + void GotPlugins(scoped_refptr<PluginPrefs> plugin_prefs, + const std::vector<webkit::WebPluginInfo>& plugins) { bool result = PluginDataRemover::IsSupported(plugin_prefs); BrowserThread::PostTask( BrowserThread::UI, diff --git a/chrome/browser/plugin_prefs.cc b/chrome/browser/plugin_prefs.cc index 7ddf824..7e523b5 100644 --- a/chrome/browser/plugin_prefs.cc +++ b/chrome/browser/plugin_prefs.cc @@ -29,6 +29,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "content/browser/browser_thread.h" +#include "content/browser/plugin_service.h" #include "content/common/notification_service.h" #include "webkit/plugins/npapi/plugin_group.h" #include "webkit/plugins/npapi/plugin_list.h" @@ -107,7 +108,7 @@ bool PluginPrefs::EnablePlugin(bool enabled, const FilePath& path) { // Do policy checks first. These don't need to run on the FILE thread. webkit::npapi::PluginList* plugin_list = GetPluginList(); webkit::WebPluginInfo plugin; - if (plugin_list->GetPluginInfoByPath(path, &plugin)) { + if (PluginService::GetInstance()->GetPluginInfoByPath(path, &plugin)) { scoped_ptr<webkit::npapi::PluginGroup> group( plugin_list->GetPluginGroup(plugin)); PolicyStatus plugin_status = PolicyStatusForPlugin(plugin.name); diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 1cafc10..ea188b2 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -135,6 +135,7 @@ #include "content/browser/download/download_manager.h" #include "content/browser/download/save_package.h" #include "content/browser/host_zoom_map.h" +#include "content/browser/plugin_service.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/site_instance.h" #include "content/browser/tab_contents/interstitial_page.h" @@ -188,8 +189,6 @@ #include "chrome/browser/extensions/file_manager_util.h" #endif -#include "webkit/plugins/npapi/plugin_list.h" - using base::TimeDelta; /////////////////////////////////////////////////////////////////////////////// @@ -2509,7 +2508,7 @@ void Browser::CrashedPluginHelper(TabContents* tab, string16 plugin_name = plugin_path.LossyDisplayName(); webkit::WebPluginInfo plugin_info; - if (webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( + if (PluginService::GetInstance()->GetPluginInfoByPath( plugin_path, &plugin_info) && !plugin_info.name.empty()) { plugin_name = plugin_info.name; diff --git a/chrome/browser/ui/cocoa/drag_util.mm b/chrome/browser/ui/cocoa/drag_util.mm index a1e1462..2d3b4b2 100644 --- a/chrome/browser/ui/cocoa/drag_util.mm +++ b/chrome/browser/ui/cocoa/drag_util.mm @@ -84,14 +84,13 @@ static BOOL IsSupportedFileURL(Profile* profile, const GURL& url) { // TODO(bauerb): This possibly uses stale information, but it's guaranteed not // to do disk access. bool allow_wildcard = false; - bool stale = false; webkit::WebPluginInfo plugin; return PluginService::GetInstance()->GetPluginInfo( -1, // process ID MSG_ROUTING_NONE, // routing ID profile->GetResourceContext(), url, GURL(), mime_type, allow_wildcard, - &stale, &plugin, NULL); + NULL, &plugin, NULL); } BOOL IsUnsupportedDropData(Profile* profile, id<NSDraggingInfo> info) { diff --git a/chrome/browser/ui/webui/flash_ui.cc b/chrome/browser/ui/webui/flash_ui.cc index 0dd1076..074a687 100644 --- a/chrome/browser/ui/webui/flash_ui.cc +++ b/chrome/browser/ui/webui/flash_ui.cc @@ -12,6 +12,7 @@ #include "base/bind_helpers.h" #include "base/callback_old.h" #include "base/i18n/time_formatting.h" +#include "base/memory/weak_ptr.h" #include "base/string_number_conversions.h" #include "base/stringprintf.h" #include "base/threading/thread_restrictions.h" @@ -26,6 +27,7 @@ #include "chrome/common/chrome_version_info.h" #include "chrome/common/url_constants.h" #include "content/browser/gpu/gpu_data_manager.h" +#include "content/browser/plugin_service.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/browser/user_metrics.h" #include "grit/browser_resources.h" @@ -34,7 +36,6 @@ #include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" -#include "webkit/plugins/npapi/plugin_list.h" #include "webkit/plugins/webplugininfo.h" #if defined(OS_WIN) @@ -82,6 +83,9 @@ class FlashDOMHandler : public WebUIMessageHandler, // Callback for the GPU information update. void OnGpuInfoUpdate(); + // Callback for the Flash plugin information. + void OnGotPlugins(const std::vector<webkit::WebPluginInfo>& plugins); + private: // Called when we think we might have enough information to return data back // to the page. @@ -104,20 +108,27 @@ class FlashDOMHandler : public WebUIMessageHandler, // Crash list. scoped_refptr<CrashUploadList> upload_list_; + // Factory for the creating refs in callbacks. + base::WeakPtrFactory<FlashDOMHandler> weak_ptr_factory_; + // Whether the list of all crashes is available. bool crash_list_available_; // Whether the page has requested data. bool page_has_requested_data_; // Whether the GPU data has been collected. bool has_gpu_info_; + // Whether the plugin information is ready. + bool has_plugin_info_; DISALLOW_COPY_AND_ASSIGN(FlashDOMHandler); }; FlashDOMHandler::FlashDOMHandler() - : crash_list_available_(false), + : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + crash_list_available_(false), page_has_requested_data_(false), - has_gpu_info_(false) { + has_gpu_info_(false), + has_plugin_info_(false) { // Request Crash data asynchronously. upload_list_ = CrashUploadList::Create(this); upload_list_->LoadCrashListAsynchronously(); @@ -137,6 +148,9 @@ FlashDOMHandler::FlashDOMHandler() if (!gpu_data_manager_->GpuAccessAllowed()) OnGpuInfoUpdate(); + PluginService::GetInstance()->GetPlugins(base::Bind( + &FlashDOMHandler::OnGotPlugins, weak_ptr_factory_.GetWeakPtr())); + // And lastly, we fire off a timer to make sure we never get stuck at the // "Loading..." message. timeout_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimeout), @@ -175,11 +189,18 @@ void FlashDOMHandler::OnGpuInfoUpdate() { MaybeRespondToPage(); } +void FlashDOMHandler::OnGotPlugins( + const std::vector<webkit::WebPluginInfo>& plugins) { + has_plugin_info_ = true; + MaybeRespondToPage(); +} + void FlashDOMHandler::OnTimeout() { // We don't set page_has_requested_data_ because that is guaranteed to appear // and we shouldn't be responding to the page before then. has_gpu_info_ = true; crash_list_available_ = true; + has_plugin_info_ = true; MaybeRespondToPage(); } @@ -187,8 +208,10 @@ void FlashDOMHandler::MaybeRespondToPage() { // We don't reply until everything is ready. The page is showing a 'loading' // message until then. If you add criteria to this list, please update the // function OnTimeout() as well. - if (!page_has_requested_data_ || !crash_list_available_ || !has_gpu_info_) + if (!page_has_requested_data_ || !crash_list_available_ || !has_gpu_info_ || + !has_plugin_info_) { return; + } timeout_.Stop(); @@ -232,8 +255,8 @@ void FlashDOMHandler::MaybeRespondToPage() { // Obtain the version of the Flash plugins. std::vector<webkit::WebPluginInfo> info_array; - webkit::npapi::PluginList::Singleton()->GetPluginInfoArray( - GURL(), "application/x-shockwave-flash", false, NULL, &info_array, NULL); + PluginService::GetInstance()->GetPluginInfoArray( + GURL(), "application/x-shockwave-flash", false, &info_array, NULL); string16 flash_version; if (info_array.empty()) { AddPair(list, ASCIIToUTF16("Flash plugin"), "Disabled"); diff --git a/content/browser/plugin_service.cc b/content/browser/plugin_service.cc index 0ed5d55..97a90c4 100644 --- a/content/browser/plugin_service.cc +++ b/content/browser/plugin_service.cc @@ -67,9 +67,9 @@ static void GetPluginsForGroupsCallback( void WillLoadPluginsCallback() { // TODO(rsesek): Change these to CHECKs. #if defined(OS_WIN) || (defined(OS_POSIX) && !defined(OS_MACOSX)) - LOG_IF(ERROR, !BrowserThread::CurrentlyOn(BrowserThread::FILE)); + CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); #else - LOG(ERROR) << "Plugin loading should happen out-of-process."; + CHECK(false) << "Plugin loading should happen out-of-process."; #endif } @@ -326,8 +326,7 @@ PluginProcessHost* PluginService::FindOrStartNpapiPluginProcess( return plugin_host; webkit::WebPluginInfo info; - if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( - plugin_path, &info)) { + if (!GetPluginInfoByPath(plugin_path, &info)) { return NULL; } @@ -389,14 +388,17 @@ void PluginService::OpenChannelToNpapiPlugin( PluginProcessHost::Client* client) { DCHECK(!ContainsKey(pending_plugin_clients_, client)); pending_plugin_clients_.insert(client); - // The PluginList::GetPluginInfo may need to load the plugins. Don't do it on - // the IO thread. - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, - NewRunnableMethod( - this, &PluginService::GetAllowedPluginForOpenChannelToPlugin, - render_process_id, render_view_id, url, page_url, mime_type, - client, &client->GetResourceContext())); + + // Make sure plugins are loaded if necessary. + content::PluginServiceFilterParams params = { + render_process_id, + render_view_id, + page_url, + &client->GetResourceContext() + }; + GetPlugins( + base::Bind(&PluginService::ForwardGetAllowedPluginForOpenChannelToPlugin, + base::Unretained(this), params, url, mime_type, client)); } void PluginService::OpenChannelToPpapiPlugin( @@ -427,6 +429,17 @@ void PluginService::CancelOpenChannelToNpapiPlugin( pending_plugin_clients_.erase(client); } +void PluginService::ForwardGetAllowedPluginForOpenChannelToPlugin( + const content::PluginServiceFilterParams& params, + const GURL& url, + const std::string& mime_type, + PluginProcessHost::Client* client, + const std::vector<webkit::WebPluginInfo>&) { + GetAllowedPluginForOpenChannelToPlugin(params.render_process_id, + params.render_view_id, url, params.page_url, mime_type, client, + params.resource_context); +} + void PluginService::GetAllowedPluginForOpenChannelToPlugin( int render_process_id, int render_view_id, @@ -435,8 +448,6 @@ void PluginService::GetAllowedPluginForOpenChannelToPlugin( const std::string& mime_type, PluginProcessHost::Client* client, const content::ResourceContext* resource_context) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - DCHECK(resource_context); webkit::WebPluginInfo info; bool allow_wildcard = true; bool found = GetPluginInfo( @@ -448,11 +459,9 @@ void PluginService::GetAllowedPluginForOpenChannelToPlugin( plugin_path = info.path; // Now we jump back to the IO thread to finish opening the channel. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - this, &PluginService::FinishOpenChannelToPlugin, - plugin_path, client)); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&PluginService::FinishOpenChannelToPlugin, + base::Unretained(this), plugin_path, client)); } void PluginService::FinishOpenChannelToPlugin( @@ -493,18 +502,15 @@ bool PluginService::GetPluginInfo(int render_process_id, const GURL& page_url, const std::string& mime_type, bool allow_wildcard, - bool* use_stale, + bool* is_stale, webkit::WebPluginInfo* info, std::string* actual_mime_type) { - webkit::npapi::PluginList* plugin_list = - webkit::npapi::PluginList::Singleton(); - // GetPluginInfoArray may need to load the plugins, so we need to be - // on the FILE thread. - DCHECK(use_stale || BrowserThread::CurrentlyOn(BrowserThread::FILE)); std::vector<webkit::WebPluginInfo> plugins; std::vector<std::string> mime_types; - plugin_list->GetPluginInfoArray( - url, mime_type, allow_wildcard, use_stale, &plugins, &mime_types); + bool stale = GetPluginInfoArray( + url, mime_type, allow_wildcard, &plugins, &mime_types); + if (is_stale) + *is_stale = stale; if (plugins.size() > 1 && plugins.back().path == FilePath(webkit::npapi::kDefaultPluginLibraryName)) { @@ -529,6 +535,24 @@ bool PluginService::GetPluginInfo(int render_process_id, return false; } +bool PluginService::GetPluginInfoByPath(const FilePath& plugin_path, + webkit::WebPluginInfo* info) { + std::vector<webkit::WebPluginInfo> plugins; + webkit::npapi::PluginList::Singleton()->GetPluginsIfNoRefreshNeeded( + &plugins); + + for (std::vector<webkit::WebPluginInfo>::iterator it = plugins.begin(); + it != plugins.end(); + ++it) { + if (it->path == plugin_path) { + *info = *it; + return true; + } + } + + return false; +} + void PluginService::RefreshPluginList() { webkit::npapi::PluginList::Singleton()->RefreshPlugins(); } @@ -640,8 +664,7 @@ PepperPluginInfo* PluginService::GetRegisteredPpapiPluginInfo( // construct it and add it to the list. This same deal needs to be done // in the renderer side in PepperPluginRegistry. webkit::WebPluginInfo webplugin_info; - if (!webkit::npapi::PluginList::Singleton()->GetPluginInfoByPath( - plugin_path, &webplugin_info)) + if (!GetPluginInfoByPath(plugin_path, &webplugin_info)) return NULL; PepperPluginInfo new_pepper_info; if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info)) diff --git a/content/browser/plugin_service.h b/content/browser/plugin_service.h index 1691c0a..b53bb5d 100644 --- a/content/browser/plugin_service.h +++ b/content/browser/plugin_service.h @@ -46,6 +46,7 @@ namespace content { class BrowserContext; class ResourceContext; class PluginServiceFilter; +struct PluginServiceFilterParams; } namespace webkit { @@ -139,10 +140,16 @@ class CONTENT_EXPORT PluginService const GURL& page_url, const std::string& mime_type, bool allow_wildcard, - bool* use_stale, + bool* is_stale, webkit::WebPluginInfo* info, std::string* actual_mime_type); + // Get plugin info by plugin path (including disabled plugins). Returns true + // if the plugin is found and WebPluginInfo has been filled in |info|. This + // will use cached data in the plugin list. + bool GetPluginInfoByPath(const FilePath& plugin_path, + webkit::WebPluginInfo* info); + // Marks the plugin list as dirty and will cause the plugins to be reloaded // on the next access through GetPlugins() or GetPluginGroups(). void RefreshPluginList(); @@ -191,6 +198,14 @@ class CONTENT_EXPORT PluginService void GetPluginsInternal(base::MessageLoopProxy* target_loop, const GetPluginsCallback& callback); + // Binding directly to GetAllowedPluginForOpenChannelToPlugin() isn't possible + // because more arity is needed <http://crbug.com/98542>. This just forwards. + void ForwardGetAllowedPluginForOpenChannelToPlugin( + const content::PluginServiceFilterParams& params, + const GURL& url, + const std::string& mime_type, + PluginProcessHost::Client* client, + const std::vector<webkit::WebPluginInfo>&); // Helper so we can do the plugin lookup on the FILE thread. void GetAllowedPluginForOpenChannelToPlugin( int render_process_id, diff --git a/content/browser/plugin_service_filter.h b/content/browser/plugin_service_filter.h index 790c501..12bd114 100644 --- a/content/browser/plugin_service_filter.h +++ b/content/browser/plugin_service_filter.h @@ -6,7 +6,7 @@ #define CONTENT_BROWSER_PLUGIN_FILTER_H_ #pragma once -class GURL; +#include "googleurl/src/gurl.h" namespace webkit { struct WebPluginInfo; @@ -16,11 +16,21 @@ namespace content { class ResourceContext; +// base::Bind() has limited arity, and the filter-related methods tend to +// surpass that limit. +struct PluginServiceFilterParams { + int render_process_id; + int render_view_id; + GURL page_url; + const ResourceContext* resource_context; +}; + // Callback class to let the client filter the list of all installed plug-ins. // This class is called on the FILE thread. class PluginServiceFilter { public: virtual ~PluginServiceFilter() {} + // Whether to use |plugin|. The client can return false to disallow the // plugin, or return true and optionally change the passed in plugin. virtual bool ShouldUsePlugin( diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 090d97a..553e8a01 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -304,19 +304,6 @@ void RenderMessageFilter::OnChannelError() { } #endif -void RenderMessageFilter::OverrideThreadForMessage(const IPC::Message& message, - BrowserThread::ID* thread) { - switch (message.type()) { - // The PluginService::GetPluginInfo may need to load the plugins. Don't do - // it on the IO thread. - case ViewHostMsg_GetPluginInfo::ID: - *thread = BrowserThread::FILE; - break; - default: - break; - } -} - bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message, bool* message_was_ok) { bool handled = true; diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index 9922ba1..37a259c 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h @@ -83,8 +83,6 @@ class RenderMessageFilter : public BrowserMessageFilter { #endif // BrowserMessageFilter methods: - virtual void OverrideThreadForMessage(const IPC::Message& message, - BrowserThread::ID* thread); virtual bool OnMessageReceived(const IPC::Message& message, bool* message_was_ok); virtual void OnDestruct() const; diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc index 999e477..d77f25a 100644 --- a/content/browser/utility_process_host.cc +++ b/content/browser/utility_process_host.cc @@ -12,6 +12,7 @@ #include "content/common/utility_messages.h" #include "ipc/ipc_switches.h" #include "ui/base/ui_base_switches.h" +#include "webkit/plugins/plugin_switches.h" UtilityProcessHost::Client::Client() { } @@ -103,6 +104,8 @@ bool UtilityProcessHost::StartProcess() { cmd_line->AppendSwitch(switches::kChromeFrame); if (no_sandbox_ || browser_command_line.HasSwitch(switches::kNoSandbox)) cmd_line->AppendSwitch(switches::kNoSandbox); + if (browser_command_line.HasSwitch(switches::kDebugPluginLoading)) + cmd_line->AppendSwitch(switches::kDebugPluginLoading); #if defined(OS_POSIX) // TODO(port): Sandbox this on Linux. Also, zygote this to work with diff --git a/webkit/plugins/npapi/plugin_lib_mac.mm b/webkit/plugins/npapi/plugin_lib_mac.mm index 542b43d..5cb832b 100644 --- a/webkit/plugins/npapi/plugin_lib_mac.mm +++ b/webkit/plugins/npapi/plugin_lib_mac.mm @@ -3,6 +3,7 @@ // found in the LICENSE file. #import <Carbon/Carbon.h> +#import <CoreFoundation/CoreFoundation.h> #include "webkit/plugins/npapi/plugin_lib.h" @@ -176,24 +177,38 @@ bool PluginLib::ReadWebPluginInfo(const FilePath &filename, ScopedCFTypeRef<CFURLRef> bundle_url(CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault, (const UInt8*)filename.value().c_str(), filename.value().length(), true)); - if (!bundle_url) + if (!bundle_url) { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "PluginLib::ReadWebPluginInfo could not create bundle URL"; return false; + } ScopedCFTypeRef<CFBundleRef> bundle(CFBundleCreate(kCFAllocatorDefault, bundle_url.get())); - if (!bundle) + if (!bundle) { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "PluginLib::ReadWebPluginInfo could not create CFBundleRef"; return false; + } // preflight OSType type = 0; CFBundleGetPackageInfo(bundle.get(), &type, NULL); - if (type != FOUR_CHAR_CODE('BRPL')) + if (type != FOUR_CHAR_CODE('BRPL')) { + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "PluginLib::ReadWebPluginInfo bundle is not BRPL, is " << type; return false; + } CFErrorRef error; Boolean would_load = CFBundlePreflightExecutable(bundle.get(), &error); - if (!would_load) + if (!would_load) { + ScopedCFTypeRef<CFStringRef> error_string(CFErrorCopyDescription(error)); + LOG_IF(ERROR, PluginList::DebugPluginLoading()) + << "PluginLib::ReadWebPluginInfo bundle failed preflight: " + << base::SysCFStringRefToUTF8(error_string); return false; + } // get the info diff --git a/webkit/plugins/npapi/plugin_list.cc b/webkit/plugins/npapi/plugin_list.cc index e28aa88..9d62dba 100644 --- a/webkit/plugins/npapi/plugin_list.cc +++ b/webkit/plugins/npapi/plugin_list.cc @@ -597,24 +597,6 @@ void PluginList::GetPluginInfoArray( } } -bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, - webkit::WebPluginInfo* info) { - LoadPlugins(); - base::AutoLock lock(lock_); - for (size_t i = 0; i < plugin_groups_.size(); ++i) { - const std::vector<webkit::WebPluginInfo>& plugins = - plugin_groups_[i]->web_plugin_infos(); - for (size_t i = 0; i < plugins.size(); ++i) { - if (plugins[i].path == plugin_path) { - *info = plugins[i]; - return true; - } - } - } - - return false; -} - void PluginList::GetPluginGroups( bool load_if_necessary, std::vector<PluginGroup>* plugin_groups) { diff --git a/webkit/plugins/npapi/plugin_list.h b/webkit/plugins/npapi/plugin_list.h index bb8fbd1..c8fa5ff 100644 --- a/webkit/plugins/npapi/plugin_list.h +++ b/webkit/plugins/npapi/plugin_list.h @@ -148,11 +148,6 @@ class PluginList { std::vector<webkit::WebPluginInfo>* info, std::vector<std::string>* actual_mime_types); - // Get plugin info by plugin path (including disabled plugins). Returns true - // if the plugin is found and WebPluginInfo has been filled in |info|. - bool GetPluginInfoByPath(const FilePath& plugin_path, - webkit::WebPluginInfo* info); - // Populates the given vector with all available plugin groups. If // |load_if_necessary| is true, this will potentially load the plugin list // synchronously. |