| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/file_version_info.h" | 11 #include "base/file_version_info.h" |
| 12 #include "base/lock.h" | 12 #include "base/lock.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 16 #include "base/singleton.h" | 16 #include "base/singleton.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/sys_info.h" | 18 #include "base/sys_info.h" |
| 19 #include "base/waitable_event.h" | 19 #include "base/waitable_event.h" |
| 20 #include "chrome/app/client_util.h" | 20 #include "chrome/app/client_util.h" |
| 21 #include "chrome/common/chrome_constants.h" | 21 #include "chrome/common/chrome_constants.h" |
| 22 #include "chrome/common/chrome_paths.h" |
| 23 #include "chrome/common/chrome_paths_internal.h" |
| 22 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
| 23 #include "chrome/test/automation/tab_proxy.h" | 25 #include "chrome/test/automation/tab_proxy.h" |
| 24 #include "chrome_frame/chrome_launcher.h" | 26 #include "chrome_frame/chrome_launcher.h" |
| 25 #include "chrome_frame/utils.h" | 27 #include "chrome_frame/utils.h" |
| 26 #include "chrome_frame/sync_msg_reply_dispatcher.h" | 28 #include "chrome_frame/sync_msg_reply_dispatcher.h" |
| 27 | 29 |
| 28 #ifdef NDEBUG | 30 #ifdef NDEBUG |
| 29 int64 kAutomationServerReasonableLaunchDelay = 1000; // in milliseconds | 31 int64 kAutomationServerReasonableLaunchDelay = 1000; // in milliseconds |
| 30 #else | 32 #else |
| 31 int64 kAutomationServerReasonableLaunchDelay = 1000 * 10; | 33 int64 kAutomationServerReasonableLaunchDelay = 1000 * 10; |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 command_line->AppendSwitch(switches::kNoErrorDialogs); | 264 command_line->AppendSwitch(switches::kNoErrorDialogs); |
| 263 #endif | 265 #endif |
| 264 | 266 |
| 265 command_line->AppendSwitch(switches::kEnableRendererAccessibility); | 267 command_line->AppendSwitch(switches::kEnableRendererAccessibility); |
| 266 | 268 |
| 267 // In headless mode runs like reliability test runs we want full crash dumps | 269 // In headless mode runs like reliability test runs we want full crash dumps |
| 268 // from chrome. | 270 // from chrome. |
| 269 if (IsHeadlessMode()) | 271 if (IsHeadlessMode()) |
| 270 command_line->AppendSwitch(switches::kFullMemoryCrashReport); | 272 command_line->AppendSwitch(switches::kFullMemoryCrashReport); |
| 271 | 273 |
| 272 DLOG(INFO) << "Profile path: " << params.profile_path.value(); | 274 // Place the profile directory in |
| 273 command_line->AppendSwitchWithValue(switches::kUserDataDir, | 275 // "<chrome_exe_path>\..\User Data\<profile-name>" |
| 274 params.profile_path.value()); | 276 if (!entry->profile_name.empty()) { |
| 277 FilePath profile_path; |
| 278 if (chrome::GetChromeFrameUserDataDirectory(&profile_path)) { |
| 279 profile_path = profile_path.Append(entry->profile_name); |
| 280 command_line->AppendSwitchWithValue(switches::kUserDataDir, |
| 281 profile_path.value()); |
| 282 } else { |
| 283 // Can't get the profile dir :-( We need one to work, so fail. |
| 284 // We have no code for launch failure. |
| 285 entry->launch_result = AutomationLaunchResult(-1); |
| 286 } |
| 287 } |
| 275 | 288 |
| 276 std::wstring command_line_string(command_line->command_line_string()); | 289 std::wstring command_line_string(command_line->command_line_string()); |
| 277 // If there are any extra arguments, append them to the command line. | 290 // If there are any extra arguments, append them to the command line. |
| 278 if (!params.extra_chrome_arguments.empty()) { | 291 if (!params.extra_chrome_arguments.empty()) { |
| 279 command_line_string += L' ' + params.extra_chrome_arguments; | 292 command_line_string += L' ' + params.extra_chrome_arguments; |
| 280 } | 293 } |
| 281 | 294 |
| 282 automation_server_launch_start_time_ = base::TimeTicks::Now(); | 295 automation_server_launch_start_time_ = base::TimeTicks::Now(); |
| 283 | 296 |
| 284 if (!base::LaunchApp(command_line_string, false, false, NULL)) { | 297 if (!base::LaunchApp(command_line_string, false, false, NULL)) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 AUTOMATION_CREATE_TAB_FAILED, | 332 AUTOMATION_CREATE_TAB_FAILED, |
| 320 AUTOMATION_CREATE_TAB_FAILED + 1); | 333 AUTOMATION_CREATE_TAB_FAILED + 1); |
| 321 } | 334 } |
| 322 | 335 |
| 323 // Finally set the proxy. | 336 // Finally set the proxy. |
| 324 entry->proxy = proxy; | 337 entry->proxy = proxy; |
| 325 delegate->LaunchComplete(proxy, entry->launch_result); | 338 delegate->LaunchComplete(proxy, entry->launch_result); |
| 326 } | 339 } |
| 327 | 340 |
| 328 bool ProxyFactory::ReleaseAutomationServer(void* server_id) { | 341 bool ProxyFactory::ReleaseAutomationServer(void* server_id) { |
| 342 DLOG(INFO) << __FUNCTION__; |
| 343 |
| 329 if (!server_id) { | 344 if (!server_id) { |
| 330 NOTREACHED(); | 345 NOTREACHED(); |
| 331 return false; | 346 return false; |
| 332 } | 347 } |
| 333 | 348 |
| 334 ProxyCacheEntry* entry = reinterpret_cast<ProxyCacheEntry*>(server_id); | 349 ProxyCacheEntry* entry = reinterpret_cast<ProxyCacheEntry*>(server_id); |
| 335 | 350 |
| 336 #ifndef NDEBUG | 351 #ifndef NDEBUG |
| 337 lock_.Acquire(); | 352 lock_.Acquire(); |
| 338 Vector::ContainerType::iterator it = std::find(proxies_.container().begin(), | 353 Vector::ContainerType::iterator it = std::find(proxies_.container().begin(), |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 | 450 |
| 436 ChromeFrameAutomationClient::~ChromeFrameAutomationClient() { | 451 ChromeFrameAutomationClient::~ChromeFrameAutomationClient() { |
| 437 // Uninitialize must be called prior to the destructor | 452 // Uninitialize must be called prior to the destructor |
| 438 DCHECK(automation_server_ == NULL); | 453 DCHECK(automation_server_ == NULL); |
| 439 } | 454 } |
| 440 | 455 |
| 441 bool ChromeFrameAutomationClient::Initialize( | 456 bool ChromeFrameAutomationClient::Initialize( |
| 442 ChromeFrameDelegate* chrome_frame_delegate, | 457 ChromeFrameDelegate* chrome_frame_delegate, |
| 443 int automation_server_launch_timeout, | 458 int automation_server_launch_timeout, |
| 444 bool perform_version_check, | 459 bool perform_version_check, |
| 445 const FilePath& profile_path, | 460 const std::wstring& profile_name, |
| 446 const std::wstring& extra_chrome_arguments, | 461 const std::wstring& extra_chrome_arguments, |
| 447 bool incognito) { | 462 bool incognito) { |
| 448 DCHECK(!IsWindow()); | 463 DCHECK(!IsWindow()); |
| 449 chrome_frame_delegate_ = chrome_frame_delegate; | 464 chrome_frame_delegate_ = chrome_frame_delegate; |
| 450 ui_thread_id_ = PlatformThread::CurrentId(); | 465 ui_thread_id_ = PlatformThread::CurrentId(); |
| 451 #ifndef NDEBUG | 466 #ifndef NDEBUG |
| 452 // In debug mode give more time to work with a debugger. | 467 // In debug mode give more time to work with a debugger. |
| 453 if (IsDebuggerPresent()) { | 468 if (IsDebuggerPresent()) { |
| 454 // Don't use INFINITE (which is -1) or even MAXINT since we will convert | 469 // Don't use INFINITE (which is -1) or even MAXINT since we will convert |
| 455 // from milliseconds to microseconds when stored in a base::TimeDelta, | 470 // from milliseconds to microseconds when stored in a base::TimeDelta, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 475 // Keep object in memory, while the window is alive. | 490 // Keep object in memory, while the window is alive. |
| 476 // Corresponsing Release is in OnFinalMessage(); | 491 // Corresponsing Release is in OnFinalMessage(); |
| 477 AddRef(); | 492 AddRef(); |
| 478 | 493 |
| 479 // Mark our state as initializing. We'll reach initialized once | 494 // Mark our state as initializing. We'll reach initialized once |
| 480 // InitializeComplete is called successfully. | 495 // InitializeComplete is called successfully. |
| 481 init_state_ = INITIALIZING; | 496 init_state_ = INITIALIZING; |
| 482 | 497 |
| 483 chrome_launch_params_.automation_server_launch_timeout = | 498 chrome_launch_params_.automation_server_launch_timeout = |
| 484 automation_server_launch_timeout; | 499 automation_server_launch_timeout; |
| 485 chrome_launch_params_.profile_path = profile_path; | 500 chrome_launch_params_.profile_name = profile_name; |
| 486 chrome_launch_params_.profile_name = profile_path.BaseName().value(); | |
| 487 chrome_launch_params_.extra_chrome_arguments = extra_chrome_arguments; | 501 chrome_launch_params_.extra_chrome_arguments = extra_chrome_arguments; |
| 488 chrome_launch_params_.perform_version_check = perform_version_check; | 502 chrome_launch_params_.perform_version_check = perform_version_check; |
| 489 chrome_launch_params_.url = navigate_after_initialization_ ? GURL() : url_; | 503 chrome_launch_params_.url = navigate_after_initialization_ ? GURL() : url_; |
| 490 chrome_launch_params_.incognito_mode = incognito; | 504 chrome_launch_params_.incognito_mode = incognito; |
| 491 | 505 |
| 492 proxy_factory_->GetAutomationServer( | 506 proxy_factory_->GetAutomationServer( |
| 493 static_cast<ProxyFactory::LaunchDelegate*>(this), | 507 static_cast<ProxyFactory::LaunchDelegate*>(this), |
| 494 chrome_launch_params_, &automation_server_id_); | 508 chrome_launch_params_, &automation_server_id_); |
| 495 | 509 |
| 496 return true; | 510 return true; |
| 497 } | 511 } |
| 498 | 512 |
| 499 void ChromeFrameAutomationClient::Uninitialize() { | 513 void ChromeFrameAutomationClient::Uninitialize() { |
| 514 DLOG(INFO) << __FUNCTION__; |
| 515 |
| 500 if (init_state_ == UNINITIALIZED) { | 516 if (init_state_ == UNINITIALIZED) { |
| 501 DLOG(WARNING) << __FUNCTION__ << ": Automation client not initialized"; | 517 DLOG(WARNING) << __FUNCTION__ << ": Automation client not initialized"; |
| 502 return; | 518 return; |
| 503 } | 519 } |
| 504 | 520 |
| 505 init_state_ = UNINITIALIZING; | 521 init_state_ = UNINITIALIZING; |
| 506 | 522 |
| 507 // Called from client's FinalRelease() / destructor | 523 // Called from client's FinalRelease() / destructor |
| 508 // ChromeFrameAutomationClient may wait for the initialization (launch) | 524 // ChromeFrameAutomationClient may wait for the initialization (launch) |
| 509 // to complete while Uninitialize is called. | 525 // to complete while Uninitialize is called. |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 // Continue with Initialization - Create external tab | 923 // Continue with Initialization - Create external tab |
| 908 CreateExternalTab(); | 924 CreateExternalTab(); |
| 909 } else { | 925 } else { |
| 910 // Send a notification to Chrome that we are ready to connect to the | 926 // Send a notification to Chrome that we are ready to connect to the |
| 911 // ExternalTab. | 927 // ExternalTab. |
| 912 IPC::SyncMessage* message = | 928 IPC::SyncMessage* message = |
| 913 new AutomationMsg_ConnectExternalTab(0, external_tab_cookie_, true, | 929 new AutomationMsg_ConnectExternalTab(0, external_tab_cookie_, true, |
| 914 NULL, NULL, NULL); | 930 NULL, NULL, NULL); |
| 915 automation_server_->SendAsAsync(message, NewCallback(this, | 931 automation_server_->SendAsAsync(message, NewCallback(this, |
| 916 &ChromeFrameAutomationClient::CreateExternalTabComplete), this); | 932 &ChromeFrameAutomationClient::CreateExternalTabComplete), this); |
| 917 DLOG(INFO) << __FUNCTION__ << ": sending CreateExternalTabComplete"; | |
| 918 } | 933 } |
| 919 } | 934 } |
| 920 } else { | 935 } else { |
| 921 // Launch failed. Note, we cannot delete proxy here. | 936 // Launch failed. Note, we cannot delete proxy here. |
| 922 PostTask(FROM_HERE, NewRunnableMethod(this, | 937 PostTask(FROM_HERE, NewRunnableMethod(this, |
| 923 &ChromeFrameAutomationClient::InitializeComplete, result)); | 938 &ChromeFrameAutomationClient::InitializeComplete, result)); |
| 924 } | 939 } |
| 925 } | 940 } |
| 926 | 941 |
| 927 void ChromeFrameAutomationClient::InitializeComplete( | 942 void ChromeFrameAutomationClient::InitializeComplete( |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 ::GetClientRect(parent_window, &parent_client_rect); | 1092 ::GetClientRect(parent_window, &parent_client_rect); |
| 1078 int width = parent_client_rect.right - parent_client_rect.left; | 1093 int width = parent_client_rect.right - parent_client_rect.left; |
| 1079 int height = parent_client_rect.bottom - parent_client_rect.top; | 1094 int height = parent_client_rect.bottom - parent_client_rect.top; |
| 1080 | 1095 |
| 1081 Resize(width, height, SWP_SHOWWINDOW | SWP_NOZORDER); | 1096 Resize(width, height, SWP_SHOWWINDOW | SWP_NOZORDER); |
| 1082 } | 1097 } |
| 1083 } | 1098 } |
| 1084 } | 1099 } |
| 1085 | 1100 |
| 1086 void ChromeFrameAutomationClient::ReleaseAutomationServer() { | 1101 void ChromeFrameAutomationClient::ReleaseAutomationServer() { |
| 1102 DLOG(INFO) << __FUNCTION__; |
| 1087 if (automation_server_id_) { | 1103 if (automation_server_id_) { |
| 1088 // Cache the server id and clear the automation_server_id_ before | 1104 // Cache the server id and clear the automation_server_id_ before |
| 1089 // calling ReleaseAutomationServer. The reason we do this is that | 1105 // calling ReleaseAutomationServer. The reason we do this is that |
| 1090 // we must cancel pending messages before we release the automation server. | 1106 // we must cancel pending messages before we release the automation server. |
| 1091 // Furthermore, while ReleaseAutomationServer is running, we could get | 1107 // Furthermore, while ReleaseAutomationServer is running, we could get |
| 1092 // a callback to LaunchComplete which is where we normally get our pointer | 1108 // a callback to LaunchComplete which is where we normally get our pointer |
| 1093 // to the automation server and there we check the server id for NULLness | 1109 // to the automation server and there we check the server id for NULLness |
| 1094 // and do nothing if it is NULL. | 1110 // and do nothing if it is NULL. |
| 1095 void* server_id = automation_server_id_; | 1111 void* server_id = automation_server_id_; |
| 1096 automation_server_id_ = NULL; | 1112 automation_server_id_ = NULL; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 font_size > LARGEST_FONT) { | 1210 font_size > LARGEST_FONT) { |
| 1195 NOTREACHED() << "Invalid font size specified : " | 1211 NOTREACHED() << "Invalid font size specified : " |
| 1196 << font_size; | 1212 << font_size; |
| 1197 return; | 1213 return; |
| 1198 } | 1214 } |
| 1199 | 1215 |
| 1200 automation_server_->Send( | 1216 automation_server_->Send( |
| 1201 new AutomationMsg_SetPageFontSize(0, tab_handle_, font_size)); | 1217 new AutomationMsg_SetPageFontSize(0, tab_handle_, font_size)); |
| 1202 } | 1218 } |
| 1203 | 1219 |
| 1204 void ChromeFrameAutomationClient::RemoveBrowsingData(int remove_mask) { | |
| 1205 automation_server_->Send( | |
| 1206 new AutomationMsg_RemoveBrowsingData(0, remove_mask)); | |
| 1207 } | |
| 1208 | 1220 |
| 1209 ////////////////////////////////////////////////////////////////////////// | 1221 ////////////////////////////////////////////////////////////////////////// |
| 1210 // PluginUrlRequestDelegate implementation. | 1222 // PluginUrlRequestDelegate implementation. |
| 1211 // Forward network related responses to Chrome. | 1223 // Forward network related responses to Chrome. |
| 1212 | 1224 |
| 1213 void ChromeFrameAutomationClient::OnResponseStarted(int request_id, | 1225 void ChromeFrameAutomationClient::OnResponseStarted(int request_id, |
| 1214 const char* mime_type, const char* headers, int size, | 1226 const char* mime_type, const char* headers, int size, |
| 1215 base::Time last_modified, const std::string& redirect_url, | 1227 base::Time last_modified, const std::string& redirect_url, |
| 1216 int redirect_status) { | 1228 int redirect_status) { |
| 1217 const IPC::AutomationURLResponse response = { | 1229 const IPC::AutomationURLResponse response = { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1233 automation_server_->Send(new AutomationMsg_RequestData(0, tab_->handle(), | 1245 automation_server_->Send(new AutomationMsg_RequestData(0, tab_->handle(), |
| 1234 request_id, data)); | 1246 request_id, data)); |
| 1235 } | 1247 } |
| 1236 | 1248 |
| 1237 void ChromeFrameAutomationClient::OnResponseEnd(int request_id, | 1249 void ChromeFrameAutomationClient::OnResponseEnd(int request_id, |
| 1238 const URLRequestStatus& status) { | 1250 const URLRequestStatus& status) { |
| 1239 automation_server_->Send(new AutomationMsg_RequestEnd(0, tab_->handle(), | 1251 automation_server_->Send(new AutomationMsg_RequestEnd(0, tab_->handle(), |
| 1240 request_id, status)); | 1252 request_id, status)); |
| 1241 } | 1253 } |
| 1242 | 1254 |
| OLD | NEW |