OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/plugin_process_host.h" | 5 #include "content/browser/plugin_process_host.h" |
6 | 6 |
7 #if defined(OS_WIN) && !defined(USE_AURA) | 7 #if defined(OS_WIN) && !defined(USE_AURA) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
10 #include <utility> // for pair<> | 10 #include <utility> // for pair<> |
11 #endif | 11 #endif |
12 | 12 |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "base/base_switches.h" | 15 #include "base/base_switches.h" |
16 #include "base/bind.h" | 16 #include "base/bind.h" |
17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
18 #include "base/file_path.h" | 18 #include "base/file_path.h" |
19 #include "base/file_util.h" | 19 #include "base/file_util.h" |
20 #include "base/logging.h" | 20 #include "base/logging.h" |
21 #include "base/path_service.h" | 21 #include "base/path_service.h" |
22 #include "base/string_util.h" | 22 #include "base/string_util.h" |
23 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
| 24 #include "content/browser/browser_child_process_host.h" |
24 #include "content/browser/plugin_service_impl.h" | 25 #include "content/browser/plugin_service_impl.h" |
25 #include "content/common/child_process_host_impl.h" | 26 #include "content/common/child_process_host_impl.h" |
26 #include "content/common/plugin_messages.h" | 27 #include "content/common/plugin_messages.h" |
27 #include "content/common/resource_messages.h" | 28 #include "content/common/resource_messages.h" |
28 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
29 #include "content/public/browser/content_browser_client.h" | 30 #include "content/public/browser/content_browser_client.h" |
30 #include "content/public/browser/notification_types.h" | 31 #include "content/public/browser/notification_types.h" |
31 #include "content/public/common/content_switches.h" | 32 #include "content/public/common/content_switches.h" |
32 #include "content/public/common/process_type.h" | 33 #include "content/public/common/process_type.h" |
33 #include "ipc/ipc_switches.h" | 34 #include "ipc/ipc_switches.h" |
34 #include "ui/base/ui_base_switches.h" | 35 #include "ui/base/ui_base_switches.h" |
35 #include "ui/gfx/gl/gl_switches.h" | 36 #include "ui/gfx/gl/gl_switches.h" |
36 #include "ui/gfx/native_widget_types.h" | 37 #include "ui/gfx/native_widget_types.h" |
37 | 38 |
38 using content::BrowserThread; | 39 using content::BrowserThread; |
| 40 using content::ChildProcessData; |
39 using content::ChildProcessHost; | 41 using content::ChildProcessHost; |
40 | 42 |
41 #if defined(USE_X11) | 43 #if defined(USE_X11) |
42 #include "ui/gfx/gtk_native_view_id_manager.h" | 44 #include "ui/gfx/gtk_native_view_id_manager.h" |
43 #endif | 45 #endif |
44 | 46 |
45 #if defined(OS_MACOSX) | 47 #if defined(OS_MACOSX) |
46 #include "base/mac/mac_util.h" | 48 #include "base/mac/mac_util.h" |
47 #include "content/common/plugin_carbon_interpose_constants_mac.h" | 49 #include "content/common/plugin_carbon_interpose_constants_mac.h" |
48 #include "ui/gfx/rect.h" | 50 #include "ui/gfx/rect.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 } | 86 } |
85 | 87 |
86 void PluginProcessHost::AddWindow(HWND window) { | 88 void PluginProcessHost::AddWindow(HWND window) { |
87 plugin_parent_windows_set_.insert(window); | 89 plugin_parent_windows_set_.insert(window); |
88 } | 90 } |
89 | 91 |
90 void PluginProcessHost::OnReparentPluginWindow(HWND window, HWND parent) { | 92 void PluginProcessHost::OnReparentPluginWindow(HWND window, HWND parent) { |
91 // Reparent only from the plugin process to our process. | 93 // Reparent only from the plugin process to our process. |
92 DWORD process_id = 0; | 94 DWORD process_id = 0; |
93 ::GetWindowThreadProcessId(window, &process_id); | 95 ::GetWindowThreadProcessId(window, &process_id); |
94 if (process_id != ::GetProcessId(GetChildProcessHandle())) | 96 if (process_id != ::GetProcessId(process_->GetHandle())) |
95 return; | 97 return; |
96 ::GetWindowThreadProcessId(parent, &process_id); | 98 ::GetWindowThreadProcessId(parent, &process_id); |
97 if (process_id != ::GetCurrentProcessId()) | 99 if (process_id != ::GetCurrentProcessId()) |
98 return; | 100 return; |
99 | 101 |
100 BrowserThread::PostTask( | 102 BrowserThread::PostTask( |
101 BrowserThread::UI, FROM_HERE, | 103 BrowserThread::UI, FROM_HERE, |
102 base::Bind(ReparentPluginWindowHelper, window, parent)); | 104 base::Bind(ReparentPluginWindowHelper, window, parent)); |
103 } | 105 } |
104 #endif // defined(OS_WIN) | 106 #endif // defined(OS_WIN) |
105 | 107 |
106 #if defined(TOOLKIT_USES_GTK) | 108 #if defined(TOOLKIT_USES_GTK) |
107 void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, | 109 void PluginProcessHost::OnMapNativeViewId(gfx::NativeViewId id, |
108 gfx::PluginWindowHandle* output) { | 110 gfx::PluginWindowHandle* output) { |
109 *output = 0; | 111 *output = 0; |
110 #if !defined(USE_AURA) | 112 #if !defined(USE_AURA) |
111 GtkNativeViewManager::GetInstance()->GetXIDForId(output, id); | 113 GtkNativeViewManager::GetInstance()->GetXIDForId(output, id); |
112 #endif | 114 #endif |
113 } | 115 } |
114 #endif // defined(TOOLKIT_USES_GTK) | 116 #endif // defined(TOOLKIT_USES_GTK) |
115 | 117 |
116 PluginProcessHost::PluginProcessHost() | 118 PluginProcessHost::PluginProcessHost() |
117 : BrowserChildProcessHost(content::PROCESS_TYPE_PLUGIN) | |
118 #if defined(OS_MACOSX) | 119 #if defined(OS_MACOSX) |
119 , plugin_cursor_visible_(true) | 120 : plugin_cursor_visible_(true) |
120 #endif | 121 #endif |
121 { | 122 { |
| 123 process_.reset(new BrowserChildProcessHost( |
| 124 content::PROCESS_TYPE_PLUGIN, this)); |
122 } | 125 } |
123 | 126 |
124 PluginProcessHost::~PluginProcessHost() { | 127 PluginProcessHost::~PluginProcessHost() { |
125 #if defined(OS_WIN) && !defined(USE_AURA) | 128 #if defined(OS_WIN) && !defined(USE_AURA) |
126 // We erase HWNDs from the plugin_parent_windows_set_ when we receive a | 129 // We erase HWNDs from the plugin_parent_windows_set_ when we receive a |
127 // notification that the window is being destroyed. If we don't receive this | 130 // notification that the window is being destroyed. If we don't receive this |
128 // notification and the PluginProcessHost instance is being destroyed, it | 131 // notification and the PluginProcessHost instance is being destroyed, it |
129 // means that the plugin process crashed. We paint a sad face in this case in | 132 // means that the plugin process crashed. We paint a sad face in this case in |
130 // the renderer process. To ensure that the sad face shows up, and we don't | 133 // the renderer process. To ensure that the sad face shows up, and we don't |
131 // leak HWNDs, we should destroy existing plugin parent windows. | 134 // leak HWNDs, we should destroy existing plugin parent windows. |
(...skipping 25 matching lines...) Expand all Loading... |
157 } else { | 160 } else { |
158 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 161 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
159 base::Bind(base::mac::SetCursorVisibility, true)); | 162 base::Bind(base::mac::SetCursorVisibility, true)); |
160 } | 163 } |
161 } | 164 } |
162 #endif | 165 #endif |
163 // Cancel all pending and sent requests. | 166 // Cancel all pending and sent requests. |
164 CancelRequests(); | 167 CancelRequests(); |
165 } | 168 } |
166 | 169 |
| 170 bool PluginProcessHost::Send(IPC::Message* message) { |
| 171 return process_->Send(message); |
| 172 } |
| 173 |
167 bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { | 174 bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { |
168 info_ = info; | 175 info_ = info; |
169 SetName(info_.name); | 176 process_->SetName(info_.name); |
170 | 177 |
171 std::string channel_id = child_process_host()->CreateChannel(); | 178 std::string channel_id = process_->GetHost()->CreateChannel(); |
172 if (channel_id.empty()) | 179 if (channel_id.empty()) |
173 return false; | 180 return false; |
174 | 181 |
175 // Build command line for plugin. When we have a plugin launcher, we can't | 182 // Build command line for plugin. When we have a plugin launcher, we can't |
176 // allow "self" on linux and we need the real file path. | 183 // allow "self" on linux and we need the real file path. |
177 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 184 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
178 CommandLine::StringType plugin_launcher = | 185 CommandLine::StringType plugin_launcher = |
179 browser_command_line.GetSwitchValueNative(switches::kPluginLauncher); | 186 browser_command_line.GetSwitchValueNative(switches::kPluginLauncher); |
180 | 187 |
181 #if defined(OS_MACOSX) | 188 #if defined(OS_MACOSX) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 if (existing_list) { | 258 if (existing_list) { |
252 interpose_list.insert(0, ":"); | 259 interpose_list.insert(0, ":"); |
253 interpose_list.insert(0, existing_list); | 260 interpose_list.insert(0, existing_list); |
254 } | 261 } |
255 env.push_back(std::pair<std::string, std::string>( | 262 env.push_back(std::pair<std::string, std::string>( |
256 plugin_interpose_strings::kDYLDInsertLibrariesKey, | 263 plugin_interpose_strings::kDYLDInsertLibrariesKey, |
257 interpose_list)); | 264 interpose_list)); |
258 #endif | 265 #endif |
259 #endif | 266 #endif |
260 | 267 |
261 Launch( | 268 process_->Launch( |
262 #if defined(OS_WIN) | 269 #if defined(OS_WIN) |
263 FilePath(), | 270 FilePath(), |
264 #elif defined(OS_POSIX) | 271 #elif defined(OS_POSIX) |
265 false, | 272 false, |
266 env, | 273 env, |
267 #endif | 274 #endif |
268 cmd_line); | 275 cmd_line); |
269 | 276 |
270 // The plugin needs to be shutdown gracefully, i.e. NP_Shutdown needs to be | 277 // The plugin needs to be shutdown gracefully, i.e. NP_Shutdown needs to be |
271 // called on the plugin. The plugin process exits when it receives the | 278 // called on the plugin. The plugin process exits when it receives the |
272 // OnChannelError notification indicating that the browser plugin channel has | 279 // OnChannelError notification indicating that the browser plugin channel has |
273 // been destroyed. | 280 // been destroyed. |
274 SetTerminateChildOnShutdown(false); | 281 process_->SetTerminateChildOnShutdown(false); |
275 | 282 |
276 content::GetContentClient()->browser()->PluginProcessHostCreated(this); | 283 content::GetContentClient()->browser()->PluginProcessHostCreated(this); |
277 | 284 |
278 return true; | 285 return true; |
279 } | 286 } |
280 | 287 |
281 void PluginProcessHost::ForceShutdown() { | 288 void PluginProcessHost::ForceShutdown() { |
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 289 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
283 Send(new PluginProcessMsg_NotifyRenderersOfPendingShutdown()); | 290 Send(new PluginProcessMsg_NotifyRenderersOfPendingShutdown()); |
284 BrowserChildProcessHost::ForceShutdown(); | 291 process_->ForceShutdown(); |
285 } | 292 } |
286 | 293 |
287 void PluginProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { | 294 void PluginProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { |
288 child_process_host()->AddFilter(filter); | 295 process_->GetHost()->AddFilter(filter); |
289 } | 296 } |
290 | 297 |
291 bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { | 298 bool PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { |
292 bool handled = true; | 299 bool handled = true; |
293 IPC_BEGIN_MESSAGE_MAP(PluginProcessHost, msg) | 300 IPC_BEGIN_MESSAGE_MAP(PluginProcessHost, msg) |
294 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ChannelCreated, OnChannelCreated) | 301 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ChannelCreated, OnChannelCreated) |
295 #if defined(OS_WIN) && !defined(USE_AURA) | 302 #if defined(OS_WIN) && !defined(USE_AURA) |
296 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginWindowDestroyed, | 303 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginWindowDestroyed, |
297 OnPluginWindowDestroyed) | 304 OnPluginWindowDestroyed) |
298 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ReparentPluginWindow, | 305 IPC_MESSAGE_HANDLER(PluginProcessHostMsg_ReparentPluginWindow, |
(...skipping 14 matching lines...) Expand all Loading... |
313 OnPluginSetCursorVisibility) | 320 OnPluginSetCursorVisibility) |
314 #endif | 321 #endif |
315 IPC_MESSAGE_UNHANDLED(handled = false) | 322 IPC_MESSAGE_UNHANDLED(handled = false) |
316 IPC_END_MESSAGE_MAP() | 323 IPC_END_MESSAGE_MAP() |
317 | 324 |
318 DCHECK(handled); | 325 DCHECK(handled); |
319 return handled; | 326 return handled; |
320 } | 327 } |
321 | 328 |
322 void PluginProcessHost::OnChannelConnected(int32 peer_pid) { | 329 void PluginProcessHost::OnChannelConnected(int32 peer_pid) { |
323 BrowserChildProcessHost::OnChannelConnected(peer_pid); | |
324 for (size_t i = 0; i < pending_requests_.size(); ++i) { | 330 for (size_t i = 0; i < pending_requests_.size(); ++i) { |
325 RequestPluginChannel(pending_requests_[i]); | 331 RequestPluginChannel(pending_requests_[i]); |
326 } | 332 } |
327 | 333 |
328 pending_requests_.clear(); | 334 pending_requests_.clear(); |
329 } | 335 } |
330 | 336 |
331 void PluginProcessHost::OnChannelError() { | 337 void PluginProcessHost::OnChannelError() { |
332 CancelRequests(); | 338 CancelRequests(); |
333 } | 339 } |
(...skipping 11 matching lines...) Expand all Loading... |
345 Client* client = sent_requests_.front(); | 351 Client* client = sent_requests_.front(); |
346 if (client) | 352 if (client) |
347 client->OnError(); | 353 client->OnError(); |
348 sent_requests_.pop_front(); | 354 sent_requests_.pop_front(); |
349 } | 355 } |
350 } | 356 } |
351 | 357 |
352 // static | 358 // static |
353 void PluginProcessHost::CancelPendingRequestsForResourceContext( | 359 void PluginProcessHost::CancelPendingRequestsForResourceContext( |
354 const content::ResourceContext* context) { | 360 const content::ResourceContext* context) { |
355 for (BrowserChildProcessHost::Iterator host_it(content::PROCESS_TYPE_PLUGIN); | 361 for (PluginProcessHostIterator host_it; !host_it.Done(); ++host_it) { |
356 !host_it.Done(); ++host_it) { | 362 PluginProcessHost* host = *host_it; |
357 PluginProcessHost* host = static_cast<PluginProcessHost*>(*host_it); | |
358 for (size_t i = 0; i < host->pending_requests_.size(); ++i) { | 363 for (size_t i = 0; i < host->pending_requests_.size(); ++i) { |
359 if (&host->pending_requests_[i]->GetResourceContext() == context) { | 364 if (&host->pending_requests_[i]->GetResourceContext() == context) { |
360 host->pending_requests_[i]->OnError(); | 365 host->pending_requests_[i]->OnError(); |
361 host->pending_requests_.erase(host->pending_requests_.begin() + i); | 366 host->pending_requests_.erase(host->pending_requests_.begin() + i); |
362 --i; | 367 --i; |
363 } | 368 } |
364 } | 369 } |
365 } | 370 } |
366 } | 371 } |
367 | 372 |
368 void PluginProcessHost::OpenChannelToPlugin(Client* client) { | 373 void PluginProcessHost::OpenChannelToPlugin(Client* client) { |
369 Notify(content::NOTIFICATION_CHILD_INSTANCE_CREATED); | 374 process_->Notify(content::NOTIFICATION_CHILD_INSTANCE_CREATED); |
370 client->SetPluginInfo(info_); | 375 client->SetPluginInfo(info_); |
371 if (child_process_host()->IsChannelOpening()) { | 376 if (process_->GetHost()->IsChannelOpening()) { |
372 // The channel is already in the process of being opened. Put | 377 // The channel is already in the process of being opened. Put |
373 // this "open channel" request into a queue of requests that will | 378 // this "open channel" request into a queue of requests that will |
374 // be run once the channel is open. | 379 // be run once the channel is open. |
375 pending_requests_.push_back(client); | 380 pending_requests_.push_back(client); |
376 return; | 381 return; |
377 } | 382 } |
378 | 383 |
379 // We already have an open channel, send a request right away to plugin. | 384 // We already have an open channel, send a request right away to plugin. |
380 RequestPluginChannel(client); | 385 RequestPluginChannel(client); |
381 } | 386 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 } | 429 } |
425 | 430 |
426 void PluginProcessHost::OnChannelCreated( | 431 void PluginProcessHost::OnChannelCreated( |
427 const IPC::ChannelHandle& channel_handle) { | 432 const IPC::ChannelHandle& channel_handle) { |
428 Client* client = sent_requests_.front(); | 433 Client* client = sent_requests_.front(); |
429 | 434 |
430 if (client) | 435 if (client) |
431 client->OnChannelOpened(channel_handle); | 436 client->OnChannelOpened(channel_handle); |
432 sent_requests_.pop_front(); | 437 sent_requests_.pop_front(); |
433 } | 438 } |
OLD | NEW |