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_BROWSER_PLUGIN_LIST_H_
6 #define CONTENT_BROWSER_PLUGIN_LIST_H_
7 
8 #include <set>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include "base/callback.h"
14 #include "base/files/file_path.h"
15 #include "base/lazy_instance.h"
16 #include "base/macros.h"
17 #include "base/synchronization/lock.h"
18 #include "base/thread_annotations.h"
19 #include "build/build_config.h"
20 #include "content/common/content_export.h"
21 #include "content/public/common/webplugininfo.h"
22 #include "ppapi/buildflags/buildflags.h"
23 
24 #if !BUILDFLAG(ENABLE_PLUGINS)
25 #error "Plugins should be enabled"
26 #endif
27 
28 class GURL;
29 
30 namespace content {
31 
32 // The PluginList is responsible for loading our NPAPI based plugins. It does
33 // so in whatever manner is appropriate for the platform. On Windows, it loads
34 // plugins from a known directory by looking for DLLs which start with "NP",
35 // and checking to see if they are valid NPAPI libraries. On the Mac, it walks
36 // the machine-wide and user plugin directories and loads anything that has
37 // the correct types. On Linux, it walks the plugin directories as well
38 // (e.g. /usr/lib/browser-plugins/).
39 // This object is thread safe.
40 class CONTENT_EXPORT PluginList {
41  public:
42   // Gets the one instance of the PluginList.
43   static PluginList* Singleton();
44 
45   // Cause the plugin list to refresh next time they are accessed, regardless
46   // of whether they are already loaded.
47   void RefreshPlugins();
48 
49   // Register an internal plugin with the specified plugin information.
50   // An internal plugin must be registered before it can
51   // be loaded using PluginList::LoadPlugin().
52   // If |add_at_beginning| is true the plugin will be added earlier in
53   // the list so that it can override the MIME types of older registrations.
54   void RegisterInternalPlugin(const WebPluginInfo& info, bool add_at_beginning);
55 
56   // Removes a specified internal plugin from the list. The search will match
57   // on the path from the version info previously registered.
58   void UnregisterInternalPlugin(const base::FilePath& path);
59 
60   // Gets a list of all the registered internal plugins.
61   void GetInternalPlugins(std::vector<WebPluginInfo>* plugins);
62 
63   // Get all the plugins synchronously, loading them if necessary.
64   void GetPlugins(std::vector<WebPluginInfo>* plugins);
65 
66   // Copies the list of plugins into |plugins| without loading them.
67   // Returns true if the list of plugins is up to date.
68   bool GetPluginsNoRefresh(std::vector<WebPluginInfo>* plugins);
69 
70   // Returns a list in |info| containing plugins that are found for
71   // the given url and mime type (including disabled plugins, for
72   // which |info->enabled| is false).  The mime type which corresponds
73   // to the URL is optionally returned back in |actual_mime_types| (if
74   // it is non-NULL), one for each of the plugin info objects found.
75   // The |allow_wildcard| parameter controls whether this function
76   // returns plugins which support wildcard mime types (* as the mime
77   // type).  The |info| parameter is required to be non-NULL.  The
78   // list is in order of "most desirable" to "least desirable".
79   // This will load the plugin list if necessary.
80   // The return value indicates whether the plugin list was stale.
81   bool GetPluginInfoArray(const GURL& url,
82                           const std::string& mime_type,
83                           bool allow_wildcard,
84                           std::vector<WebPluginInfo>* info,
85                           std::vector<std::string>* actual_mime_types);
86 
87   void set_will_load_plugins_callback(const base::RepeatingClosure& callback);
88 
89  private:
90   enum LoadingState {
91     LOADING_STATE_NEEDS_REFRESH,
92     LOADING_STATE_REFRESHING,
93     LOADING_STATE_UP_TO_DATE,
94   };
95 
96   friend class PluginListTest;
97   friend struct base::LazyInstanceTraitsBase<PluginList>;
98 
99   PluginList();
100   ~PluginList();
101 
102   // The following functions are used to support probing for WebPluginInfo
103   // using a different instance of this class.
104 
105   // Computes a list of all plugins to potentially load from all sources.
106   void GetPluginPathsToLoad(std::vector<base::FilePath>* plugin_paths);
107 
108   // Signals that plugin loading will start. This method should be called before
109   // loading plugins with a different instance of this class. Returns false if
110   // the plugin list is up to date.
111   // When loading has finished, SetPlugins() should be called with the list of
112   // plugins.
113   bool PrepareForPluginLoading();
114 
115   // Clears the internal list of Plugins and copies them from the vector.
116   void SetPlugins(const std::vector<WebPluginInfo>& plugins);
117 
118   // Load all plugins from the default plugins directory.
119   void LoadPlugins();
120 
121   // Removes |plugin_path| from the list of extra plugin paths. Should only be
122   // called while holding |lock_|.
123   void RemoveExtraPluginPathLocked(const base::FilePath& plugin_path)
124       EXCLUSIVE_LOCKS_REQUIRED(lock_);
125 
126   // Creates a WebPluginInfo structure given a plugin's path.  On success
127   // returns true, with the information being put into "info".
128   // Returns false if the library couldn't be found, or if it's not a plugin.
129   bool ReadPluginInfo(const base::FilePath& filename, WebPluginInfo* info);
130 
131   // Load a specific plugin with full path. Return true iff loading the plugin
132   // was successful.
133   bool LoadPluginIntoPluginList(const base::FilePath& filename,
134                                 std::vector<WebPluginInfo>* plugins,
135                                 WebPluginInfo* plugin_info);
136 
137   //
138   // Internals
139   //
140 
141   // States whether we will load the plugin list the next time we try to access
142   // it, whether we are currently in the process of loading it, or whether we
143   // consider it up to date.
144   LoadingState loading_state_ GUARDED_BY(lock_);
145 
146   // Extra plugin paths that we want to search when loading.
147   std::vector<base::FilePath> extra_plugin_paths_ GUARDED_BY(lock_);
148 
149   // Holds information about internal plugins.
150   std::vector<WebPluginInfo> internal_plugins_ GUARDED_BY(lock_);
151 
152   // A list holding all plugins.
153   std::vector<WebPluginInfo> plugins_list_ GUARDED_BY(lock_);
154 
155   // Callback that is invoked whenever the PluginList will reload the plugins.
156   base::RepeatingClosure will_load_plugins_callback_ GUARDED_BY(lock_);
157 
158   // Need synchronization for the above members since this object can be
159   // accessed on multiple threads.
160   base::Lock lock_;
161 
162   DISALLOW_COPY_AND_ASSIGN(PluginList);
163 };
164 
165 }  // namespace content
166 
167 #endif  // CONTENT_BROWSER_PLUGIN_LIST_H_
168