OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #include "chrome/browser/plugin_process_host.h" | 7 #include "chrome/browser/plugin_process_host.h" |
8 | 8 |
9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
10 #include <windows.h> | 10 #include <windows.h> |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 } | 262 } |
263 #else | 263 #else |
264 // TODO(port): Send the file data to the caller. | 264 // TODO(port): Send the file data to the caller. |
265 NOTIMPLEMENTED(); | 265 NOTIMPLEMENTED(); |
266 #endif | 266 #endif |
267 | 267 |
268 // Don't access any members after this. | 268 // Don't access any members after this. |
269 delete this; | 269 delete this; |
270 } | 270 } |
271 | 271 |
| 272 #if defined(OS_WIN) |
272 // Sends the reply to the create window message on the IO thread. | 273 // Sends the reply to the create window message on the IO thread. |
273 class SendReplyTask : public Task { | 274 class SendReplyTask : public Task { |
274 public: | 275 public: |
275 SendReplyTask(FilePath plugin_path, IPC::Message* reply_msg) | 276 SendReplyTask(FilePath plugin_path, HWND window, IPC::Message* reply_msg) |
276 : plugin_path_(plugin_path), reply_msg_(reply_msg) { } | 277 : plugin_path_(plugin_path), |
| 278 reply_msg_(reply_msg), |
| 279 window_(window){ } |
277 | 280 |
278 virtual void Run() { | 281 virtual void Run() { |
279 PluginProcessHost* plugin = | 282 PluginProcessHost* plugin = |
280 PluginService::GetInstance()->FindPluginProcess(plugin_path_); | 283 PluginService::GetInstance()->FindPluginProcess(plugin_path_); |
281 if (!plugin) | 284 if (!plugin) |
282 return; | 285 return; |
283 | 286 |
| 287 plugin->AddWindow(window_); |
284 plugin->Send(reply_msg_); | 288 plugin->Send(reply_msg_); |
285 } | 289 } |
286 | 290 |
287 private: | 291 private: |
288 FilePath plugin_path_; | 292 FilePath plugin_path_; |
289 IPC::Message* reply_msg_; | 293 IPC::Message* reply_msg_; |
| 294 HWND window_; |
290 }; | 295 }; |
291 | 296 |
292 #if defined(OS_WIN) | |
293 | |
294 // Creates a child window of the given HWND on the UI thread. | 297 // Creates a child window of the given HWND on the UI thread. |
295 class CreateWindowTask : public Task { | 298 class CreateWindowTask : public Task { |
296 public: | 299 public: |
297 CreateWindowTask( | 300 CreateWindowTask( |
298 FilePath plugin_path, HWND parent, IPC::Message* reply_msg) | 301 FilePath plugin_path, HWND parent, IPC::Message* reply_msg) |
299 : plugin_path_(plugin_path), parent_(parent), reply_msg_(reply_msg) { } | 302 : plugin_path_(plugin_path), parent_(parent), reply_msg_(reply_msg) { } |
300 | 303 |
301 virtual void Run() { | 304 virtual void Run() { |
302 static ATOM window_class = 0; | 305 static ATOM window_class = 0; |
303 if (!window_class) { | 306 if (!window_class) { |
(...skipping 17 matching lines...) Expand all Loading... |
321 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, | 324 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, |
322 MAKEINTATOM(window_class), 0, | 325 MAKEINTATOM(window_class), 0, |
323 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, | 326 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, |
324 0, 0, 0, 0, parent_, 0, GetModuleHandle(NULL), 0); | 327 0, 0, 0, 0, parent_, 0, GetModuleHandle(NULL), 0); |
325 TRACK_HWND_CREATION(window); | 328 TRACK_HWND_CREATION(window); |
326 | 329 |
327 PluginProcessHostMsg_CreateWindow::WriteReplyParams( | 330 PluginProcessHostMsg_CreateWindow::WriteReplyParams( |
328 reply_msg_, window); | 331 reply_msg_, window); |
329 | 332 |
330 g_browser_process->io_thread()->message_loop()->PostTask( | 333 g_browser_process->io_thread()->message_loop()->PostTask( |
331 FROM_HERE, new SendReplyTask(plugin_path_, reply_msg_)); | 334 FROM_HERE, new SendReplyTask(plugin_path_, window, reply_msg_)); |
332 } | 335 } |
333 | 336 |
334 private: | 337 private: |
335 FilePath plugin_path_; | 338 FilePath plugin_path_; |
336 HWND parent_; | 339 HWND parent_; |
337 IPC::Message* reply_msg_; | 340 IPC::Message* reply_msg_; |
338 }; | 341 }; |
339 | 342 |
340 // Destroys the given window on the UI thread. | |
341 class DestroyWindowTask : public Task { | |
342 public: | |
343 explicit DestroyWindowTask(HWND window) : window_(window) { } | |
344 | |
345 virtual void Run() { | |
346 DestroyWindow(window_); | |
347 TRACK_HWND_DESTRUCTION(window_); | |
348 } | |
349 | |
350 private: | |
351 HWND window_; | |
352 }; | |
353 | |
354 void PluginProcessHost::OnCreateWindow(HWND parent, | 343 void PluginProcessHost::OnCreateWindow(HWND parent, |
355 IPC::Message* reply_msg) { | 344 IPC::Message* reply_msg) { |
356 // Need to create this window on the UI thread. | 345 // Need to create this window on the UI thread. |
357 PluginService::GetInstance()->main_message_loop()->PostTask( | 346 PluginService::GetInstance()->main_message_loop()->PostTask( |
358 FROM_HERE, new CreateWindowTask(info_.path, parent, reply_msg)); | 347 FROM_HERE, new CreateWindowTask(info_.path, parent, reply_msg)); |
359 } | 348 } |
360 | 349 |
361 void PluginProcessHost::OnDestroyWindow(HWND window) { | 350 void PluginProcessHost::OnDestroyWindow(HWND window) { |
362 PluginService::GetInstance()->main_message_loop()->PostTask( | 351 std::set<HWND>::iterator window_index = |
363 FROM_HERE, new DestroyWindowTask(window)); | 352 plugin_parent_windows_set_.find(window); |
| 353 if (window_index != plugin_parent_windows_set_.end()) { |
| 354 plugin_parent_windows_set_.erase(window_index); |
| 355 } |
| 356 |
| 357 PostMessage(window, WM_CLOSE, 0, 0); |
| 358 } |
| 359 |
| 360 void PluginProcessHost::AddWindow(HWND window) { |
| 361 plugin_parent_windows_set_.insert(window); |
364 } | 362 } |
365 | 363 |
366 #endif // defined(OS_WIN) | 364 #endif // defined(OS_WIN) |
367 | 365 |
368 PluginProcessHost::PluginProcessHost(MessageLoop* main_message_loop) | 366 PluginProcessHost::PluginProcessHost(MessageLoop* main_message_loop) |
369 : ChildProcessHost(PLUGIN_PROCESS, main_message_loop), | 367 : ChildProcessHost(PLUGIN_PROCESS, main_message_loop), |
370 ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) { | 368 ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) { |
371 } | 369 } |
372 | 370 |
373 PluginProcessHost::~PluginProcessHost() { | 371 PluginProcessHost::~PluginProcessHost() { |
374 // Cancel all requests for plugin processes. | 372 // Cancel all requests for plugin processes. |
375 // TODO(mpcomplete): use a real process ID when http://b/issue?id=1210062 is | 373 // TODO(mpcomplete): use a real process ID when http://b/issue?id=1210062 is |
376 // fixed. | 374 // fixed. |
377 PluginService::GetInstance()->resource_dispatcher_host()-> | 375 PluginService::GetInstance()->resource_dispatcher_host()-> |
378 CancelRequestsForProcess(-1); | 376 CancelRequestsForProcess(-1); |
| 377 |
| 378 #if defined(OS_WIN) |
| 379 // We erase HWNDs from the plugin_parent_windows_set_ when we receive a |
| 380 // notification that the window is being destroyed. If we don't receive this |
| 381 // notification and the PluginProcessHost instance is being destroyed, it |
| 382 // means that the plugin process crashed. We paint a sad face in this case in |
| 383 // the renderer process. To ensure that the sad face shows up, and we don't |
| 384 // leak HWNDs, we should destroy existing plugin parent windows. |
| 385 std::set<HWND>::iterator window_index; |
| 386 for (window_index = plugin_parent_windows_set_.begin(); |
| 387 window_index != plugin_parent_windows_set_.end(); |
| 388 window_index++) { |
| 389 PostMessage(*window_index, WM_CLOSE, 0, 0); |
| 390 } |
| 391 #endif |
379 } | 392 } |
380 | 393 |
381 bool PluginProcessHost::Init(const WebPluginInfo& info, | 394 bool PluginProcessHost::Init(const WebPluginInfo& info, |
382 const std::string& activex_clsid, | 395 const std::string& activex_clsid, |
383 const std::wstring& locale) { | 396 const std::wstring& locale) { |
384 info_ = info; | 397 info_ = info; |
385 set_name(info_.name); | 398 set_name(info_.name); |
386 | 399 |
387 if (!CreateChannel()) | 400 if (!CreateChannel()) |
388 return false; | 401 return false; |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 } | 804 } |
792 | 805 |
793 void PluginProcessHost::Shutdown() { | 806 void PluginProcessHost::Shutdown() { |
794 #if defined(OS_WIN) | 807 #if defined(OS_WIN) |
795 Send(new PluginProcessMsg_BrowserShutdown); | 808 Send(new PluginProcessMsg_BrowserShutdown); |
796 #else | 809 #else |
797 // TODO(port): Port plugin_messages_internal.h. | 810 // TODO(port): Port plugin_messages_internal.h. |
798 NOTIMPLEMENTED(); | 811 NOTIMPLEMENTED(); |
799 #endif | 812 #endif |
800 } | 813 } |
OLD | NEW |