blob: 2b2c69f225f2812bdcc9a555ecc05acfe6158a6d [file] [log] [blame]
[email protected]a0421732011-02-23 03:55:401// Copyright (c) 2011 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// This class responds to requests from renderers for the list of plugins, and
6// also a proxy object for plugin instances.
7
8#ifndef CONTENT_BROWSER_PLUGIN_SERVICE_H_
9#define CONTENT_BROWSER_PLUGIN_SERVICE_H_
10#pragma once
11
12#include <string>
[email protected]6b14feb2011-08-16 11:22:5613#include <vector>
[email protected]a0421732011-02-23 03:55:4014
15#include "base/basictypes.h"
[email protected]d33e7cc2011-09-23 01:43:5616#include "base/callback.h"
[email protected]3b63f8f42011-03-28 01:54:1517#include "base/memory/scoped_vector.h"
18#include "base/memory/singleton.h"
[email protected]a0421732011-02-23 03:55:4019#include "base/synchronization/waitable_event_watcher.h"
20#include "build/build_config.h"
[email protected]a0421732011-02-23 03:55:4021#include "content/browser/plugin_process_host.h"
22#include "content/browser/ppapi_plugin_process_host.h"
[email protected]8d128d62011-09-13 22:11:5723#include "content/common/content_export.h"
[email protected]6c2381d2011-10-19 02:52:5324#include "content/public/browser/notification_observer.h"
25#include "content/public/browser/notification_registrar.h"
[email protected]a0421732011-02-23 03:55:4026#include "googleurl/src/gurl.h"
27#include "ipc/ipc_channel_handle.h"
[email protected]a0421732011-02-23 03:55:4028
29#if defined(OS_WIN)
[email protected]3b63f8f42011-03-28 01:54:1530#include "base/memory/scoped_ptr.h"
[email protected]a0421732011-02-23 03:55:4031#include "base/win/registry.h"
32#endif
33
[email protected]e63c4d72011-05-31 22:38:2934#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]493c8002011-04-14 16:56:0135#include "base/files/file_path_watcher.h"
[email protected]a0421732011-02-23 03:55:4036#endif
37
[email protected]a0421732011-02-23 03:55:4038class PluginDirWatcherDelegate;
[email protected]d4af1e72011-10-21 17:45:4339class PluginLoaderPosix;
[email protected]a0421732011-02-23 03:55:4040
[email protected]d33e7cc2011-09-23 01:43:5641namespace base {
42class MessageLoopProxy;
43}
44
[email protected]dfba8762011-09-02 12:49:5445namespace content {
[email protected]45a22e62011-10-12 09:48:0246class BrowserContext;
[email protected]dfba8762011-09-02 12:49:5447class ResourceContext;
[email protected]738a7212011-10-21 17:33:5248struct PepperPluginInfo;
[email protected]dfba8762011-09-02 12:49:5449class PluginServiceFilter;
[email protected]88ca4912011-10-12 14:00:4350struct PluginServiceFilterParams;
[email protected]dfba8762011-09-02 12:49:5451}
52
[email protected]d33e7cc2011-09-23 01:43:5653namespace webkit {
54namespace npapi {
55class PluginGroup;
56class PluginList;
57}
58}
59
[email protected]a0421732011-02-23 03:55:4060// This must be created on the main thread but it's only called on the IO/file
[email protected]d33e7cc2011-09-23 01:43:5661// thread. This is an asynchronous wrapper around the PluginList interface for
62// querying plugin information. This must be used instead of that to avoid
63// doing expensive disk operations on the IO/UI threads.
[email protected]8d128d62011-09-13 22:11:5764class CONTENT_EXPORT PluginService
[email protected]a0421732011-02-23 03:55:4065 : public base::WaitableEventWatcher::Delegate,
[email protected]6c2381d2011-10-19 02:52:5366 public content::NotificationObserver {
[email protected]a0421732011-02-23 03:55:4067 public:
68 struct OverriddenPlugin {
69 int render_process_id;
70 int render_view_id;
[email protected]6b14feb2011-08-16 11:22:5671 GURL url; // If empty, the override applies to all urls in render_view.
[email protected]91d9f3d2011-08-14 05:24:4472 webkit::WebPluginInfo plugin;
[email protected]a0421732011-02-23 03:55:4073 };
74
[email protected]d33e7cc2011-09-23 01:43:5675 typedef base::Callback<void(const std::vector<webkit::WebPluginInfo>&)>
76 GetPluginsCallback;
77 typedef base::Callback<void(const std::vector<webkit::npapi::PluginGroup>&)>
78 GetPluginGroupsCallback;
79
[email protected]a0421732011-02-23 03:55:4080 // Returns the PluginService singleton.
81 static PluginService* GetInstance();
82
[email protected]dfba8762011-09-02 12:49:5483 // Starts watching for changes in the list of installed plug-ins.
84 void StartWatchingPlugins();
85
[email protected]a0421732011-02-23 03:55:4086 // Gets the browser's UI locale.
87 const std::string& GetUILocale();
88
89 // Returns the plugin process host corresponding to the plugin process that
90 // has been started by this service. Returns NULL if no process has been
91 // started.
92 PluginProcessHost* FindNpapiPluginProcess(const FilePath& plugin_path);
93 PpapiPluginProcessHost* FindPpapiPluginProcess(const FilePath& plugin_path);
[email protected]a50432d2011-09-30 16:32:1494 PpapiPluginProcessHost* FindPpapiBrokerProcess(const FilePath& broker_path);
[email protected]a0421732011-02-23 03:55:4095
96 // Returns the plugin process host corresponding to the plugin process that
97 // has been started by this service. This will start a process to host the
98 // 'plugin_path' if needed. If the process fails to start, the return value
99 // is NULL. Must be called on the IO thread.
100 PluginProcessHost* FindOrStartNpapiPluginProcess(
101 const FilePath& plugin_path);
102 PpapiPluginProcessHost* FindOrStartPpapiPluginProcess(
[email protected]d259a8e2011-05-18 22:31:09103 const FilePath& plugin_path,
[email protected]a50432d2011-09-30 16:32:14104 PpapiPluginProcessHost::PluginClient* client);
105 PpapiPluginProcessHost* FindOrStartPpapiBrokerProcess(
[email protected]eb415bf0e2011-04-14 02:45:42106 const FilePath& plugin_path);
[email protected]a0421732011-02-23 03:55:40107
108 // Opens a channel to a plugin process for the given mime type, starting
109 // a new plugin process if necessary. This must be called on the IO thread
110 // or else a deadlock can occur.
111 void OpenChannelToNpapiPlugin(int render_process_id,
112 int render_view_id,
113 const GURL& url,
[email protected]dfba8762011-09-02 12:49:54114 const GURL& page_url,
[email protected]a0421732011-02-23 03:55:40115 const std::string& mime_type,
116 PluginProcessHost::Client* client);
117 void OpenChannelToPpapiPlugin(const FilePath& path,
[email protected]a50432d2011-09-30 16:32:14118 PpapiPluginProcessHost::PluginClient* client);
[email protected]eb415bf0e2011-04-14 02:45:42119 void OpenChannelToPpapiBroker(const FilePath& path,
[email protected]a50432d2011-09-30 16:32:14120 PpapiPluginProcessHost::BrokerClient* client);
[email protected]a0421732011-02-23 03:55:40121
[email protected]4befe7592011-09-14 22:49:09122 // Cancels opening a channel to a NPAPI plugin.
123 void CancelOpenChannelToNpapiPlugin(PluginProcessHost::Client* client);
124
[email protected]11e1c182011-05-17 20:26:27125 // Gets the plugin in the list of plugins that matches the given url and mime
[email protected]51b63f62011-10-05 18:55:42126 // type. Returns true if the data is frome a stale plugin list, false if it
127 // is up to date. This can be called from any thread.
128 bool GetPluginInfoArray(const GURL& url,
129 const std::string& mime_type,
130 bool allow_wildcard,
131 std::vector<webkit::WebPluginInfo>* info,
132 std::vector<std::string>* actual_mime_types);
133
134 // Gets plugin info for an individual plugin and filters the plugins using
135 // the |context| and renderer IDs. This will report whether the data is stale
136 // via |is_stale| and returns whether or not the plugin can be found.
[email protected]11e1c182011-05-17 20:26:27137 bool GetPluginInfo(int render_process_id,
138 int render_view_id,
[email protected]dfba8762011-09-02 12:49:54139 const content::ResourceContext& context,
[email protected]11e1c182011-05-17 20:26:27140 const GURL& url,
[email protected]dfba8762011-09-02 12:49:54141 const GURL& page_url,
[email protected]11e1c182011-05-17 20:26:27142 const std::string& mime_type,
[email protected]dfba8762011-09-02 12:49:54143 bool allow_wildcard,
[email protected]88ca4912011-10-12 14:00:43144 bool* is_stale,
[email protected]91d9f3d2011-08-14 05:24:44145 webkit::WebPluginInfo* info,
[email protected]11e1c182011-05-17 20:26:27146 std::string* actual_mime_type);
[email protected]a0421732011-02-23 03:55:40147
[email protected]88ca4912011-10-12 14:00:43148 // Get plugin info by plugin path (including disabled plugins). Returns true
149 // if the plugin is found and WebPluginInfo has been filled in |info|. This
150 // will use cached data in the plugin list.
151 bool GetPluginInfoByPath(const FilePath& plugin_path,
152 webkit::WebPluginInfo* info);
153
[email protected]d33e7cc2011-09-23 01:43:56154 // Marks the plugin list as dirty and will cause the plugins to be reloaded
155 // on the next access through GetPlugins() or GetPluginGroups().
156 void RefreshPluginList();
157
158 // Asynchronously loads plugins if necessary and then calls back to the
159 // provided function on the calling MessageLoop on completion.
160 void GetPlugins(const GetPluginsCallback& callback);
161
162 // Asynchronously loads the list of plugin groups if necessary and then calls
163 // back to the provided function on the calling MessageLoop on completion.
164 void GetPluginGroups(const GetPluginGroupsCallback& callback);
[email protected]2de307592011-04-05 21:16:58165
[email protected]45a22e62011-10-12 09:48:02166 // Tells all the renderer processes associated with the given browser context
167 // to throw away their cache of the plugin list, and optionally also reload
168 // all the pages with plugins. If |browser_context| is NULL, purges the cache
169 // in all renderers.
[email protected]2de307592011-04-05 21:16:58170 // NOTE: can only be called on the UI thread.
[email protected]45a22e62011-10-12 09:48:02171 static void PurgePluginListCache(content::BrowserContext* browser_context,
172 bool reload_pages);
[email protected]2de307592011-04-05 21:16:58173
[email protected]dfba8762011-09-02 12:49:54174 void set_filter(content::PluginServiceFilter* filter) {
175 filter_ = filter;
176 }
[email protected]d33e7cc2011-09-23 01:43:56177 content::PluginServiceFilter* filter() { return filter_; }
[email protected]dfba8762011-09-02 12:49:54178
[email protected]a0421732011-02-23 03:55:40179 private:
180 friend struct DefaultSingletonTraits<PluginService>;
181
182 // Creates the PluginService object, but doesn't actually build the plugin
183 // list yet. It's generated lazily.
184 PluginService();
[email protected]3690ebe02011-05-25 09:08:19185 virtual ~PluginService();
[email protected]a0421732011-02-23 03:55:40186
187 // base::WaitableEventWatcher::Delegate implementation.
188 virtual void OnWaitableEventSignaled(base::WaitableEvent* waitable_event);
189
[email protected]6c2381d2011-10-19 02:52:53190 // content::NotificationObserver implementation
191 virtual void Observe(int type, const content::NotificationSource& source,
192 const content::NotificationDetails& details);
[email protected]a0421732011-02-23 03:55:40193
194 void RegisterPepperPlugins();
195
[email protected]738a7212011-10-21 17:33:52196 content::PepperPluginInfo* GetRegisteredPpapiPluginInfo(
197 const FilePath& plugin_path);
[email protected]eb415bf0e2011-04-14 02:45:42198
[email protected]d33e7cc2011-09-23 01:43:56199 // Function that is run on the FILE thread to load the plugins synchronously.
200 void GetPluginsInternal(base::MessageLoopProxy* target_loop,
201 const GetPluginsCallback& callback);
202
[email protected]88ca4912011-10-12 14:00:43203 // Binding directly to GetAllowedPluginForOpenChannelToPlugin() isn't possible
204 // because more arity is needed <http://crbug.com/98542>. This just forwards.
205 void ForwardGetAllowedPluginForOpenChannelToPlugin(
206 const content::PluginServiceFilterParams& params,
207 const GURL& url,
208 const std::string& mime_type,
209 PluginProcessHost::Client* client,
210 const std::vector<webkit::WebPluginInfo>&);
[email protected]a0421732011-02-23 03:55:40211 // Helper so we can do the plugin lookup on the FILE thread.
212 void GetAllowedPluginForOpenChannelToPlugin(
213 int render_process_id,
214 int render_view_id,
215 const GURL& url,
[email protected]dfba8762011-09-02 12:49:54216 const GURL& page_url,
[email protected]a0421732011-02-23 03:55:40217 const std::string& mime_type,
[email protected]87c4be42011-09-16 01:10:59218 PluginProcessHost::Client* client,
219 const content::ResourceContext* resource_context);
[email protected]a0421732011-02-23 03:55:40220
221 // Helper so we can finish opening the channel after looking up the
222 // plugin.
223 void FinishOpenChannelToPlugin(
224 const FilePath& plugin_path,
225 PluginProcessHost::Client* client);
226
[email protected]e63c4d72011-05-31 22:38:29227#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]a0421732011-02-23 03:55:40228 // Registers a new FilePathWatcher for a given path.
229 static void RegisterFilePathWatcher(
[email protected]493c8002011-04-14 16:56:01230 base::files::FilePathWatcher* watcher,
[email protected]a0421732011-02-23 03:55:40231 const FilePath& path,
[email protected]493c8002011-04-14 16:56:01232 base::files::FilePathWatcher::Delegate* delegate);
[email protected]a0421732011-02-23 03:55:40233#endif
234
[email protected]a0421732011-02-23 03:55:40235 // The browser's UI locale.
236 const std::string ui_locale_;
237
[email protected]6c2381d2011-10-19 02:52:53238 content::NotificationRegistrar registrar_;
[email protected]a0421732011-02-23 03:55:40239
[email protected]a0421732011-02-23 03:55:40240#if defined(OS_WIN)
241 // Registry keys for getting notifications when new plugins are installed.
242 base::win::RegKey hkcu_key_;
243 base::win::RegKey hklm_key_;
244 scoped_ptr<base::WaitableEvent> hkcu_event_;
245 scoped_ptr<base::WaitableEvent> hklm_event_;
246 base::WaitableEventWatcher hkcu_watcher_;
247 base::WaitableEventWatcher hklm_watcher_;
248#endif
249
[email protected]e63c4d72011-05-31 22:38:29250#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]493c8002011-04-14 16:56:01251 ScopedVector<base::files::FilePathWatcher> file_watchers_;
[email protected]a0421732011-02-23 03:55:40252 scoped_refptr<PluginDirWatcherDelegate> file_watcher_delegate_;
253#endif
254
[email protected]738a7212011-10-21 17:33:52255 std::vector<content::PepperPluginInfo> ppapi_plugins_;
[email protected]a0421732011-02-23 03:55:40256
[email protected]dfba8762011-09-02 12:49:54257 // Weak pointer; outlives us.
258 content::PluginServiceFilter* filter_;
[email protected]a0421732011-02-23 03:55:40259
[email protected]4befe7592011-09-14 22:49:09260 std::set<PluginProcessHost::Client*> pending_plugin_clients_;
261
[email protected]d4af1e72011-10-21 17:45:43262#if defined(OS_POSIX)
263 scoped_refptr<PluginLoaderPosix> plugin_loader_;
264#endif
265
[email protected]a0421732011-02-23 03:55:40266 DISALLOW_COPY_AND_ASSIGN(PluginService);
267};
268
269DISABLE_RUNNABLE_METHOD_REFCOUNT(PluginService);
270
271#endif // CONTENT_BROWSER_PLUGIN_SERVICE_H_