diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-21 21:48:36 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-21 21:48:36 +0000 |
commit | 875d489e8aadd251c638c1bad6bb7ca967605f98 (patch) | |
tree | e1be54c561d33b240f6c88b042c9b2df732ac5c6 /chrome/browser/plugin_process_host.cc | |
parent | e3db4fabfc7aabca3cd1998e05d2a769fbd0c5b6 (diff) | |
download | chromium_src-875d489e8aadd251c638c1bad6bb7ca967605f98.zip chromium_src-875d489e8aadd251c638c1bad6bb7ca967605f98.tar.gz chromium_src-875d489e8aadd251c638c1bad6bb7ca967605f98.tar.bz2 |
Fix hang seen in plugin process because plugin creation ended up having to wait on UI thread. Instead of using sync messages, the plugin hwnd is initially parented to the RenderWidgetHost's HWND. It's then lazily reparented to an intermediate HWND on the UI thread when it comes time to move it.
BUG=10711
TEST=added regression tests, but testers please confirm plugins on top video sites are placed correctly.
Review URL: http://codereview.chromium.org/67285
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14137 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/plugin_process_host.cc')
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 97 |
1 files changed, 10 insertions, 87 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 6cea0c7..9ed3dbf 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -254,92 +254,16 @@ void PluginDownloadUrlHelper::DownloadCompletedHelper(bool success) { delete this; } - -// Sends the reply to the create window message on the IO thread. -class SendReplyTask : public Task { - public: - SendReplyTask(FilePath plugin_path, HWND window, IPC::Message* reply_msg) - : plugin_path_(plugin_path), - reply_msg_(reply_msg), - window_(window){ } - - virtual void Run() { - PluginProcessHost* plugin = - PluginService::GetInstance()->FindPluginProcess(plugin_path_); - if (!plugin) - return; - - plugin->AddWindow(window_); - plugin->Send(reply_msg_); - } - - private: - FilePath plugin_path_; - IPC::Message* reply_msg_; - HWND window_; -}; - -// Creates a child window of the given HWND on the UI thread. -class CreateWindowTask : public Task { - public: - CreateWindowTask( - FilePath plugin_path, HWND parent, IPC::Message* reply_msg) - : plugin_path_(plugin_path), parent_(parent), reply_msg_(reply_msg) { } - - virtual void Run() { - static ATOM window_class = 0; - if (!window_class) { - WNDCLASSEX wcex; - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_DBLCLKS; - wcex.lpfnWndProc = DefWindowProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = GetModuleHandle(NULL); - wcex.hIcon = 0; - wcex.hCursor = 0; - wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1); - wcex.lpszMenuName = 0; - wcex.lpszClassName = kWrapperNativeWindowClassName; - wcex.hIconSm = 0; - window_class = RegisterClassEx(&wcex); - } - - HWND window = CreateWindowEx( - WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, - MAKEINTATOM(window_class), 0, - WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - 0, 0, 0, 0, parent_, 0, GetModuleHandle(NULL), 0); - TRACK_HWND_CREATION(window); - - PluginProcessHostMsg_CreateWindow::WriteReplyParams( - reply_msg_, window); - - g_browser_process->io_thread()->message_loop()->PostTask( - FROM_HERE, new SendReplyTask(plugin_path_, window, reply_msg_)); - } - - private: - FilePath plugin_path_; - HWND parent_; - IPC::Message* reply_msg_; -}; - -void PluginProcessHost::OnCreateWindow(HWND parent, - IPC::Message* reply_msg) { - // Need to create this window on the UI thread. - PluginService::GetInstance()->main_message_loop()->PostTask( - FROM_HERE, new CreateWindowTask(info_.path, parent, reply_msg)); -} - -void PluginProcessHost::OnDestroyWindow(HWND window) { +void PluginProcessHost::OnPluginWindowDestroyed(HWND window, HWND parent) { + // The window is destroyed at this point, we just care about its parent, which + // is the intermediate window we created. std::set<HWND>::iterator window_index = - plugin_parent_windows_set_.find(window); - if (window_index != plugin_parent_windows_set_.end()) { - plugin_parent_windows_set_.erase(window_index); - } + plugin_parent_windows_set_.find(parent); + if (window_index == plugin_parent_windows_set_.end()) + return; - PostMessage(window, WM_CLOSE, 0, 0); + plugin_parent_windows_set_.erase(window_index); + PostMessage(parent, WM_CLOSE, 0, 0); } void PluginProcessHost::OnDownloadUrl(const std::string& url, @@ -499,9 +423,8 @@ void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginProcessHostMsg_ResolveProxy, OnResolveProxy) #if defined(OS_WIN) - IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginProcessHostMsg_CreateWindow, - OnCreateWindow) - IPC_MESSAGE_HANDLER(PluginProcessHostMsg_DestroyWindow, OnDestroyWindow) + IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginWindowDestroyed, + OnPluginWindowDestroyed) IPC_MESSAGE_HANDLER(PluginProcessHostMsg_DownloadUrl, OnDownloadUrl) #endif IPC_MESSAGE_UNHANDLED_ERROR() |