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