blob: b76a8b00136bff43348e86041dda2bec57129b1a [file] [log] [blame]
[email protected]a3b85d852012-01-27 02:04:481// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]6be08ae2011-10-18 02:23:232// 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_LOADER_POSIX_H_
6#define CONTENT_BROWSER_PLUGIN_LOADER_POSIX_H_
7
[email protected]9a9ab7d32012-03-12 22:51:118#include <deque>
[email protected]6be08ae2011-10-18 02:23:239#include <vector>
10
[email protected]d9b73c82011-11-09 23:17:2811#include "base/basictypes.h"
[email protected]c4f883a2012-02-03 17:02:0712#include "base/compiler_specific.h"
[email protected]6be08ae2011-10-18 02:23:2313#include "base/memory/ref_counted.h"
[email protected]d4af1e72011-10-21 17:45:4314#include "base/time.h"
[email protected]e67385f2011-12-21 06:00:5615#include "content/browser/plugin_service_impl.h"
[email protected]c4f883a2012-02-03 17:02:0716#include "content/public/browser/utility_process_host_client.h"
[email protected]d4af1e72011-10-21 17:45:4317#include "ipc/ipc_message.h"
[email protected]6be08ae2011-10-18 02:23:2318#include "webkit/plugins/webplugininfo.h"
19
[email protected]6be08ae2011-10-18 02:23:2320namespace base {
21class MessageLoopProxy;
22}
23
[email protected]c4f883a2012-02-03 17:02:0724namespace content {
25class UtilityProcessHost;
26}
27
[email protected]d4af1e72011-10-21 17:45:4328// This class is responsible for managing the out-of-process plugin loading on
29// POSIX systems. It primarily lives on the IO thread, but has a brief stay on
30// the FILE thread to iterate over plugin directories when it is first
31// constructed.
32//
33// The following is the algorithm used to load plugins:
34// 1. This asks the PluginList for the list of all potential plugins to attempt
35// to load. This is referred to as the canonical list.
36// 2. The child process this hosts is forked and the canonical list is sent to
37// it.
38// 3. The child process iterates over the canonical list, attempting to load
39// each plugin in the order specified by the list. It sends an IPC message
40// to the browser after each load, indicating success or failure. The two
41// processes synchronize the position in the vector that will be used to
42// attempt to load the next plugin.
43// 4. If the child dies during this process, the host forks another child and
44// resumes loading at the position past the plugin that it just attempted to
45// load, bypassing the problematic plugin.
46// 5. This algorithm continues until the canonical list has been walked to the
47// end, after which the list of loaded plugins is set on the PluginList and
48// the completion callback is run.
[email protected]c4f883a2012-02-03 17:02:0749class CONTENT_EXPORT PluginLoaderPosix
50 : public NON_EXPORTED_BASE(content::UtilityProcessHostClient),
51 public IPC::Message::Sender {
[email protected]6be08ae2011-10-18 02:23:2352 public:
[email protected]d4af1e72011-10-21 17:45:4353 PluginLoaderPosix();
54
55 // Must be called from the IO thread.
[email protected]e67385f2011-12-21 06:00:5656 void LoadPlugins(
57 scoped_refptr<base::MessageLoopProxy> target_loop,
58 const content::PluginService::GetPluginsCallback& callback);
[email protected]6be08ae2011-10-18 02:23:2359
[email protected]c4f883a2012-02-03 17:02:0760 // UtilityProcessHostClient:
[email protected]6be08ae2011-10-18 02:23:2361 virtual void OnProcessCrashed(int exit_code) OVERRIDE;
62 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
63
[email protected]d4af1e72011-10-21 17:45:4364 // IPC::Message::Sender:
[email protected]edc64de2011-11-17 20:07:3865 virtual bool Send(IPC::Message* msg) OVERRIDE;
[email protected]d4af1e72011-10-21 17:45:4366
[email protected]6be08ae2011-10-18 02:23:2367 private:
[email protected]d4af1e72011-10-21 17:45:4368 struct PendingCallback {
69 PendingCallback(scoped_refptr<base::MessageLoopProxy> target_loop,
[email protected]e67385f2011-12-21 06:00:5670 const content::PluginService::GetPluginsCallback& callback);
[email protected]d4af1e72011-10-21 17:45:4371 ~PendingCallback();
72
73 scoped_refptr<base::MessageLoopProxy> target_loop;
[email protected]e67385f2011-12-21 06:00:5674 content::PluginService::GetPluginsCallback callback;
[email protected]d4af1e72011-10-21 17:45:4375 };
76
[email protected]6be08ae2011-10-18 02:23:2377 virtual ~PluginLoaderPosix();
78
[email protected]d4af1e72011-10-21 17:45:4379 // Called on the FILE thread to get the list of plugin paths to probe.
80 void GetPluginsToLoad();
81
82 // Must be called on the IO thread.
83 virtual void LoadPluginsInternal();
84
85 // Message handlers.
[email protected]d9b73c82011-11-09 23:17:2886 void OnPluginLoaded(uint32 index, const webkit::WebPluginInfo& plugin);
87 void OnPluginLoadFailed(uint32 index, const FilePath& plugin_path);
[email protected]d4af1e72011-10-21 17:45:4388
89 // Checks if the plugin path is an internal plugin, and, if it is, adds it to
90 // |loaded_plugins_|.
91 bool MaybeAddInternalPlugin(const FilePath& plugin_path);
92
93 // Runs all the registered callbacks on each's target loop if the condition
94 // for ending the load process is done (i.e. the |next_load_index_| is outside
[email protected]5abe6302011-12-20 23:44:3295 // the range of the |canonical_list_|).
[email protected]6a0dc7a2011-11-02 14:37:0796 bool MaybeRunPendingCallbacks();
[email protected]d4af1e72011-10-21 17:45:4397
98 // The process host for which this is a client.
[email protected]c4f883a2012-02-03 17:02:0799 base::WeakPtr<content::UtilityProcessHost> process_host_;
[email protected]d4af1e72011-10-21 17:45:43100
101 // A list of paths to plugins which will be loaded by the utility process, in
102 // the order specified by this vector.
103 std::vector<FilePath> canonical_list_;
104
105 // The index in |canonical_list_| of the plugin that the child process will
106 // attempt to load next.
107 size_t next_load_index_;
108
109 // Internal plugins that have been registered at the time of loading.
110 std::vector<webkit::WebPluginInfo> internal_plugins_;
111
112 // A vector of plugins that have been loaded successfully.
113 std::vector<webkit::WebPluginInfo> loaded_plugins_;
[email protected]6be08ae2011-10-18 02:23:23114
115 // The callback and message loop on which the callback will be run when the
116 // plugin loading process has been completed.
[email protected]9a9ab7d32012-03-12 22:51:11117 std::deque<PendingCallback> callbacks_;
[email protected]6be08ae2011-10-18 02:23:23118
[email protected]d4af1e72011-10-21 17:45:43119 // The time at which plugin loading started.
120 base::TimeTicks load_start_time_;
121
122 friend class MockPluginLoaderPosix;
[email protected]6be08ae2011-10-18 02:23:23123 DISALLOW_COPY_AND_ASSIGN(PluginLoaderPosix);
124};
125
126#endif // CONTENT_BROWSER_PLUGIN_LOADER_POSIX_H_