// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This class responds to requests from renderers for the list of plugins, and // also a proxy object for plugin instances. #ifndef CHROME_BROWSER_PLUGIN_SERVICE_H__ #define CHROME_BROWSER_PLUGIN_SERVICE_H__ #include #include "base/basictypes.h" #include "base/hash_tables.h" #include "base/lock.h" #include "chrome/browser/browser_process.h" #include "webkit/glue/webplugin.h" namespace IPC { class Message; } class PluginProcessHost; 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. class PluginService { public: // Returns the PluginService singleton. static PluginService* GetInstance(); // Creates the PluginService object, but doesn't actually build the plugin // list yet. It's generated lazily. // Note: don't call these directly - use GetInstance() above. They are public // so Singleton can access them. PluginService(); ~PluginService(); // Gets the list of available plugins. void GetPlugins(bool refresh, std::vector* 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); // Sets/gets the data directory that Chrome plugins should use to store // persistent data. void SetChromePluginDataDir(const std::wstring& data_dir); const std::wstring& GetChromePluginDataDir(); // Gets the browser's UI locale. const std::wstring& GetUILocale(); // Returns the plugin process host corresponding to the plugin process that // has been started by this service. Returns NULL if no process has been // started. PluginProcessHost* FindPluginProcess(const std::wstring& dll); // Returns the plugin process host corresponding to the plugin process that // has been started by this service. This will start a process to host the // 'dll' if needed. If the process fails to start, the return value is NULL. // Must be called on the IO thread. PluginProcessHost* FindOrStartPluginProcess(const std::wstring& dll, const std::string& clsid); // Opens a channel to a plugin process for the given mime type, starting // a new plugin process if necessary. This must be called on the IO thread // or else a deadlock can occur. void OpenChannelToPlugin(ResourceMessageFilter* renderer_msg_filter, const GURL& url, const std::string& mime_type, const std::string& clsid, const std::wstring& locale, IPC::Message* reply_msg); // A PluginProcessHost object calls this before its process is shut down. void OnPluginProcessIsShuttingDown(PluginProcessHost* host); // A PluginProcessHost object calls this after its process has exited. This // call deletes the host instance. void OnPluginProcessExited(PluginProcessHost* host); bool HavePluginFor(const std::string& mime_type, bool allow_wildcard); std::wstring GetPluginPath(const GURL& url, const std::string& mime_type, const std::string& clsid, std::string* actual_mime_type); // Get plugin info by matching full dll path. bool GetPluginInfoByDllPath(const std::wstring& dll_path, WebPluginInfo* info); // Returns true if the plugin's mime-type supports a given mime-type. // Checks for absolute matching and wildcards. mime-types should be in // lower case. bool SupportsMimeType(const std::wstring& plugin_mime_type, const std::wstring& mime_type); // The UI thread's message loop MessageLoop* main_message_loop() { return main_message_loop_; } ResourceDispatcherHost* resource_dispatcher_host() const { return resource_dispatcher_host_; } // Initiates shutdown on all running PluginProcessHost instances. // Can be invoked on the main thread. void Shutdown(); private: friend class PluginProcessHostIterator; // Removes a host from the plugin_hosts collection void RemoveHost(PluginProcessHost* host); // Shutdown handler which executes in the context of the IO thread. void OnShutdown(); // mapping between plugin dll path and PluginProcessHost typedef base::hash_map PluginMap; PluginMap plugin_hosts_; // The main thread's message loop. MessageLoop* main_message_loop_; // The IO thread's resource dispatcher host. ResourceDispatcherHost* resource_dispatcher_host_; // The data directory that Chrome plugins should use to store persistent data. std::wstring chrome_plugin_data_dir_; // The browser's UI locale. const std::wstring ui_locale_; // 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_; // Handles plugin process shutdown. class ShutdownHandler : public base::RefCountedThreadSafe { public: ShutdownHandler() {} ~ShutdownHandler() {} // Initiates plugin process shutdown. Ensures that the actual shutdown // happens on the io thread. void InitiateShutdown(); private: // Shutdown handler which runs on the io thread. void OnShutdown(); DISALLOW_EVIL_CONSTRUCTORS(ShutdownHandler); }; friend class ShutdownHandler; scoped_refptr plugin_shutdown_handler_; DISALLOW_EVIL_CONSTRUCTORS(PluginService); }; // The PluginProcessHostIterator allows to iterate through all the // PluginProcessHosts. Note that this should be done from the IO thread and that // the iterator should not be kept around as it may be invalidated on // subsequent event processing in the event loop. class PluginProcessHostIterator { public: PluginProcessHostIterator(); PluginProcessHostIterator(const PluginProcessHostIterator& instance); PluginProcessHostIterator& operator=( const PluginProcessHostIterator& instance) { iterator_ = instance.iterator_; } const PluginProcessHost* operator->() const { return iterator_->second; } const PluginProcessHost* operator*() const { return iterator_->second; } const PluginProcessHost* operator++() { // ++preincrement ++iterator_; if (iterator_ == end_) return NULL; else return iterator_->second; } const PluginProcessHost* operator++(int) { // postincrement++ const PluginProcessHost* r; if (iterator_ == end_) r = NULL; else r = iterator_->second; iterator_++; return r; } bool Done() { return (iterator_ == end_); } private: PluginService::PluginMap::const_iterator iterator_; PluginService::PluginMap::const_iterator end_; }; #endif // CHROME_BROWSER_PLUGIN_SERVICE_H__