[email protected] | b39c9b2 | 2012-01-24 17:45:46 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
[email protected] | a042173 | 2011-02-23 03:55:40 | [diff] [blame] | 5 | #include "content/browser/plugin_process_host.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 6 | |
[email protected] | 3e076a8 | 2012-09-11 19:12:36 | [diff] [blame] | 7 | #if defined(OS_WIN) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 8 | #include <windows.h> |
[email protected] | 2456c57 | 2009-11-09 04:21:51 | [diff] [blame] | 9 | #elif defined(OS_POSIX) |
| 10 | #include <utility> // for pair<> |
[email protected] | 6eaddcc | 2009-02-23 21:03:04 | [diff] [blame] | 11 | #endif |
| 12 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 13 | #include <vector> |
| 14 | |
[email protected] | 7c85437 | 2011-08-15 20:41:46 | [diff] [blame] | 15 | #include "base/base_switches.h" |
[email protected] | 8075105 | 2011-11-12 17:10:58 | [diff] [blame] | 16 | #include "base/bind.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 17 | #include "base/command_line.h" |
[email protected] | 5799981 | 2013-02-24 05:40:52 | [diff] [blame] | 18 | #include "base/files/file_path.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 19 | #include "base/logging.h" |
[email protected] | a5f73fea | 2012-02-15 18:09:17 | [diff] [blame] | 20 | #include "base/metrics/histogram.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 21 | #include "base/path_service.h" |
[email protected] | d2f1196 | 2009-08-17 19:50:04 | [diff] [blame] | 22 | #include "base/string_util.h" |
[email protected] | 386c7350 | 2010-09-15 17:38:42 | [diff] [blame] | 23 | #include "base/utf_string_conversions.h" |
[email protected] | 4c01d499 | 2012-01-23 23:33:01 | [diff] [blame] | 24 | #include "content/browser/browser_child_process_host_impl.h" |
[email protected] | 89ac531b | 2012-06-28 05:35:16 | [diff] [blame] | 25 | #include "content/browser/gpu/gpu_data_manager_impl.h" |
[email protected] | e67385f | 2011-12-21 06:00:56 | [diff] [blame] | 26 | #include "content/browser/plugin_service_impl.h" |
[email protected] | 4734d0b | 2011-12-03 07:10:44 | [diff] [blame] | 27 | #include "content/common/child_process_host_impl.h" |
[email protected] | 872f3a9 | 2013-05-21 08:16:08 | [diff] [blame^] | 28 | #include "content/common/plugin_process_messages.h" |
[email protected] | 94dc971d | 2011-03-05 19:08:32 | [diff] [blame] | 29 | #include "content/common/resource_messages.h" |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 30 | #include "content/public/browser/browser_thread.h" |
[email protected] | 87f3c08 | 2011-10-19 18:07:44 | [diff] [blame] | 31 | #include "content/public/browser/content_browser_client.h" |
[email protected] | 10d861c5 | 2011-11-10 00:03:41 | [diff] [blame] | 32 | #include "content/public/browser/notification_types.h" |
[email protected] | 47214d88 | 2012-02-29 06:28:48 | [diff] [blame] | 33 | #include "content/public/browser/plugin_service.h" |
[email protected] | c08950d2 | 2011-10-13 22:20:29 | [diff] [blame] | 34 | #include "content/public/common/content_switches.h" |
[email protected] | bd5d6cf | 2011-12-01 00:39:12 | [diff] [blame] | 35 | #include "content/public/common/process_type.h" |
[email protected] | 979c7e4 | 2009-07-23 16:14:09 | [diff] [blame] | 36 | #include "ipc/ipc_switches.h" |
[email protected] | 42ce29d | 2011-01-20 23:19:46 | [diff] [blame] | 37 | #include "ui/base/ui_base_switches.h" |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 38 | #include "ui/gfx/native_widget_types.h" |
[email protected] | c9e2cbbb | 2012-05-12 21:17:27 | [diff] [blame] | 39 | #include "ui/gl/gl_switches.h" |
[email protected] | 6eaddcc | 2009-02-23 21:03:04 | [diff] [blame] | 40 | |
[email protected] | 753efc4 | 2010-03-09 19:52:16 | [diff] [blame] | 41 | #if defined(USE_X11) |
[email protected] | 08397d5 | 2011-02-05 01:53:38 | [diff] [blame] | 42 | #include "ui/gfx/gtk_native_view_id_manager.h" |
[email protected] | 700d3d5 | 2009-07-07 17:40:46 | [diff] [blame] | 43 | #endif |
| 44 | |
[email protected] | f3ef7b1 | 2009-08-07 22:03:17 | [diff] [blame] | 45 | #if defined(OS_MACOSX) |
[email protected] | 0378bf4 | 2011-01-01 18:20:14 | [diff] [blame] | 46 | #include "base/mac/mac_util.h" |
[email protected] | d3108145 | 2011-03-15 21:04:02 | [diff] [blame] | 47 | #include "content/common/plugin_carbon_interpose_constants_mac.h" |
[email protected] | 08397d5 | 2011-02-05 01:53:38 | [diff] [blame] | 48 | #include "ui/gfx/rect.h" |
[email protected] | f3ef7b1 | 2009-08-07 22:03:17 | [diff] [blame] | 49 | #endif |
| 50 | |
[email protected] | 3e076a8 | 2012-09-11 19:12:36 | [diff] [blame] | 51 | #if defined(OS_WIN) |
[email protected] | ded0989 | 2011-08-16 01:44:35 | [diff] [blame] | 52 | #include "base/win/windows_version.h" |
[email protected] | a15eb4a | 2013-03-21 21:33:38 | [diff] [blame] | 53 | #include "content/public/common/sandboxed_process_launcher_delegate.h" |
[email protected] | ded0989 | 2011-08-16 01:44:35 | [diff] [blame] | 54 | #include "webkit/plugins/npapi/plugin_constants_win.h" |
[email protected] | e4486d320 | 2011-06-07 01:42:04 | [diff] [blame] | 55 | #include "webkit/plugins/npapi/webplugin_delegate_impl.h" |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 56 | #endif |
[email protected] | e4486d320 | 2011-06-07 01:42:04 | [diff] [blame] | 57 | |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 58 | namespace content { |
| 59 | |
| 60 | #if defined(OS_WIN) |
[email protected] | 875d489 | 2009-04-21 21:48:36 | [diff] [blame] | 61 | void 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] | 20b64d3 | 2009-03-05 02:07:18 | [diff] [blame] | 64 | std::set<HWND>::iterator window_index = |
[email protected] | 875d489 | 2009-04-21 21:48:36 | [diff] [blame] | 65 | plugin_parent_windows_set_.find(parent); |
| 66 | if (window_index == plugin_parent_windows_set_.end()) |
| 67 | return; |
[email protected] | 20b64d3 | 2009-03-05 02:07:18 | [diff] [blame] | 68 | |
[email protected] | 875d489 | 2009-04-21 21:48:36 | [diff] [blame] | 69 | plugin_parent_windows_set_.erase(window_index); |
| 70 | PostMessage(parent, WM_CLOSE, 0, 0); |
[email protected] | 20b64d3 | 2009-03-05 02:07:18 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | void PluginProcessHost::AddWindow(HWND window) { |
| 74 | plugin_parent_windows_set_.insert(window); |
[email protected] | 6eaddcc | 2009-02-23 21:03:04 | [diff] [blame] | 75 | } |
| 76 | |
[email protected] | a15eb4a | 2013-03-21 21:33:38 | [diff] [blame] | 77 | // NOTE: changes to this class need to be reviewed by the security team. |
| 78 | class 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] | 6eaddcc | 2009-02-23 21:03:04 | [diff] [blame] | 92 | #endif // defined(OS_WIN) |
[email protected] | d7f4595 | 2009-01-16 23:04:23 | [diff] [blame] | 93 | |
[email protected] | a13283cc | 2012-04-05 00:21:22 | [diff] [blame] | 94 | #if defined(TOOLKIT_GTK) |
[email protected] | 700d3d5 | 2009-07-07 17:40:46 | [diff] [blame] | 95 | void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, |
| 96 | gfx::PluginWindowHandle* output) { |
| 97 | *output = 0; |
[email protected] | 3fa441d | 2011-09-18 17:28:50 | [diff] [blame] | 98 | #if !defined(USE_AURA) |
[email protected] | 687b960 | 2010-12-08 10:43:08 | [diff] [blame] | 99 | GtkNativeViewManager::GetInstance()->GetXIDForId(output, id); |
[email protected] | 3fa441d | 2011-09-18 17:28:50 | [diff] [blame] | 100 | #endif |
[email protected] | 700d3d5 | 2009-07-07 17:40:46 | [diff] [blame] | 101 | } |
[email protected] | a13283cc | 2012-04-05 00:21:22 | [diff] [blame] | 102 | #endif // defined(TOOLKIT_GTK) |
[email protected] | 700d3d5 | 2009-07-07 17:40:46 | [diff] [blame] | 103 | |
[email protected] | dabe607 | 2009-03-17 00:52:35 | [diff] [blame] | 104 | PluginProcessHost::PluginProcessHost() |
[email protected] | 2db34723 | 2010-05-28 21:26:36 | [diff] [blame] | 105 | #if defined(OS_MACOSX) |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 106 | : plugin_cursor_visible_(true) |
[email protected] | 2db34723 | 2010-05-28 21:26:36 | [diff] [blame] | 107 | #endif |
| 108 | { |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 109 | process_.reset(new BrowserChildProcessHostImpl(PROCESS_TYPE_PLUGIN, this)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | PluginProcessHost::~PluginProcessHost() { |
[email protected] | 3e076a8 | 2012-09-11 19:12:36 | [diff] [blame] | 113 | #if defined(OS_WIN) |
[email protected] | 20b64d3 | 2009-03-05 02:07:18 | [diff] [blame] | 114 | // 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] | 0208c0c | 2013-04-22 03:43:18 | [diff] [blame] | 123 | ++window_index) { |
[email protected] | 20b64d3 | 2009-03-05 02:07:18 | [diff] [blame] | 124 | PostMessage(*window_index, WM_CLOSE, 0, 0); |
| 125 | } |
[email protected] | 1d5ac66 | 2009-10-01 19:41:56 | [diff] [blame] | 126 | #elif defined(OS_MACOSX) |
[email protected] | 0208c0c | 2013-04-22 03:43:18 | [diff] [blame] | 127 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
[email protected] | b44dbd1 | 2009-10-11 19:02:15 | [diff] [blame] | 128 | // If the plugin process crashed but had fullscreen windows open at the time, |
| 129 | // make sure that the menu bar is visible. |
[email protected] | 0208c0c | 2013-04-22 03:43:18 | [diff] [blame] | 130 | 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] | 1d5ac66 | 2009-10-01 19:41:56 | [diff] [blame] | 134 | } |
[email protected] | 18db4618 | 2010-02-02 17:04:55 | [diff] [blame] | 135 | // If the plugin hid the cursor, reset that. |
| 136 | if (!plugin_cursor_visible_) { |
[email protected] | 0208c0c | 2013-04-22 03:43:18 | [diff] [blame] | 137 | BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 138 | base::Bind(base::mac::SetCursorVisibility, true)); |
[email protected] | 18db4618 | 2010-02-02 17:04:55 | [diff] [blame] | 139 | } |
[email protected] | 20b64d3 | 2009-03-05 02:07:18 | [diff] [blame] | 140 | #endif |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 141 | // Cancel all pending and sent requests. |
| 142 | CancelRequests(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 143 | } |
| 144 | |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 145 | bool PluginProcessHost::Send(IPC::Message* message) { |
| 146 | return process_->Send(message); |
| 147 | } |
| 148 | |
[email protected] | 9990736 | 2012-01-11 05:41:40 | [diff] [blame] | 149 | bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { |
[email protected] | a27a938 | 2009-02-11 23:55:10 | [diff] [blame] | 150 | info_ = info; |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 151 | process_->SetName(info_.name); |
[email protected] | a27a938 | 2009-02-11 23:55:10 | [diff] [blame] | 152 | |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 153 | std::string channel_id = process_->GetHost()->CreateChannel(); |
[email protected] | 4734d0b | 2011-12-03 07:10:44 | [diff] [blame] | 154 | if (channel_id.empty()) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 155 | return false; |
| 156 | |
[email protected] | 7c4ea14 | 2010-01-26 05:15:42 | [diff] [blame] | 157 | // 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] | 13081fc | 2010-08-04 18:24:38 | [diff] [blame] | 160 | CommandLine::StringType plugin_launcher = |
| 161 | browser_command_line.GetSwitchValueNative(switches::kPluginLauncher); |
[email protected] | 8c40f32 | 2011-08-24 03:33:36 | [diff] [blame] | 162 | |
| 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] | 4cb4310 | 2011-12-02 20:24:49 | [diff] [blame] | 167 | int flags = ChildProcessHost::CHILD_ALLOW_HEAP_EXECUTION; |
[email protected] | 8c40f32 | 2011-08-24 03:33:36 | [diff] [blame] | 168 | #elif defined(OS_LINUX) |
[email protected] | 4cb4310 | 2011-12-02 20:24:49 | [diff] [blame] | 169 | int flags = plugin_launcher.empty() ? ChildProcessHost::CHILD_ALLOW_SELF : |
| 170 | ChildProcessHost::CHILD_NORMAL; |
[email protected] | 8c40f32 | 2011-08-24 03:33:36 | [diff] [blame] | 171 | #else |
[email protected] | 4cb4310 | 2011-12-02 20:24:49 | [diff] [blame] | 172 | int flags = ChildProcessHost::CHILD_NORMAL; |
[email protected] | 8c40f32 | 2011-08-24 03:33:36 | [diff] [blame] | 173 | #endif |
| 174 | |
[email protected] | 2dec8ec | 2013-02-07 19:20:34 | [diff] [blame] | 175 | base::FilePath exe_path = ChildProcessHost::GetChildPath(flags); |
[email protected] | ba4c78e | 2009-10-13 23:00:11 | [diff] [blame] | 176 | if (exe_path.empty()) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 177 | return false; |
| 178 | |
[email protected] | fb1277e8 | 2009-11-21 20:32:30 | [diff] [blame] | 179 | CommandLine* cmd_line = new CommandLine(exe_path); |
[email protected] | 588c54b0 | 2009-09-18 21:45:54 | [diff] [blame] | 180 | // 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] | 05076ba2 | 2010-07-30 05:59:57 | [diff] [blame] | 182 | cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kPluginProcess); |
[email protected] | 4f08c83f | 2010-07-29 23:02:34 | [diff] [blame] | 183 | cmd_line->AppendSwitchPath(switches::kPluginPath, info.path); |
[email protected] | 588c54b0 | 2009-09-18 21:45:54 | [diff] [blame] | 184 | |
[email protected] | 2735e369 | 2009-09-25 18:19:39 | [diff] [blame] | 185 | // Propagate the following switches to the plugin command line (along with |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 186 | // any associated values) if present in the browser command line |
[email protected] | 4f08c83f | 2010-07-29 23:02:34 | [diff] [blame] | 187 | static const char* const kSwitchNames[] = { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 188 | switches::kDisableBreakpad, |
[email protected] | dc51d1c | 2011-11-30 04:42:21 | [diff] [blame] | 189 | #if defined(OS_MACOSX) |
[email protected] | 89ac531b | 2012-06-28 05:35:16 | [diff] [blame] | 190 | switches::kDisableCoreAnimationPlugins, |
[email protected] | 172ca98 | 2012-10-03 19:55:07 | [diff] [blame] | 191 | switches::kEnableSandboxLogging, |
| 192 | #endif |
[email protected] | 4500a72 | 2009-03-27 19:56:54 | [diff] [blame] | 193 | switches::kEnableStatsTable, |
[email protected] | b1f172a7 | 2011-04-11 17:26:07 | [diff] [blame] | 194 | switches::kFullMemoryCrashReport, |
| 195 | switches::kLoggingLevel, |
[email protected] | b1f172a7 | 2011-04-11 17:26:07 | [diff] [blame] | 196 | switches::kLogPluginMessages, |
[email protected] | b1f172a7 | 2011-04-11 17:26:07 | [diff] [blame] | 197 | switches::kNoSandbox, |
| 198 | switches::kPluginStartupDialog, |
[email protected] | b1f172a7 | 2011-04-11 17:26:07 | [diff] [blame] | 199 | switches::kTestSandbox, |
[email protected] | 50f3842 | 2011-11-09 19:21:33 | [diff] [blame] | 200 | switches::kTraceStartup, |
[email protected] | b1f172a7 | 2011-04-11 17:26:07 | [diff] [blame] | 201 | switches::kUseGL, |
| 202 | switches::kUserAgent, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 203 | }; |
| 204 | |
[email protected] | 4f08c83f | 2010-07-29 23:02:34 | [diff] [blame] | 205 | cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, |
| 206 | arraysize(kSwitchNames)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 207 | |
[email protected] | 89ac531b | 2012-06-28 05:35:16 | [diff] [blame] | 208 | GpuDataManagerImpl::GetInstance()->AppendPluginCommandLine(cmd_line); |
| 209 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 210 | // If specified, prepend a launcher program to the command line. |
[email protected] | e5e19c3 | 2009-04-20 22:10:02 | [diff] [blame] | 211 | if (!plugin_launcher.empty()) |
[email protected] | fb1277e8 | 2009-11-21 20:32:30 | [diff] [blame] | 212 | cmd_line->PrependWrapper(plugin_launcher); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 213 | |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 214 | std::string locale = GetContentClient()->browser()->GetApplicationLocale(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 215 | 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] | f77d8762 | 2010-07-30 17:43:17 | [diff] [blame] | 218 | cmd_line->AppendSwitchASCII(switches::kLang, locale); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 219 | } |
| 220 | |
[email protected] | 4734d0b | 2011-12-03 07:10:44 | [diff] [blame] | 221 | cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 222 | |
[email protected] | 2456c57 | 2009-11-09 04:21:51 | [diff] [blame] | 223 | #if defined(OS_POSIX) |
[email protected] | a82af39 | 2012-02-24 04:40:20 | [diff] [blame] | 224 | base::EnvironmentVector env; |
[email protected] | 23563dc1e | 2010-02-16 16:11:00 | [diff] [blame] | 225 | #if defined(OS_MACOSX) && !defined(__LP64__) |
[email protected] | 097d4ed | 2012-10-22 16:37:54 | [diff] [blame] | 226 | if (!browser_command_line.HasSwitch(switches::kDisableCarbonInterposing)) { |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 227 | std::string interpose_list = GetContentClient()->GetCarbonInterposePath(); |
[email protected] | 097d4ed | 2012-10-22 16:37:54 | [diff] [blame] | 228 | 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] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 231 | const char* existing_list = getenv(kDYLDInsertLibrariesKey); |
[email protected] | 097d4ed | 2012-10-22 16:37:54 | [diff] [blame] | 232 | if (existing_list) { |
| 233 | interpose_list.insert(0, ":"); |
| 234 | interpose_list.insert(0, existing_list); |
| 235 | } |
[email protected] | 69211e8c | 2012-07-23 22:20:41 | [diff] [blame] | 236 | } |
[email protected] | 097d4ed | 2012-10-22 16:37:54 | [diff] [blame] | 237 | env.push_back(std::pair<std::string, std::string>( |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 238 | kDYLDInsertLibrariesKey, interpose_list)); |
[email protected] | f3ef7b1 | 2009-08-07 22:03:17 | [diff] [blame] | 239 | } |
[email protected] | fb1277e8 | 2009-11-21 20:32:30 | [diff] [blame] | 240 | #endif |
| 241 | #endif |
| 242 | |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 243 | process_->Launch( |
[email protected] | fb1277e8 | 2009-11-21 20:32:30 | [diff] [blame] | 244 | #if defined(OS_WIN) |
[email protected] | a15eb4a | 2013-03-21 21:33:38 | [diff] [blame] | 245 | new PluginSandboxedProcessLauncherDelegate, |
[email protected] | fb1277e8 | 2009-11-21 20:32:30 | [diff] [blame] | 246 | #elif defined(OS_POSIX) |
[email protected] | 7c4ea14 | 2010-01-26 05:15:42 | [diff] [blame] | 247 | false, |
[email protected] | fb1277e8 | 2009-11-21 20:32:30 | [diff] [blame] | 248 | env, |
| 249 | #endif |
| 250 | cmd_line); |
| 251 | |
[email protected] | 358cb8e | 2011-05-25 02:12:45 | [diff] [blame] | 252 | // 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] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 256 | process_->SetTerminateChildOnShutdown(false); |
[email protected] | 358cb8e | 2011-05-25 02:12:45 | [diff] [blame] | 257 | |
[email protected] | fb1277e8 | 2009-11-21 20:32:30 | [diff] [blame] | 258 | return true; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 259 | } |
[email protected] | fb1277e8 | 2009-11-21 20:32:30 | [diff] [blame] | 260 | |
[email protected] | 4e59e81 | 2010-04-06 20:51:16 | [diff] [blame] | 261 | void PluginProcessHost::ForceShutdown() { |
[email protected] | f8b3ef8 | 2010-10-11 02:45:52 | [diff] [blame] | 262 | DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
[email protected] | 4e59e81 | 2010-04-06 20:51:16 | [diff] [blame] | 263 | Send(new PluginProcessMsg_NotifyRenderersOfPendingShutdown()); |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 264 | process_->ForceShutdown(); |
[email protected] | 4e59e81 | 2010-04-06 20:51:16 | [diff] [blame] | 265 | } |
| 266 | |
[email protected] | 4cb4310 | 2011-12-02 20:24:49 | [diff] [blame] | 267 | void PluginProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 268 | process_->GetHost()->AddFilter(filter); |
[email protected] | 4cb4310 | 2011-12-02 20:24:49 | [diff] [blame] | 269 | } |
| 270 | |
[email protected] | a95986a8 | 2010-12-24 06:19:28 | [diff] [blame] | 271 | bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { |
| 272 | bool handled = true; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 273 | IPC_BEGIN_MESSAGE_MAP(PluginProcessHost, msg) |
| 274 | IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ChannelCreated, OnChannelCreated) |
[email protected] | 3e076a8 | 2012-09-11 19:12:36 | [diff] [blame] | 275 | #if defined(OS_WIN) |
[email protected] | 875d489 | 2009-04-21 21:48:36 | [diff] [blame] | 276 | IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginWindowDestroyed, |
| 277 | OnPluginWindowDestroyed) |
[email protected] | 829c284 | 2009-04-01 01:48:52 | [diff] [blame] | 278 | #endif |
[email protected] | a13283cc | 2012-04-05 00:21:22 | [diff] [blame] | 279 | #if defined(TOOLKIT_GTK) |
[email protected] | 700d3d5 | 2009-07-07 17:40:46 | [diff] [blame] | 280 | IPC_MESSAGE_HANDLER(PluginProcessHostMsg_MapNativeViewId, |
| 281 | OnMapNativeViewId) |
| 282 | #endif |
[email protected] | 1d5ac66 | 2009-10-01 19:41:56 | [diff] [blame] | 283 | #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] | 18db4618 | 2010-02-02 17:04:55 | [diff] [blame] | 290 | IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginSetCursorVisibility, |
| 291 | OnPluginSetCursorVisibility) |
[email protected] | 1d5ac66 | 2009-10-01 19:41:56 | [diff] [blame] | 292 | #endif |
[email protected] | a95986a8 | 2010-12-24 06:19:28 | [diff] [blame] | 293 | IPC_MESSAGE_UNHANDLED(handled = false) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 294 | IPC_END_MESSAGE_MAP() |
[email protected] | a95986a8 | 2010-12-24 06:19:28 | [diff] [blame] | 295 | |
| 296 | DCHECK(handled); |
| 297 | return handled; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 298 | } |
| 299 | |
| 300 | void PluginProcessHost::OnChannelConnected(int32 peer_pid) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 301 | for (size_t i = 0; i < pending_requests_.size(); ++i) { |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 302 | RequestPluginChannel(pending_requests_[i]); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 303 | } |
| 304 | |
| 305 | pending_requests_.clear(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 306 | } |
| 307 | |
| 308 | void PluginProcessHost::OnChannelError() { |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 309 | CancelRequests(); |
| 310 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 311 | |
[email protected] | ddb1e5a | 2010-12-13 20:10:45 | [diff] [blame] | 312 | bool PluginProcessHost::CanShutdown() { |
| 313 | return sent_requests_.empty(); |
| 314 | } |
| 315 | |
[email protected] | 47214d88 | 2012-02-29 06:28:48 | [diff] [blame] | 316 | void PluginProcessHost::OnProcessCrashed(int exit_code) { |
| 317 | PluginServiceImpl::GetInstance()->RegisterPluginCrash(info_.path); |
| 318 | } |
| 319 | |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 320 | void PluginProcessHost::CancelRequests() { |
| 321 | for (size_t i = 0; i < pending_requests_.size(); ++i) |
| 322 | pending_requests_[i]->OnError(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 323 | pending_requests_.clear(); |
[email protected] | a3a8fb6d | 2009-10-22 20:12:51 | [diff] [blame] | 324 | |
| 325 | while (!sent_requests_.empty()) { |
[email protected] | 8d32d5f | 2011-09-15 02:22:32 | [diff] [blame] | 326 | Client* client = sent_requests_.front(); |
| 327 | if (client) |
| 328 | client->OnError(); |
[email protected] | 4befe759 | 2011-09-14 22:49:09 | [diff] [blame] | 329 | sent_requests_.pop_front(); |
[email protected] | a3a8fb6d | 2009-10-22 20:12:51 | [diff] [blame] | 330 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 331 | } |
| 332 | |
[email protected] | 1a5acea8 | 2011-09-12 11:00:21 | [diff] [blame] | 333 | // static |
| 334 | void PluginProcessHost::CancelPendingRequestsForResourceContext( |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 335 | ResourceContext* context) { |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 336 | for (PluginProcessHostIterator host_it; !host_it.Done(); ++host_it) { |
| 337 | PluginProcessHost* host = *host_it; |
[email protected] | 1a5acea8 | 2011-09-12 11:00:21 | [diff] [blame] | 338 | for (size_t i = 0; i < host->pending_requests_.size(); ++i) { |
[email protected] | df02aca | 2012-02-09 21:03:20 | [diff] [blame] | 339 | if (host->pending_requests_[i]->GetResourceContext() == context) { |
[email protected] | 1a5acea8 | 2011-09-12 11:00:21 | [diff] [blame] | 340 | host->pending_requests_[i]->OnError(); |
| 341 | host->pending_requests_.erase(host->pending_requests_.begin() + i); |
| 342 | --i; |
| 343 | } |
| 344 | } |
| 345 | } |
| 346 | } |
| 347 | |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 348 | void PluginProcessHost::OpenChannelToPlugin(Client* client) { |
[email protected] | f4eaf7b9 | 2013-02-28 22:00:40 | [diff] [blame] | 349 | BrowserThread::PostTask( |
| 350 | BrowserThread::UI, FROM_HERE, |
| 351 | base::Bind(&BrowserChildProcessHostImpl::NotifyProcessInstanceCreated, |
| 352 | process_->GetData())); |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 353 | client->SetPluginInfo(info_); |
[email protected] | 4967f79 | 2012-01-20 22:14:40 | [diff] [blame] | 354 | if (process_->GetHost()->IsChannelOpening()) { |
[email protected] | d2e884d | 2009-06-22 20:37:52 | [diff] [blame] | 355 | // 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] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 358 | pending_requests_.push_back(client); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 359 | return; |
| 360 | } |
| 361 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 362 | // We already have an open channel, send a request right away to plugin. |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 363 | RequestPluginChannel(client); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 364 | } |
| 365 | |
[email protected] | 4befe759 | 2011-09-14 22:49:09 | [diff] [blame] | 366 | void 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 | |
| 378 | void 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] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 390 | void PluginProcessHost::RequestPluginChannel(Client* client) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 391 | // 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] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 396 | PluginProcessMsg_CreateChannel* msg = |
[email protected] | d5a1916 | 2011-06-30 18:51:54 | [diff] [blame] | 397 | new PluginProcessMsg_CreateChannel( |
| 398 | client->ID(), |
| 399 | client->OffTheRecord()); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 400 | msg->set_unblock(true); |
| 401 | if (Send(msg)) { |
[email protected] | 4befe759 | 2011-09-14 22:49:09 | [diff] [blame] | 402 | sent_requests_.push_back(client); |
| 403 | client->OnSentPluginChannelRequest(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 404 | } else { |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 405 | client->OnError(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 406 | } |
| 407 | } |
| 408 | |
[email protected] | 3dfc7a4 | 2009-06-27 01:43:51 | [diff] [blame] | 409 | void PluginProcessHost::OnChannelCreated( |
| 410 | const IPC::ChannelHandle& channel_handle) { |
[email protected] | 46b69e4 | 2010-11-02 12:26:39 | [diff] [blame] | 411 | Client* client = sent_requests_.front(); |
[email protected] | 3dfc7a4 | 2009-06-27 01:43:51 | [diff] [blame] | 412 | |
[email protected] | 4befe759 | 2011-09-14 22:49:09 | [diff] [blame] | 413 | if (client) |
| 414 | client->OnChannelOpened(channel_handle); |
| 415 | sent_requests_.pop_front(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 416 | } |
[email protected] | 13075767 | 2012-10-24 00:26:19 | [diff] [blame] | 417 | |
| 418 | } // namespace content |