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 "chrome_frame/chrome_frame_automation.h" | 5 #include "chrome_frame/chrome_frame_automation.h" |
6 | 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" |
7 #include "base/callback.h" | 9 #include "base/callback.h" |
8 #include "base/command_line.h" | 10 #include "base/command_line.h" |
9 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
10 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
11 #include "base/file_util.h" | 13 #include "base/file_util.h" |
12 #include "base/file_version_info.h" | 14 #include "base/file_version_info.h" |
13 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
14 #include "base/logging.h" | 16 #include "base/logging.h" |
15 #include "base/path_service.h" | 17 #include "base/path_service.h" |
16 #include "base/process_util.h" | 18 #include "base/process_util.h" |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 launch_milliseconds << " ms."; | 191 launch_milliseconds << " ms."; |
190 } | 192 } |
191 } | 193 } |
192 | 194 |
193 base::Time launch_time_begin_; | 195 base::Time launch_time_begin_; |
194 #else | 196 #else |
195 void Dump() {} | 197 void Dump() {} |
196 #endif | 198 #endif |
197 }; | 199 }; |
198 | 200 |
199 DISABLE_RUNNABLE_METHOD_REFCOUNT(AutomationProxyCacheEntry); | |
200 | |
201 AutomationProxyCacheEntry::AutomationProxyCacheEntry( | 201 AutomationProxyCacheEntry::AutomationProxyCacheEntry( |
202 ChromeFrameLaunchParams* params, LaunchDelegate* delegate) | 202 ChromeFrameLaunchParams* params, LaunchDelegate* delegate) |
203 : profile_name(params->profile_name()), | 203 : profile_name(params->profile_name()), |
204 launch_result_(AUTOMATION_LAUNCH_RESULT_INVALID) { | 204 launch_result_(AUTOMATION_LAUNCH_RESULT_INVALID) { |
205 DCHECK(delegate); | 205 DCHECK(delegate); |
206 thread_.reset(new base::Thread(WideToASCII(profile_name).c_str())); | 206 thread_.reset(new base::Thread(WideToASCII(profile_name).c_str())); |
207 thread_->Start(); | 207 thread_->Start(); |
208 // Use scoped_refptr so that the params will get released when the task | 208 // Use scoped_refptr so that the params will get released when the task |
209 // has been run. | 209 // has been run. |
210 scoped_refptr<ChromeFrameLaunchParams> ref_params(params); | 210 scoped_refptr<ChromeFrameLaunchParams> ref_params(params); |
211 thread_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, | 211 thread_->message_loop()->PostTask( |
212 &AutomationProxyCacheEntry::CreateProxy, ref_params, delegate)); | 212 FROM_HERE, base::Bind(&AutomationProxyCacheEntry::CreateProxy, |
| 213 base::Unretained(this), ref_params, delegate)); |
213 } | 214 } |
214 | 215 |
215 AutomationProxyCacheEntry::~AutomationProxyCacheEntry() { | 216 AutomationProxyCacheEntry::~AutomationProxyCacheEntry() { |
216 DVLOG(1) << __FUNCTION__ << profile_name; | 217 DVLOG(1) << __FUNCTION__ << profile_name; |
217 // Attempt to fix chrome_frame_tests crash seen at times on the IE6/IE7 | 218 // Attempt to fix chrome_frame_tests crash seen at times on the IE6/IE7 |
218 // builders. It appears that there are cases when we can enter here when the | 219 // builders. It appears that there are cases when we can enter here when the |
219 // AtExitManager is tearing down the global ProxyCache which causes a crash | 220 // AtExitManager is tearing down the global ProxyCache which causes a crash |
220 // while tearing down the AutomationProxy object due to a NULL MessageLoop | 221 // while tearing down the AutomationProxy object due to a NULL MessageLoop |
221 // The AutomationProxy class uses the SyncChannel which assumes the existence | 222 // The AutomationProxy class uses the SyncChannel which assumes the existence |
222 // of a MessageLoop instance. | 223 // of a MessageLoop instance. |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 | 403 |
403 void AutomationProxyCacheEntry::OnChannelError() { | 404 void AutomationProxyCacheEntry::OnChannelError() { |
404 DCHECK(IsSameThread(base::PlatformThread::CurrentId())); | 405 DCHECK(IsSameThread(base::PlatformThread::CurrentId())); |
405 launch_result_ = AUTOMATION_SERVER_CRASHED; | 406 launch_result_ = AUTOMATION_SERVER_CRASHED; |
406 LaunchDelegates::const_iterator it = launch_delegates_.begin(); | 407 LaunchDelegates::const_iterator it = launch_delegates_.begin(); |
407 for (; it != launch_delegates_.end(); ++it) { | 408 for (; it != launch_delegates_.end(); ++it) { |
408 (*it)->AutomationServerDied(); | 409 (*it)->AutomationServerDied(); |
409 } | 410 } |
410 } | 411 } |
411 | 412 |
412 DISABLE_RUNNABLE_METHOD_REFCOUNT(ProxyFactory); | |
413 | |
414 ProxyFactory::ProxyFactory() { | 413 ProxyFactory::ProxyFactory() { |
415 } | 414 } |
416 | 415 |
417 ProxyFactory::~ProxyFactory() { | 416 ProxyFactory::~ProxyFactory() { |
418 for (size_t i = 0; i < proxies_.container().size(); ++i) { | 417 for (size_t i = 0; i < proxies_.container().size(); ++i) { |
419 DWORD result = proxies_[i]->WaitForThread(0); | 418 DWORD result = proxies_[i]->WaitForThread(0); |
420 if (WAIT_OBJECT_0 != result) | 419 if (WAIT_OBJECT_0 != result) |
421 // TODO(stoyan): Don't leak proxies on exit. | 420 // TODO(stoyan): Don't leak proxies on exit. |
422 DLOG(ERROR) << "Proxies leaked on exit."; | 421 DLOG(ERROR) << "Proxies leaked on exit."; |
423 } | 422 } |
(...skipping 14 matching lines...) Expand all Loading... |
438 } | 437 } |
439 } | 438 } |
440 | 439 |
441 if (entry == NULL) { | 440 if (entry == NULL) { |
442 DVLOG(1) << __FUNCTION__ << " creating new proxy entry"; | 441 DVLOG(1) << __FUNCTION__ << " creating new proxy entry"; |
443 entry = new AutomationProxyCacheEntry(params, delegate); | 442 entry = new AutomationProxyCacheEntry(params, delegate); |
444 proxies_.container().push_back(entry); | 443 proxies_.container().push_back(entry); |
445 } else if (delegate) { | 444 } else if (delegate) { |
446 // Notify the new delegate of the launch status from the worker thread | 445 // Notify the new delegate of the launch status from the worker thread |
447 // and add it to the list of delegates. | 446 // and add it to the list of delegates. |
448 entry->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(entry.get(), | 447 entry->message_loop()->PostTask( |
449 &AutomationProxyCacheEntry::AddDelegate, delegate)); | 448 FROM_HERE, base::Bind(&AutomationProxyCacheEntry::AddDelegate, |
| 449 base::Unretained(entry.get()), delegate)); |
450 } | 450 } |
451 | 451 |
452 DCHECK(automation_server_id != NULL); | 452 DCHECK(automation_server_id != NULL); |
453 DCHECK(!entry->IsSameThread(base::PlatformThread::CurrentId())); | 453 DCHECK(!entry->IsSameThread(base::PlatformThread::CurrentId())); |
454 | 454 |
455 *automation_server_id = entry; | 455 *automation_server_id = entry; |
456 } | 456 } |
457 | 457 |
458 bool ProxyFactory::ReleaseAutomationServer(void* server_id, | 458 bool ProxyFactory::ReleaseAutomationServer(void* server_id, |
459 LaunchDelegate* delegate) { | 459 LaunchDelegate* delegate) { |
(...skipping 16 matching lines...) Expand all Loading... |
476 lock_.Release(); | 476 lock_.Release(); |
477 #endif | 477 #endif |
478 | 478 |
479 // AddRef the entry object as we might need to take it out of the proxy | 479 // AddRef the entry object as we might need to take it out of the proxy |
480 // stack and then uninitialize the entry. | 480 // stack and then uninitialize the entry. |
481 entry->AddRef(); | 481 entry->AddRef(); |
482 | 482 |
483 bool last_delegate = false; | 483 bool last_delegate = false; |
484 if (delegate) { | 484 if (delegate) { |
485 base::WaitableEvent done(true, false); | 485 base::WaitableEvent done(true, false); |
486 entry->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(entry, | 486 entry->message_loop()->PostTask( |
487 &AutomationProxyCacheEntry::RemoveDelegate, delegate, &done, | 487 FROM_HERE, |
488 &last_delegate)); | 488 base::Bind(&AutomationProxyCacheEntry::RemoveDelegate, |
| 489 base::Unretained(entry), delegate, &done, &last_delegate)); |
489 done.Wait(); | 490 done.Wait(); |
490 } | 491 } |
491 | 492 |
492 if (last_delegate) { | 493 if (last_delegate) { |
493 lock_.Acquire(); | 494 lock_.Acquire(); |
494 Vector::ContainerType::iterator it = std::find(proxies_.container().begin(), | 495 Vector::ContainerType::iterator it = std::find(proxies_.container().begin(), |
495 proxies_.container().end(), | 496 proxies_.container().end(), |
496 entry); | 497 entry); |
497 proxies_.container().erase(it); | 498 proxies_.container().erase(it); |
498 lock_.Release(); | 499 lock_.Release(); |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 new AutomationMsg_ConnectExternalTab(external_tab_cookie_, true, | 876 new AutomationMsg_ConnectExternalTab(external_tab_cookie_, true, |
876 m_hWnd, NULL, NULL, NULL, 0); | 877 m_hWnd, NULL, NULL, NULL, 0); |
877 automation_server_->SendAsAsync(message, | 878 automation_server_->SendAsAsync(message, |
878 new CreateExternalTabContext(this), | 879 new CreateExternalTabContext(this), |
879 this); | 880 this); |
880 DVLOG(1) << __FUNCTION__ << ": sending CreateExternalTabComplete"; | 881 DVLOG(1) << __FUNCTION__ << ": sending CreateExternalTabComplete"; |
881 } | 882 } |
882 } | 883 } |
883 } else { | 884 } else { |
884 // Launch failed. Note, we cannot delete proxy here. | 885 // Launch failed. Note, we cannot delete proxy here. |
885 PostTask(FROM_HERE, NewRunnableMethod(this, | 886 PostTask(FROM_HERE, |
886 &ChromeFrameAutomationClient::InitializeComplete, result)); | 887 base::Bind(&ChromeFrameAutomationClient::InitializeComplete, this, |
| 888 result)); |
887 } | 889 } |
888 } | 890 } |
889 | 891 |
890 void ChromeFrameAutomationClient::AutomationServerDied() { | 892 void ChromeFrameAutomationClient::AutomationServerDied() { |
891 // Make sure we notify our delegate. | 893 // Make sure we notify our delegate. |
892 PostTask(FROM_HERE, NewRunnableMethod(this, | 894 PostTask( |
893 &ChromeFrameAutomationClient::InitializeComplete, | 895 FROM_HERE, |
894 AUTOMATION_SERVER_CRASHED)); | 896 base::Bind(&ChromeFrameAutomationClient::InitializeComplete, this, |
| 897 AUTOMATION_SERVER_CRASHED)); |
895 // Then uninitialize. | 898 // Then uninitialize. |
896 PostTask(FROM_HERE, NewRunnableMethod(this, | 899 PostTask( |
897 &ChromeFrameAutomationClient::Uninitialize)); | 900 FROM_HERE, base::Bind(&ChromeFrameAutomationClient::Uninitialize, this)); |
898 } | 901 } |
899 | 902 |
900 void ChromeFrameAutomationClient::InitializeComplete( | 903 void ChromeFrameAutomationClient::InitializeComplete( |
901 AutomationLaunchResult result) { | 904 AutomationLaunchResult result) { |
902 DCHECK_EQ(base::PlatformThread::CurrentId(), ui_thread_id_); | 905 DCHECK_EQ(base::PlatformThread::CurrentId(), ui_thread_id_); |
903 if (result != AUTOMATION_SUCCESS) { | 906 if (result != AUTOMATION_SUCCESS) { |
904 DLOG(WARNING) << "InitializeComplete: failure " << result; | 907 DLOG(WARNING) << "InitializeComplete: failure " << result; |
905 ReleaseAutomationServer(); | 908 ReleaseAutomationServer(); |
906 } else { | 909 } else { |
907 init_state_ = INITIALIZED; | 910 init_state_ = INITIALIZED; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 case AutomationMsg_SetCookieAsync::ID: | 990 case AutomationMsg_SetCookieAsync::ID: |
988 if (ui_thread || (url_fetcher_flags_ & | 991 if (ui_thread || (url_fetcher_flags_ & |
989 PluginUrlRequestManager::COOKIE_REQUEST_THREADSAFE)) { | 992 PluginUrlRequestManager::COOKIE_REQUEST_THREADSAFE)) { |
990 AutomationMsg_SetCookieAsync::Dispatch(&msg, url_fetcher_, this, | 993 AutomationMsg_SetCookieAsync::Dispatch(&msg, url_fetcher_, this, |
991 &PluginUrlRequestManager::SetCookiesInHost); | 994 &PluginUrlRequestManager::SetCookiesInHost); |
992 return true; | 995 return true; |
993 } | 996 } |
994 break; | 997 break; |
995 } | 998 } |
996 | 999 |
997 PostTask(FROM_HERE, NewRunnableMethod(this, | 1000 PostTask(FROM_HERE, |
998 &ChromeFrameAutomationClient::ProcessUrlRequestMessage, tab, msg, true)); | 1001 base::Bind(&ChromeFrameAutomationClient::ProcessUrlRequestMessage, |
| 1002 this, tab, msg, true)); |
999 return true; | 1003 return true; |
1000 } | 1004 } |
1001 | 1005 |
1002 // These are invoked in channel's background thread. | 1006 // These are invoked in channel's background thread. |
1003 // Cannot call any method of the activex here since it is a STA kind of being. | 1007 // Cannot call any method of the activex here since it is a STA kind of being. |
1004 // By default we marshal the IPC message to the main/GUI thread and from there | 1008 // By default we marshal the IPC message to the main/GUI thread and from there |
1005 // we safely invoke chrome_frame_delegate_->OnMessageReceived(msg). | 1009 // we safely invoke chrome_frame_delegate_->OnMessageReceived(msg). |
1006 bool ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab, | 1010 bool ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab, |
1007 const IPC::Message& msg) { | 1011 const IPC::Message& msg) { |
1008 DCHECK(tab == tab_.get()); | 1012 DCHECK(tab == tab_.get()); |
1009 // Quickly process network related messages. | 1013 // Quickly process network related messages. |
1010 if (url_fetcher_ && ProcessUrlRequestMessage(tab, msg, false)) | 1014 if (url_fetcher_ && ProcessUrlRequestMessage(tab, msg, false)) |
1011 return true; | 1015 return true; |
1012 | 1016 |
1013 // Early check to avoid needless marshaling | 1017 // Early check to avoid needless marshaling |
1014 if (chrome_frame_delegate_ == NULL) | 1018 if (chrome_frame_delegate_ == NULL) |
1015 return false; | 1019 return false; |
1016 | 1020 |
1017 PostTask(FROM_HERE, NewRunnableMethod(this, | 1021 PostTask(FROM_HERE, |
1018 &ChromeFrameAutomationClient::OnMessageReceivedUIThread, msg)); | 1022 base::Bind(&ChromeFrameAutomationClient::OnMessageReceivedUIThread, |
| 1023 this, msg)); |
1019 return true; | 1024 return true; |
1020 } | 1025 } |
1021 | 1026 |
1022 void ChromeFrameAutomationClient::OnChannelError(TabProxy* tab) { | 1027 void ChromeFrameAutomationClient::OnChannelError(TabProxy* tab) { |
1023 DCHECK(tab == tab_.get()); | 1028 DCHECK(tab == tab_.get()); |
1024 // Early check to avoid needless marshaling | 1029 // Early check to avoid needless marshaling |
1025 if (chrome_frame_delegate_ == NULL) | 1030 if (chrome_frame_delegate_ == NULL) |
1026 return; | 1031 return; |
1027 | 1032 |
1028 PostTask(FROM_HERE, NewRunnableMethod(this, | 1033 PostTask( |
1029 &ChromeFrameAutomationClient::OnChannelErrorUIThread)); | 1034 FROM_HERE, |
| 1035 base::Bind(&ChromeFrameAutomationClient::OnChannelErrorUIThread, this)); |
1030 } | 1036 } |
1031 | 1037 |
1032 void ChromeFrameAutomationClient::OnMessageReceivedUIThread( | 1038 void ChromeFrameAutomationClient::OnMessageReceivedUIThread( |
1033 const IPC::Message& msg) { | 1039 const IPC::Message& msg) { |
1034 DCHECK_EQ(base::PlatformThread::CurrentId(), ui_thread_id_); | 1040 DCHECK_EQ(base::PlatformThread::CurrentId(), ui_thread_id_); |
1035 // Forward to the delegate. | 1041 // Forward to the delegate. |
1036 if (chrome_frame_delegate_) | 1042 if (chrome_frame_delegate_) |
1037 chrome_frame_delegate_->OnMessageReceived(msg); | 1043 chrome_frame_delegate_->OnMessageReceived(msg); |
1038 } | 1044 } |
1039 | 1045 |
(...skipping 11 matching lines...) Expand all Loading... |
1051 | 1057 |
1052 void ChromeFrameAutomationClient::ReportNavigationError( | 1058 void ChromeFrameAutomationClient::ReportNavigationError( |
1053 AutomationMsg_NavigationResponseValues error_code, | 1059 AutomationMsg_NavigationResponseValues error_code, |
1054 const std::string& url) { | 1060 const std::string& url) { |
1055 if (!chrome_frame_delegate_) | 1061 if (!chrome_frame_delegate_) |
1056 return; | 1062 return; |
1057 | 1063 |
1058 if (ui_thread_id_ == base::PlatformThread::CurrentId()) { | 1064 if (ui_thread_id_ == base::PlatformThread::CurrentId()) { |
1059 chrome_frame_delegate_->OnLoadFailed(error_code, url); | 1065 chrome_frame_delegate_->OnLoadFailed(error_code, url); |
1060 } else { | 1066 } else { |
1061 PostTask(FROM_HERE, NewRunnableMethod(this, | 1067 PostTask(FROM_HERE, |
1062 &ChromeFrameAutomationClient::ReportNavigationError, | 1068 base::Bind(&ChromeFrameAutomationClient::ReportNavigationError, |
1063 error_code, url)); | 1069 this, error_code, url)); |
1064 } | 1070 } |
1065 } | 1071 } |
1066 | 1072 |
1067 void ChromeFrameAutomationClient::Resize(int width, int height, | 1073 void ChromeFrameAutomationClient::Resize(int width, int height, |
1068 int flags) { | 1074 int flags) { |
1069 if (tab_.get() && ::IsWindow(chrome_window())) { | 1075 if (tab_.get() && ::IsWindow(chrome_window())) { |
1070 SetWindowPos(HWND_TOP, 0, 0, width, height, flags); | 1076 SetWindowPos(HWND_TOP, 0, 0, width, height, flags); |
1071 tab_->Reposition(chrome_window(), HWND_TOP, 0, 0, width, height, | 1077 tab_->Reposition(chrome_window(), HWND_TOP, 0, 0, width, height, |
1072 flags, m_hWnd); | 1078 flags, m_hWnd); |
1073 } | 1079 } |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 const net::URLRequestStatus& status) { | 1272 const net::URLRequestStatus& status) { |
1267 automation_server_->Send(new AutomationMsg_RequestEnd( | 1273 automation_server_->Send(new AutomationMsg_RequestEnd( |
1268 tab_->handle(), request_id, status)); | 1274 tab_->handle(), request_id, status)); |
1269 } | 1275 } |
1270 | 1276 |
1271 void ChromeFrameAutomationClient::OnCookiesRetrieved(bool success, | 1277 void ChromeFrameAutomationClient::OnCookiesRetrieved(bool success, |
1272 const GURL& url, const std::string& cookie_string, int cookie_id) { | 1278 const GURL& url, const std::string& cookie_string, int cookie_id) { |
1273 automation_server_->Send(new AutomationMsg_GetCookiesHostResponse( | 1279 automation_server_->Send(new AutomationMsg_GetCookiesHostResponse( |
1274 tab_->handle(), success, url, cookie_string, cookie_id)); | 1280 tab_->handle(), success, url, cookie_string, cookie_id)); |
1275 } | 1281 } |
OLD | NEW |