1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_COMMON_PLUGIN_LIST_H_ 6 #define CONTENT_COMMON_PLUGIN_LIST_H_ 7 8 #include <set> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "base/basictypes.h" 14 #include "base/callback.h" 15 #include "base/files/file_path.h" 16 #include "base/lazy_instance.h" 17 #include "base/synchronization/lock.h" 18 #include "content/common/content_export.h" 19 #include "content/public/common/webplugininfo.h" 20 21 #if !defined(ENABLE_PLUGINS) 22 #error "Plugins should be enabled" 23 #endif 24 25 class GURL; 26 27 namespace content { 28 29 // The PluginList is responsible for loading our NPAPI based plugins. It does 30 // so in whatever manner is appropriate for the platform. On Windows, it loads 31 // plugins from a known directory by looking for DLLs which start with "NP", 32 // and checking to see if they are valid NPAPI libraries. On the Mac, it walks 33 // the machine-wide and user plugin directories and loads anything that has 34 // the correct types. On Linux, it walks the plugin directories as well 35 // (e.g. /usr/lib/browser-plugins/). 36 // This object is thread safe. 37 class CONTENT_EXPORT PluginList { 38 public: 39 // Gets the one instance of the PluginList. 40 static PluginList* Singleton(); 41 42 // Returns true if we're in debug-plugin-loading mode. This is controlled 43 // by a command line switch. 44 static bool DebugPluginLoading(); 45 46 // Returns true if the plugin supports |mime_type|. |mime_type| should be all 47 // lower case. 48 static bool SupportsType(const WebPluginInfo& plugin, 49 const std::string& mime_type, 50 bool allow_wildcard); 51 52 // Disables discovery of third_party plugins in standard places next time 53 // plugins are loaded. 54 void DisablePluginsDiscovery(); 55 56 // Cause the plugin list to refresh next time they are accessed, regardless 57 // of whether they are already loaded. 58 void RefreshPlugins(); 59 60 // Add/Remove an extra plugin to load when we actually do the loading. Must 61 // be called before the plugins have been loaded. 62 void AddExtraPluginPath(const base::FilePath& plugin_path); 63 void RemoveExtraPluginPath(const base::FilePath& plugin_path); 64 65 // Same as above, but specifies a directory in which to search for plugins. 66 void AddExtraPluginDir(const base::FilePath& plugin_dir); 67 68 // Get the ordered list of directories from which to load plugins 69 void GetPluginDirectories(std::vector<base::FilePath>* plugin_dirs); 70 71 // Register an internal plugin with the specified plugin information. 72 // An internal plugin must be registered before it can 73 // be loaded using PluginList::LoadPlugin(). 74 // If |add_at_beginning| is true the plugin will be added earlier in 75 // the list so that it can override the MIME types of older registrations. 76 void RegisterInternalPlugin(const WebPluginInfo& info, 77 bool add_at_beginning); 78 79 // Removes a specified internal plugin from the list. The search will match 80 // on the path from the version info previously registered. 81 void UnregisterInternalPlugin(const base::FilePath& path); 82 83 // Gets a list of all the registered internal plugins. 84 void GetInternalPlugins(std::vector<WebPluginInfo>* plugins); 85 86 // Creates a WebPluginInfo structure given a plugin's path. On success 87 // returns true, with the information being put into "info". 88 // Returns false if the library couldn't be found, or if it's not a plugin. 89 bool ReadPluginInfo(const base::FilePath& filename, 90 WebPluginInfo* info); 91 92 // In Windows plugins, the mime types are passed as a specially formatted list 93 // of strings. This function parses those strings into a WebPluginMimeType 94 // vector. 95 // TODO(evan): move this code into plugin_list_win. 96 static bool ParseMimeTypes( 97 const std::string& mime_types, 98 const std::string& file_extensions, 99 const base::string16& mime_type_descriptions, 100 std::vector<WebPluginMimeType>* parsed_mime_types); 101 102 // Get all the plugins synchronously, loading them if necessary. 103 void GetPlugins(std::vector<WebPluginInfo>* plugins, 104 bool include_npapi); 105 106 // Copies the list of plug-ins into |plugins| without loading them. 107 // Returns true if the list of plugins is up-to-date. 108 bool GetPluginsNoRefresh(std::vector<WebPluginInfo>* plugins); 109 110 // Returns a list in |info| containing plugins that are found for 111 // the given url and mime type (including disabled plugins, for 112 // which |info->enabled| is false). The mime type which corresponds 113 // to the URL is optionally returned back in |actual_mime_types| (if 114 // it is non-NULL), one for each of the plugin info objects found. 115 // The |allow_wildcard| parameter controls whether this function 116 // returns plugins which support wildcard mime types (* as the mime 117 // type). The |info| parameter is required to be non-NULL. The 118 // list is in order of "most desirable" to "least desirable". 119 // If |use_stale| is NULL, this will load the plug-in list if necessary. 120 // If it is not NULL, the plug-in list will not be loaded, and |*use_stale| 121 // will be true iff the plug-in list was stale. 122 void GetPluginInfoArray(const GURL& url, 123 const std::string& mime_type, 124 bool allow_wildcard, 125 bool* use_stale, 126 bool include_npapi, 127 std::vector<WebPluginInfo>* info, 128 std::vector<std::string>* actual_mime_types); 129 130 // Load a specific plugin with full path. Return true iff loading the plug-in 131 // was successful. 132 bool LoadPluginIntoPluginList(const base::FilePath& filename, 133 std::vector<WebPluginInfo>* plugins, 134 WebPluginInfo* plugin_info); 135 136 // The following functions are used to support probing for WebPluginInfo 137 // using a different instance of this class. 138 139 // Computes a list of all plugins to potentially load from all sources. 140 void GetPluginPathsToLoad(std::vector<base::FilePath>* plugin_paths, 141 bool include_npapi); 142 143 // Signals that plugin loading will start. This method should be called before 144 // loading plugins with a different instance of this class. Returns false if 145 // the plugin list is up to date. 146 // When loading has finished, SetPlugins() should be called with the list of 147 // plugins. 148 bool PrepareForPluginLoading(); 149 150 // Clears the internal list of Plugins and copies them from the vector. 151 void SetPlugins(const std::vector<WebPluginInfo>& plugins); 152 153 void set_will_load_plugins_callback(const base::Closure& callback); 154 155 virtual ~PluginList(); 156 157 // Creates a WebPluginInfo structure given a plugin's path. On success 158 // returns true, with the information being put into "info". 159 // Returns false if the library couldn't be found, or if it's not a plugin. 160 static bool ReadWebPluginInfo(const base::FilePath& filename, 161 WebPluginInfo* info); 162 163 private: 164 enum LoadingState { 165 LOADING_STATE_NEEDS_REFRESH, 166 LOADING_STATE_REFRESHING, 167 LOADING_STATE_UP_TO_DATE, 168 }; 169 170 friend class PluginListTest; 171 friend struct base::DefaultLazyInstanceTraits<PluginList>; 172 173 PluginList(); 174 175 // Load all plugins from the default plugins directory. 176 void LoadPlugins(bool include_npapi); 177 178 // Walks a directory and produces a list of all the plugins to potentially 179 // load in that directory. 180 void GetPluginsInDir(const base::FilePath& path, 181 std::vector<base::FilePath>* plugins); 182 183 // Returns true if we should load the given plugin, or false otherwise. 184 // |plugins| is the list of plugins we have crawled in the current plugin 185 // loading run. 186 bool ShouldLoadPluginUsingPluginList(const WebPluginInfo& info, 187 std::vector<WebPluginInfo>* plugins); 188 189 // Returns true if the given plugin supports a given file extension. 190 // |extension| should be all lower case. If |mime_type| is not NULL, it will 191 // be set to the MIME type if found. The MIME type which corresponds to the 192 // extension is optionally returned back. 193 bool SupportsExtension(const WebPluginInfo& plugin, 194 const std::string& extension, 195 std::string* actual_mime_type); 196 197 // Removes |plugin_path| from the list of extra plugin paths. Should only be 198 // called while holding |lock_|. 199 void RemoveExtraPluginPathLocked(const base::FilePath& plugin_path); 200 201 // 202 // Command-line switches 203 // 204 205 #if defined(OS_WIN) 206 // Gets plugin paths registered under HKCU\Software\MozillaPlugins and 207 // HKLM\Software\MozillaPlugins. 208 void GetPluginPathsFromRegistry(std::vector<base::FilePath>* plugins); 209 #endif 210 211 // 212 // Internals 213 // 214 215 // States whether we will load the plug-in list the next time we try to access 216 // it, whether we are currently in the process of loading it, or whether we 217 // consider it up-to-date. 218 LoadingState loading_state_; 219 220 // Extra plugin paths that we want to search when loading. 221 std::vector<base::FilePath> extra_plugin_paths_; 222 223 // Extra plugin directories that we want to search when loading. 224 std::vector<base::FilePath> extra_plugin_dirs_; 225 226 // Holds information about internal plugins. 227 std::vector<WebPluginInfo> internal_plugins_; 228 229 // A list holding all plug-ins. 230 std::vector<WebPluginInfo> plugins_list_; 231 232 // Callback that is invoked whenever the PluginList will reload the plugins. 233 base::Closure will_load_plugins_callback_; 234 235 // Need synchronization for the above members since this object can be 236 // accessed on multiple threads. 237 base::Lock lock_; 238 239 // Flag indicating whether third_party plugins will be searched for 240 // in common places. 241 bool plugins_discovery_disabled_; 242 243 DISALLOW_COPY_AND_ASSIGN(PluginList); 244 }; 245 246 } // namespace content 247 248 #endif // CONTENT_COMMON_PLUGIN_LIST_H_ 249