blob: 7b0c258cdf43a9180ab80bb690ce90fa175ed85d [file] [log] [blame]
[email protected]b39c9b22012-01-24 17:45:461// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]a0421732011-02-23 03:55:405#include "content/browser/plugin_process_host.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]3e076a82012-09-11 19:12:367#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:298#include <windows.h>
[email protected]2456c572009-11-09 04:21:519#elif defined(OS_POSIX)
10#include <utility> // for pair<>
[email protected]6eaddcc2009-02-23 21:03:0411#endif
12
initial.commit09911bf2008-07-26 23:55:2913#include <vector>
14
[email protected]7c854372011-08-15 20:41:4615#include "base/base_switches.h"
[email protected]80751052011-11-12 17:10:5816#include "base/bind.h"
initial.commit09911bf2008-07-26 23:55:2917#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
initial.commit09911bf2008-07-26 23:55:2919#include "base/logging.h"
[email protected]a5f73fea2012-02-15 18:09:1720#include "base/metrics/histogram.h"
initial.commit09911bf2008-07-26 23:55:2921#include "base/path_service.h"
[email protected]d2f11962009-08-17 19:50:0422#include "base/string_util.h"
[email protected]386c73502010-09-15 17:38:4223#include "base/utf_string_conversions.h"
[email protected]4c01d4992012-01-23 23:33:0124#include "content/browser/browser_child_process_host_impl.h"
[email protected]89ac531b2012-06-28 05:35:1625#include "content/browser/gpu/gpu_data_manager_impl.h"
[email protected]e67385f2011-12-21 06:00:5626#include "content/browser/plugin_service_impl.h"
[email protected]4734d0b2011-12-03 07:10:4427#include "content/common/child_process_host_impl.h"
[email protected]872f3a92013-05-21 08:16:0828#include "content/common/plugin_process_messages.h"
[email protected]94dc971d2011-03-05 19:08:3229#include "content/common/resource_messages.h"
[email protected]c38831a12011-10-28 12:44:4930#include "content/public/browser/browser_thread.h"
[email protected]87f3c082011-10-19 18:07:4431#include "content/public/browser/content_browser_client.h"
[email protected]10d861c52011-11-10 00:03:4132#include "content/public/browser/notification_types.h"
[email protected]47214d882012-02-29 06:28:4833#include "content/public/browser/plugin_service.h"
[email protected]c08950d22011-10-13 22:20:2934#include "content/public/common/content_switches.h"
[email protected]bd5d6cf2011-12-01 00:39:1235#include "content/public/common/process_type.h"
[email protected]979c7e42009-07-23 16:14:0936#include "ipc/ipc_switches.h"
[email protected]42ce29d2011-01-20 23:19:4637#include "ui/base/ui_base_switches.h"
[email protected]c38831a12011-10-28 12:44:4938#include "ui/gfx/native_widget_types.h"
[email protected]c9e2cbbb2012-05-12 21:17:2739#include "ui/gl/gl_switches.h"
[email protected]6eaddcc2009-02-23 21:03:0440
[email protected]753efc42010-03-09 19:52:1641#if defined(USE_X11)
[email protected]08397d52011-02-05 01:53:3842#include "ui/gfx/gtk_native_view_id_manager.h"
[email protected]700d3d52009-07-07 17:40:4643#endif
44
[email protected]f3ef7b12009-08-07 22:03:1745#if defined(OS_MACOSX)
[email protected]0378bf42011-01-01 18:20:1446#include "base/mac/mac_util.h"
[email protected]d31081452011-03-15 21:04:0247#include "content/common/plugin_carbon_interpose_constants_mac.h"
[email protected]08397d52011-02-05 01:53:3848#include "ui/gfx/rect.h"
[email protected]f3ef7b12009-08-07 22:03:1749#endif
50
[email protected]3e076a82012-09-11 19:12:3651#if defined(OS_WIN)
[email protected]ded09892011-08-16 01:44:3552#include "base/win/windows_version.h"
[email protected]a15eb4a2013-03-21 21:33:3853#include "content/public/common/sandboxed_process_launcher_delegate.h"
[email protected]ded09892011-08-16 01:44:3554#include "webkit/plugins/npapi/plugin_constants_win.h"
[email protected]e4486d3202011-06-07 01:42:0455#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
[email protected]130757672012-10-24 00:26:1956#endif
[email protected]e4486d3202011-06-07 01:42:0457
[email protected]130757672012-10-24 00:26:1958namespace content {
59
60#if defined(OS_WIN)
[email protected]875d4892009-04-21 21:48:3661void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) {
62 // The window is destroyed at this point, we just care about its parent, which
63 // is the intermediate window we created.
[email protected]20b64d32009-03-05 02:07:1864 std::set<HWND>::iterator window_index =
[email protected]875d4892009-04-21 21:48:3665 plugin_parent_windows_set_.find(parent);
66 if (window_index == plugin_parent_windows_set_.end())
67 return;
[email protected]20b64d32009-03-05 02:07:1868
[email protected]875d4892009-04-21 21:48:3669 plugin_parent_windows_set_.erase(window_index);
70 PostMessage(parent, WM_CLOSE, 0, 0);
[email protected]20b64d32009-03-05 02:07:1871}
72
73void PluginProcessHost::AddWindow(HWND window) {
74 plugin_parent_windows_set_.insert(window);
[email protected]6eaddcc2009-02-23 21:03:0475}
76
[email protected]a15eb4a2013-03-21 21:33:3877// NOTE: changes to this class need to be reviewed by the security team.
78class PluginSandboxedProcessLauncherDelegate
79 : public SandboxedProcessLauncherDelegate {
80 public:
81 PluginSandboxedProcessLauncherDelegate() {}
82 virtual ~PluginSandboxedProcessLauncherDelegate() {}
83
84 virtual void ShouldSandbox(bool* in_sandbox) OVERRIDE {
85 *in_sandbox = false;
86 }
87
88 private:
89 DISALLOW_COPY_AND_ASSIGN(PluginSandboxedProcessLauncherDelegate);
90};
91
[email protected]6eaddcc2009-02-23 21:03:0492#endif // defined(OS_WIN)
[email protected]d7f45952009-01-16 23:04:2393
[email protected]a13283cc2012-04-05 00:21:2294#if defined(TOOLKIT_GTK)
[email protected]700d3d52009-07-07 17:40:4695void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id,
96 gfx::PluginWindowHandle* output) {
97 *output = 0;
[email protected]3fa441d2011-09-18 17:28:5098#if !defined(USE_AURA)
[email protected]687b9602010-12-08 10:43:0899 GtkNativeViewManager::GetInstance()->GetXIDForId(output, id);
[email protected]3fa441d2011-09-18 17:28:50100#endif
[email protected]700d3d52009-07-07 17:40:46101}
[email protected]a13283cc2012-04-05 00:21:22102#endif // defined(TOOLKIT_GTK)
[email protected]700d3d52009-07-07 17:40:46103
[email protected]dabe6072009-03-17 00:52:35104PluginProcessHost::PluginProcessHost()
[email protected]2db347232010-05-28 21:26:36105#if defined(OS_MACOSX)
[email protected]4967f792012-01-20 22:14:40106 : plugin_cursor_visible_(true)
[email protected]2db347232010-05-28 21:26:36107#endif
108{
[email protected]130757672012-10-24 00:26:19109 process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_PLUGIN, this));
initial.commit09911bf2008-07-26 23:55:29110}
111
112PluginProcessHost::~PluginProcessHost() {
[email protected]3e076a82012-09-11 19:12:36113#if defined(OS_WIN)
[email protected]20b64d32009-03-05 02:07:18114 // We erase HWNDs from the plugin_parent_windows_set_ when we receive a
115 // notification that the window is being destroyed. If we don't receive this
116 // notification and the PluginProcessHost instance is being destroyed, it
117 // means that the plugin process crashed. We paint a sad face in this case in
118 // the renderer process. To ensure that the sad face shows up, and we don't
119 // leak HWNDs, we should destroy existing plugin parent windows.
120 std::set<HWND>::iterator window_index;
121 for (window_index = plugin_parent_windows_set_.begin();
122 window_index != plugin_parent_windows_set_.end();
[email protected]0208c0c2013-04-22 03:43:18123 ++window_index) {
[email protected]20b64d32009-03-05 02:07:18124 PostMessage(*window_index, WM_CLOSE, 0, 0);
125 }
[email protected]1d5ac662009-10-01 19:41:56126#elif defined(OS_MACOSX)
[email protected]0208c0c2013-04-22 03:43:18127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]b44dbd12009-10-11 19:02:15128 // If the plugin process crashed but had fullscreen windows open at the time,
129 // make sure that the menu bar is visible.
[email protected]0208c0c2013-04-22 03:43:18130 for (size_t i = 0; i < plugin_fullscreen_windows_set_.size(); ++i) {
131 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
132 base::Bind(base::mac::ReleaseFullScreen,
133 base::mac::kFullScreenModeHideAll));
[email protected]1d5ac662009-10-01 19:41:56134 }
[email protected]18db46182010-02-02 17:04:55135 // If the plugin hid the cursor, reset that.
136 if (!plugin_cursor_visible_) {
[email protected]0208c0c2013-04-22 03:43:18137 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
138 base::Bind(base::mac::SetCursorVisibility, true));
[email protected]18db46182010-02-02 17:04:55139 }
[email protected]20b64d32009-03-05 02:07:18140#endif
[email protected]46b69e42010-11-02 12:26:39141 // Cancel all pending and sent requests.
142 CancelRequests();
initial.commit09911bf2008-07-26 23:55:29143}
144
[email protected]4967f792012-01-20 22:14:40145bool PluginProcessHost::Send(IPC::Message* message) {
146 return process_->Send(message);
147}
148
[email protected]99907362012-01-11 05:41:40149bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) {
[email protected]a27a9382009-02-11 23:55:10150 info_ = info;
[email protected]4967f792012-01-20 22:14:40151 process_->SetName(info_.name);
[email protected]a27a9382009-02-11 23:55:10152
[email protected]4967f792012-01-20 22:14:40153 std::string channel_id = process_->GetHost()->CreateChannel();
[email protected]4734d0b2011-12-03 07:10:44154 if (channel_id.empty())
initial.commit09911bf2008-07-26 23:55:29155 return false;
156
[email protected]7c4ea142010-01-26 05:15:42157 // Build command line for plugin. When we have a plugin launcher, we can't
158 // allow "self" on linux and we need the real file path.
159 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
[email protected]13081fc2010-08-04 18:24:38160 CommandLine::StringType plugin_launcher =
161 browser_command_line.GetSwitchValueNative(switches::kPluginLauncher);
[email protected]8c40f322011-08-24 03:33:36162
163#if defined(OS_MACOSX)
164 // Run the plug-in process in a mode tolerant of heap execution without
165 // explicit mprotect calls. Some plug-ins still rely on this quaint and
166 // archaic "feature." See http://crbug.com/93551.
[email protected]4cb43102011-12-02 20:24:49167 int flags = ChildProcessHost::CHILD_ALLOW_HEAP_EXECUTION;
[email protected]8c40f322011-08-24 03:33:36168#elif defined(OS_LINUX)
[email protected]4cb43102011-12-02 20:24:49169 int flags = plugin_launcher.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
170 ChildProcessHost::CHILD_NORMAL;
[email protected]8c40f322011-08-24 03:33:36171#else
[email protected]4cb43102011-12-02 20:24:49172 int flags = ChildProcessHost::CHILD_NORMAL;
[email protected]8c40f322011-08-24 03:33:36173#endif
174
[email protected]2dec8ec2013-02-07 19:20:34175 base::FilePath exe_path = ChildProcessHost::GetChildPath(flags);
[email protected]ba4c78e2009-10-13 23:00:11176 if (exe_path.empty())
initial.commit09911bf2008-07-26 23:55:29177 return false;
178
[email protected]fb1277e82009-11-21 20:32:30179 CommandLine* cmd_line = new CommandLine(exe_path);
[email protected]588c54b02009-09-18 21:45:54180 // Put the process type and plugin path first so they're easier to see
181 // in process listings using native process management tools.
[email protected]05076ba22010-07-30 05:59:57182 cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kPluginProcess);
[email protected]4f08c83f2010-07-29 23:02:34183 cmd_line->AppendSwitchPath(switches::kPluginPath, info.path);
[email protected]588c54b02009-09-18 21:45:54184
[email protected]2735e3692009-09-25 18:19:39185 // Propagate the following switches to the plugin command line (along with
initial.commit09911bf2008-07-26 23:55:29186 // any associated values) if present in the browser command line
[email protected]4f08c83f2010-07-29 23:02:34187 static const char* const kSwitchNames[] = {
initial.commit09911bf2008-07-26 23:55:29188 switches::kDisableBreakpad,
[email protected]dc51d1c2011-11-30 04:42:21189#if defined(OS_MACOSX)
[email protected]89ac531b2012-06-28 05:35:16190 switches::kDisableCoreAnimationPlugins,
[email protected]172ca982012-10-03 19:55:07191 switches::kEnableSandboxLogging,
192#endif
[email protected]4500a722009-03-27 19:56:54193 switches::kEnableStatsTable,
[email protected]b1f172a72011-04-11 17:26:07194 switches::kFullMemoryCrashReport,
195 switches::kLoggingLevel,
[email protected]b1f172a72011-04-11 17:26:07196 switches::kLogPluginMessages,
[email protected]b1f172a72011-04-11 17:26:07197 switches::kNoSandbox,
198 switches::kPluginStartupDialog,
[email protected]b1f172a72011-04-11 17:26:07199 switches::kTestSandbox,
[email protected]50f38422011-11-09 19:21:33200 switches::kTraceStartup,
[email protected]b1f172a72011-04-11 17:26:07201 switches::kUseGL,
202 switches::kUserAgent,
initial.commit09911bf2008-07-26 23:55:29203 };
204
[email protected]4f08c83f2010-07-29 23:02:34205 cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
206 arraysize(kSwitchNames));
initial.commit09911bf2008-07-26 23:55:29207
[email protected]89ac531b2012-06-28 05:35:16208 GpuDataManagerImpl::GetInstance()->AppendPluginCommandLine(cmd_line);
209
initial.commit09911bf2008-07-26 23:55:29210 // If specified, prepend a launcher program to the command line.
[email protected]e5e19c32009-04-20 22:10:02211 if (!plugin_launcher.empty())
[email protected]fb1277e82009-11-21 20:32:30212 cmd_line->PrependWrapper(plugin_launcher);
initial.commit09911bf2008-07-26 23:55:29213
[email protected]130757672012-10-24 00:26:19214 std::string locale = GetContentClient()->browser()->GetApplicationLocale();
initial.commit09911bf2008-07-26 23:55:29215 if (!locale.empty()) {
216 // Pass on the locale so the null plugin will use the right language in the
217 // prompt to install the desired plugin.
[email protected]f77d87622010-07-30 17:43:17218 cmd_line->AppendSwitchASCII(switches::kLang, locale);
initial.commit09911bf2008-07-26 23:55:29219 }
220
[email protected]4734d0b2011-12-03 07:10:44221 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
initial.commit09911bf2008-07-26 23:55:29222
[email protected]2456c572009-11-09 04:21:51223#if defined(OS_POSIX)
[email protected]a82af392012-02-24 04:40:20224 base::EnvironmentVector env;
[email protected]23563dc1e2010-02-16 16:11:00225#if defined(OS_MACOSX) && !defined(__LP64__)
[email protected]097d4ed2012-10-22 16:37:54226 if (!browser_command_line.HasSwitch(switches::kDisableCarbonInterposing)) {
[email protected]130757672012-10-24 00:26:19227 std::string interpose_list = GetContentClient()->GetCarbonInterposePath();
[email protected]097d4ed2012-10-22 16:37:54228 if (!interpose_list.empty()) {
229 // Add our interposing library for Carbon. This is stripped back out in
230 // plugin_main.cc, so changes here should be reflected there.
[email protected]130757672012-10-24 00:26:19231 const char* existing_list = getenv(kDYLDInsertLibrariesKey);
[email protected]097d4ed2012-10-22 16:37:54232 if (existing_list) {
233 interpose_list.insert(0, ":");
234 interpose_list.insert(0, existing_list);
235 }
[email protected]69211e8c2012-07-23 22:20:41236 }
[email protected]097d4ed2012-10-22 16:37:54237 env.push_back(std::pair<std::string, std::string>(
[email protected]130757672012-10-24 00:26:19238 kDYLDInsertLibrariesKey, interpose_list));
[email protected]f3ef7b12009-08-07 22:03:17239 }
[email protected]fb1277e82009-11-21 20:32:30240#endif
241#endif
242
[email protected]4967f792012-01-20 22:14:40243 process_->Launch(
[email protected]fb1277e82009-11-21 20:32:30244#if defined(OS_WIN)
[email protected]a15eb4a2013-03-21 21:33:38245 new PluginSandboxedProcessLauncherDelegate,
[email protected]fb1277e82009-11-21 20:32:30246#elif defined(OS_POSIX)
[email protected]7c4ea142010-01-26 05:15:42247 false,
[email protected]fb1277e82009-11-21 20:32:30248 env,
249#endif
250 cmd_line);
251
[email protected]358cb8e2011-05-25 02:12:45252 // The plugin needs to be shutdown gracefully, i.e. NP_Shutdown needs to be
253 // called on the plugin. The plugin process exits when it receives the
254 // OnChannelError notification indicating that the browser plugin channel has
255 // been destroyed.
[email protected]4967f792012-01-20 22:14:40256 process_->SetTerminateChildOnShutdown(false);
[email protected]358cb8e2011-05-25 02:12:45257
[email protected]fb1277e82009-11-21 20:32:30258 return true;
initial.commit09911bf2008-07-26 23:55:29259}
[email protected]fb1277e82009-11-21 20:32:30260
[email protected]4e59e812010-04-06 20:51:16261void PluginProcessHost::ForceShutdown() {
[email protected]f8b3ef82010-10-11 02:45:52262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
[email protected]4e59e812010-04-06 20:51:16263 Send(new PluginProcessMsg_NotifyRenderersOfPendingShutdown());
[email protected]4967f792012-01-20 22:14:40264 process_->ForceShutdown();
[email protected]4e59e812010-04-06 20:51:16265}
266
[email protected]4cb43102011-12-02 20:24:49267void PluginProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]4967f792012-01-20 22:14:40268 process_->GetHost()->AddFilter(filter);
[email protected]4cb43102011-12-02 20:24:49269}
270
[email protected]a95986a82010-12-24 06:19:28271bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
272 bool handled = true;
initial.commit09911bf2008-07-26 23:55:29273 IPC_BEGIN_MESSAGE_MAP(PluginProcessHost, msg)
274 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ChannelCreated, OnChannelCreated)
[email protected]3e076a82012-09-11 19:12:36275#if defined(OS_WIN)
[email protected]875d4892009-04-21 21:48:36276 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginWindowDestroyed,
277 OnPluginWindowDestroyed)
[email protected]829c2842009-04-01 01:48:52278#endif
[email protected]a13283cc2012-04-05 00:21:22279#if defined(TOOLKIT_GTK)
[email protected]700d3d52009-07-07 17:40:46280 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_MapNativeViewId,
281 OnMapNativeViewId)
282#endif
[email protected]1d5ac662009-10-01 19:41:56283#if defined(OS_MACOSX)
284 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginSelectWindow,
285 OnPluginSelectWindow)
286 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginShowWindow,
287 OnPluginShowWindow)
288 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginHideWindow,
289 OnPluginHideWindow)
[email protected]18db46182010-02-02 17:04:55290 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginSetCursorVisibility,
291 OnPluginSetCursorVisibility)
[email protected]1d5ac662009-10-01 19:41:56292#endif
[email protected]a95986a82010-12-24 06:19:28293 IPC_MESSAGE_UNHANDLED(handled = false)
initial.commit09911bf2008-07-26 23:55:29294 IPC_END_MESSAGE_MAP()
[email protected]a95986a82010-12-24 06:19:28295
296 DCHECK(handled);
297 return handled;
initial.commit09911bf2008-07-26 23:55:29298}
299
300void PluginProcessHost::OnChannelConnected(int32 peer_pid) {
initial.commit09911bf2008-07-26 23:55:29301 for (size_t i = 0; i < pending_requests_.size(); ++i) {
[email protected]46b69e42010-11-02 12:26:39302 RequestPluginChannel(pending_requests_[i]);
initial.commit09911bf2008-07-26 23:55:29303 }
304
305 pending_requests_.clear();
initial.commit09911bf2008-07-26 23:55:29306}
307
308void PluginProcessHost::OnChannelError() {
[email protected]46b69e42010-11-02 12:26:39309 CancelRequests();
310}
initial.commit09911bf2008-07-26 23:55:29311
[email protected]ddb1e5a2010-12-13 20:10:45312bool PluginProcessHost::CanShutdown() {
313 return sent_requests_.empty();
314}
315
[email protected]47214d882012-02-29 06:28:48316void PluginProcessHost::OnProcessCrashed(int exit_code) {
317 PluginServiceImpl::GetInstance()->RegisterPluginCrash(info_.path);
318}
319
[email protected]46b69e42010-11-02 12:26:39320void PluginProcessHost::CancelRequests() {
321 for (size_t i = 0; i < pending_requests_.size(); ++i)
322 pending_requests_[i]->OnError();
initial.commit09911bf2008-07-26 23:55:29323 pending_requests_.clear();
[email protected]a3a8fb6d2009-10-22 20:12:51324
325 while (!sent_requests_.empty()) {
[email protected]8d32d5f2011-09-15 02:22:32326 Client* client = sent_requests_.front();
327 if (client)
328 client->OnError();
[email protected]4befe7592011-09-14 22:49:09329 sent_requests_.pop_front();
[email protected]a3a8fb6d2009-10-22 20:12:51330 }
initial.commit09911bf2008-07-26 23:55:29331}
332
[email protected]1a5acea82011-09-12 11:00:21333// static
334void PluginProcessHost::CancelPendingRequestsForResourceContext(
[email protected]130757672012-10-24 00:26:19335 ResourceContext* context) {
[email protected]4967f792012-01-20 22:14:40336 for (PluginProcessHostIterator host_it; !host_it.Done(); ++host_it) {
337 PluginProcessHost* host = *host_it;
[email protected]1a5acea82011-09-12 11:00:21338 for (size_t i = 0; i < host->pending_requests_.size(); ++i) {
[email protected]df02aca2012-02-09 21:03:20339 if (host->pending_requests_[i]->GetResourceContext() == context) {
[email protected]1a5acea82011-09-12 11:00:21340 host->pending_requests_[i]->OnError();
341 host->pending_requests_.erase(host->pending_requests_.begin() + i);
342 --i;
343 }
344 }
345 }
346}
347
[email protected]46b69e42010-11-02 12:26:39348void PluginProcessHost::OpenChannelToPlugin(Client* client) {
[email protected]f4eaf7b92013-02-28 22:00:40349 BrowserThread::PostTask(
350 BrowserThread::UI, FROM_HERE,
351 base::Bind(&BrowserChildProcessHostImpl::NotifyProcessInstanceCreated,
352 process_->GetData()));
[email protected]46b69e42010-11-02 12:26:39353 client->SetPluginInfo(info_);
[email protected]4967f792012-01-20 22:14:40354 if (process_->GetHost()->IsChannelOpening()) {
[email protected]d2e884d2009-06-22 20:37:52355 // The channel is already in the process of being opened. Put
356 // this "open channel" request into a queue of requests that will
357 // be run once the channel is open.
[email protected]46b69e42010-11-02 12:26:39358 pending_requests_.push_back(client);
initial.commit09911bf2008-07-26 23:55:29359 return;
360 }
361
initial.commit09911bf2008-07-26 23:55:29362 // We already have an open channel, send a request right away to plugin.
[email protected]46b69e42010-11-02 12:26:39363 RequestPluginChannel(client);
initial.commit09911bf2008-07-26 23:55:29364}
365
[email protected]4befe7592011-09-14 22:49:09366void PluginProcessHost::CancelPendingRequest(Client* client) {
367 std::vector<Client*>::iterator it = pending_requests_.begin();
368 while (it != pending_requests_.end()) {
369 if (client == *it) {
370 pending_requests_.erase(it);
371 return;
372 }
373 ++it;
374 }
375 DCHECK(it != pending_requests_.end());
376}
377
378void PluginProcessHost::CancelSentRequest(Client* client) {
379 std::list<Client*>::iterator it = sent_requests_.begin();
380 while (it != sent_requests_.end()) {
381 if (client == *it) {
382 *it = NULL;
383 return;
384 }
385 ++it;
386 }
387 DCHECK(it != sent_requests_.end());
388}
389
[email protected]46b69e42010-11-02 12:26:39390void PluginProcessHost::RequestPluginChannel(Client* client) {
initial.commit09911bf2008-07-26 23:55:29391 // We can't send any sync messages from the browser because it might lead to
392 // a hang. However this async messages must be answered right away by the
393 // plugin process (i.e. unblocks a Send() call like a sync message) otherwise
394 // a deadlock can occur if the plugin creation request from the renderer is
395 // a result of a sync message by the plugin process.
[email protected]46b69e42010-11-02 12:26:39396 PluginProcessMsg_CreateChannel* msg =
[email protected]d5a19162011-06-30 18:51:54397 new PluginProcessMsg_CreateChannel(
398 client->ID(),
399 client->OffTheRecord());
initial.commit09911bf2008-07-26 23:55:29400 msg->set_unblock(true);
401 if (Send(msg)) {
[email protected]4befe7592011-09-14 22:49:09402 sent_requests_.push_back(client);
403 client->OnSentPluginChannelRequest();
initial.commit09911bf2008-07-26 23:55:29404 } else {
[email protected]46b69e42010-11-02 12:26:39405 client->OnError();
initial.commit09911bf2008-07-26 23:55:29406 }
407}
408
[email protected]3dfc7a42009-06-27 01:43:51409void PluginProcessHost::OnChannelCreated(
410 const IPC::ChannelHandle& channel_handle) {
[email protected]46b69e42010-11-02 12:26:39411 Client* client = sent_requests_.front();
[email protected]3dfc7a42009-06-27 01:43:51412
[email protected]4befe7592011-09-14 22:49:09413 if (client)
414 client->OnChannelOpened(channel_handle);
415 sent_requests_.pop_front();
initial.commit09911bf2008-07-26 23:55:29416}
[email protected]130757672012-10-24 00:26:19417
418} // namespace content