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