OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
14 #include "base/file_version_info.h" | 14 #include "base/file_version_info.h" |
15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/metrics/field_trial.h" | |
18 #include "base/path_service.h" | 17 #include "base/path_service.h" |
19 #include "base/process_util.h" | 18 #include "base/process_util.h" |
20 #include "base/string_util.h" | 19 #include "base/string_util.h" |
21 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
22 #include "base/synchronization/waitable_event.h" | 21 #include "base/synchronization/waitable_event.h" |
23 #include "base/sys_info.h" | 22 #include "base/sys_info.h" |
24 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
25 #include "chrome/app/client_util.h" | 24 #include "chrome/app/client_util.h" |
26 #include "chrome/common/automation_messages.h" | 25 #include "chrome/common/automation_messages.h" |
27 #include "chrome/common/chrome_constants.h" | 26 #include "chrome/common/chrome_constants.h" |
28 #include "chrome/common/chrome_switches.h" | 27 #include "chrome/common/chrome_switches.h" |
29 #include "chrome/test/automation/tab_proxy.h" | 28 #include "chrome/test/automation/tab_proxy.h" |
30 #include "chrome_frame/chrome_launcher_utils.h" | 29 #include "chrome_frame/chrome_launcher_utils.h" |
31 #include "chrome_frame/crash_reporting/crash_metrics.h" | 30 #include "chrome_frame/crash_reporting/crash_metrics.h" |
32 #include "chrome_frame/custom_sync_call_context.h" | 31 #include "chrome_frame/custom_sync_call_context.h" |
33 #include "chrome_frame/navigation_constraints.h" | 32 #include "chrome_frame/navigation_constraints.h" |
34 #include "chrome_frame/simple_resource_loader.h" | 33 #include "chrome_frame/simple_resource_loader.h" |
35 #include "chrome_frame/utils.h" | 34 #include "chrome_frame/utils.h" |
36 #include "ui/base/ui_base_switches.h" | 35 #include "ui/base/ui_base_switches.h" |
37 | 36 |
38 namespace { | 37 namespace { |
39 | 38 |
40 #ifdef NDEBUG | 39 #ifdef NDEBUG |
41 int64 kAutomationServerReasonableLaunchDelay = 1000; // in milliseconds | 40 int64 kAutomationServerReasonableLaunchDelay = 1000; // in milliseconds |
42 #else | 41 #else |
43 int64 kAutomationServerReasonableLaunchDelay = 1000 * 10; | 42 int64 kAutomationServerReasonableLaunchDelay = 1000 * 10; |
44 #endif | 43 #endif |
45 | 44 |
46 const char kChromeShutdownDelaySeconds[] = "30"; | |
47 const char kWithDelayFieldTrialName[] = "WithShutdownDelay"; | |
48 const char kNoDelayFieldTrialName[] = "NoShutdownDelay"; | |
49 | |
50 } // namespace | 45 } // namespace |
51 | 46 |
52 class ChromeFrameAutomationProxyImpl::TabProxyNotificationMessageFilter | 47 class ChromeFrameAutomationProxyImpl::TabProxyNotificationMessageFilter |
53 : public IPC::ChannelProxy::MessageFilter { | 48 : public IPC::ChannelProxy::MessageFilter { |
54 public: | 49 public: |
55 explicit TabProxyNotificationMessageFilter(AutomationHandleTracker* tracker) | 50 explicit TabProxyNotificationMessageFilter(AutomationHandleTracker* tracker) |
56 : tracker_(tracker) { | 51 : tracker_(tracker) { |
57 } | 52 } |
58 | 53 |
59 void AddTabProxy(AutomationHandle tab_proxy) { | 54 void AddTabProxy(AutomationHandle tab_proxy) { |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 // In headless mode runs like reliability test runs we want full crash dumps | 290 // In headless mode runs like reliability test runs we want full crash dumps |
296 // from chrome. | 291 // from chrome. |
297 if (IsHeadlessMode()) | 292 if (IsHeadlessMode()) |
298 command_line->AppendSwitch(switches::kFullMemoryCrashReport); | 293 command_line->AppendSwitch(switches::kFullMemoryCrashReport); |
299 | 294 |
300 // In accessible mode automation tests expect renderer accessibility to be | 295 // In accessible mode automation tests expect renderer accessibility to be |
301 // enabled in chrome. | 296 // enabled in chrome. |
302 if (IsAccessibleMode()) | 297 if (IsAccessibleMode()) |
303 command_line->AppendSwitch(switches::kForceRendererAccessibility); | 298 command_line->AppendSwitch(switches::kForceRendererAccessibility); |
304 | 299 |
305 if (params->send_shutdown_delay_switch()) | |
306 command_line->AppendSwitchASCII(switches::kChromeFrameShutdownDelay, | |
307 kChromeShutdownDelaySeconds); | |
308 | |
309 DVLOG(1) << "Profile path: " << params->profile_path().value(); | 300 DVLOG(1) << "Profile path: " << params->profile_path().value(); |
310 command_line->AppendSwitchPath(switches::kUserDataDir, | 301 command_line->AppendSwitchPath(switches::kUserDataDir, |
311 params->profile_path()); | 302 params->profile_path()); |
312 | 303 |
313 // Ensure that Chrome is running the specified version of chrome.dll. | 304 // Ensure that Chrome is running the specified version of chrome.dll. |
314 command_line->AppendSwitchNative(switches::kChromeVersion, | 305 command_line->AppendSwitchNative(switches::kChromeVersion, |
315 GetCurrentModuleVersion()); | 306 GetCurrentModuleVersion()); |
316 | 307 |
317 if (!params->language().empty()) | 308 if (!params->language().empty()) |
318 command_line->AppendSwitchNative(switches::kLang, params->language()); | 309 command_line->AppendSwitchNative(switches::kLang, params->language()); |
(...skipping 24 matching lines...) Expand all Loading... |
343 // version string it reported. | 334 // version string it reported. |
344 launch_result_ = proxy->WaitForAppLaunch(); | 335 launch_result_ = proxy->WaitForAppLaunch(); |
345 launch_stats.Dump(); | 336 launch_stats.Dump(); |
346 | 337 |
347 base::TimeDelta delta = | 338 base::TimeDelta delta = |
348 base::TimeTicks::Now() - automation_server_launch_start_time_; | 339 base::TimeTicks::Now() - automation_server_launch_start_time_; |
349 | 340 |
350 if (launch_result_ == AUTOMATION_SUCCESS) { | 341 if (launch_result_ == AUTOMATION_SUCCESS) { |
351 UMA_HISTOGRAM_TIMES( | 342 UMA_HISTOGRAM_TIMES( |
352 "ChromeFrame.AutomationServerLaunchSuccessTime", delta); | 343 "ChromeFrame.AutomationServerLaunchSuccessTime", delta); |
353 UMA_HISTOGRAM_TIMES( | |
354 base::FieldTrial::MakeName( | |
355 "ChromeFrame.AutomationServerLaunchSuccessTime", | |
356 "ChromeShutdownDelay"), | |
357 delta); | |
358 } else { | 344 } else { |
359 UMA_HISTOGRAM_TIMES( | 345 UMA_HISTOGRAM_TIMES( |
360 "ChromeFrame.AutomationServerLaunchFailedTime", delta); | 346 "ChromeFrame.AutomationServerLaunchFailedTime", delta); |
361 UMA_HISTOGRAM_TIMES( | |
362 base::FieldTrial::MakeName( | |
363 "ChromeFrame.AutomationServerLaunchFailedTime", | |
364 "ChromeShutdownDelay"), | |
365 delta); | |
366 } | 347 } |
367 | 348 |
368 UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.LaunchResult", | 349 UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.LaunchResult", |
369 launch_result_, | 350 launch_result_, |
370 AUTOMATION_SUCCESS, | 351 AUTOMATION_SUCCESS, |
371 AUTOMATION_CREATE_TAB_FAILED, | 352 AUTOMATION_CREATE_TAB_FAILED, |
372 AUTOMATION_CREATE_TAB_FAILED + 1); | 353 AUTOMATION_CREATE_TAB_FAILED + 1); |
373 } | 354 } |
374 | 355 |
375 TRACE_EVENT_END_ETW("chromeframe.createproxy", this, ""); | 356 TRACE_EVENT_END_ETW("chromeframe.createproxy", this, ""); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 init_state_(UNINITIALIZED), | 531 init_state_(UNINITIALIZED), |
551 use_chrome_network_(false), | 532 use_chrome_network_(false), |
552 proxy_factory_(g_proxy_factory.Pointer()), | 533 proxy_factory_(g_proxy_factory.Pointer()), |
553 handle_top_level_requests_(false), | 534 handle_top_level_requests_(false), |
554 tab_handle_(-1), | 535 tab_handle_(-1), |
555 session_id_(-1), | 536 session_id_(-1), |
556 external_tab_cookie_(0), | 537 external_tab_cookie_(0), |
557 url_fetcher_(NULL), | 538 url_fetcher_(NULL), |
558 url_fetcher_flags_(PluginUrlRequestManager::NOT_THREADSAFE), | 539 url_fetcher_flags_(PluginUrlRequestManager::NOT_THREADSAFE), |
559 navigate_after_initialization_(false), | 540 navigate_after_initialization_(false), |
560 route_all_top_level_navigations_(false), | 541 route_all_top_level_navigations_(false) { |
561 send_shutdown_delay_switch_(true) { | |
562 InitializeFieldTrials(); | |
563 } | 542 } |
564 | 543 |
565 ChromeFrameAutomationClient::~ChromeFrameAutomationClient() { | 544 ChromeFrameAutomationClient::~ChromeFrameAutomationClient() { |
566 // Uninitialize must be called prior to the destructor | 545 // Uninitialize must be called prior to the destructor |
567 DCHECK(automation_server_ == NULL); | 546 DCHECK(automation_server_ == NULL); |
568 } | 547 } |
569 | 548 |
570 bool ChromeFrameAutomationClient::Initialize( | 549 bool ChromeFrameAutomationClient::Initialize( |
571 ChromeFrameDelegate* chrome_frame_delegate, | 550 ChromeFrameDelegate* chrome_frame_delegate, |
572 ChromeFrameLaunchParams* chrome_launch_params) { | 551 ChromeFrameLaunchParams* chrome_launch_params) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 // Important: Since we will be using the referrer_ variable from a | 670 // Important: Since we will be using the referrer_ variable from a |
692 // different thread, we need to force a new std::string buffer instance for | 671 // different thread, we need to force a new std::string buffer instance for |
693 // the referrer_ GURL variable. Otherwise we can run into strangeness when | 672 // the referrer_ GURL variable. Otherwise we can run into strangeness when |
694 // the GURL is accessed and it could result in a bad URL that can cause the | 673 // the GURL is accessed and it could result in a bad URL that can cause the |
695 // referrer to be dropped or something worse. | 674 // referrer to be dropped or something worse. |
696 GURL referrer_gurl(referrer.c_str()); | 675 GURL referrer_gurl(referrer.c_str()); |
697 if (!chrome_launch_params_) { | 676 if (!chrome_launch_params_) { |
698 base::FilePath profile_path; | 677 base::FilePath profile_path; |
699 chrome_launch_params_ = new ChromeFrameLaunchParams(parsed_url, | 678 chrome_launch_params_ = new ChromeFrameLaunchParams(parsed_url, |
700 referrer_gurl, profile_path, L"", SimpleResourceLoader::GetLanguage(), | 679 referrer_gurl, profile_path, L"", SimpleResourceLoader::GetLanguage(), |
701 false, false, route_all_top_level_navigations_, | 680 false, false, route_all_top_level_navigations_); |
702 send_shutdown_delay_switch_); | |
703 } else { | 681 } else { |
704 chrome_launch_params_->set_referrer(referrer_gurl); | 682 chrome_launch_params_->set_referrer(referrer_gurl); |
705 chrome_launch_params_->set_url(parsed_url); | 683 chrome_launch_params_->set_url(parsed_url); |
706 } | 684 } |
707 | 685 |
708 navigate_after_initialization_ = false; | 686 navigate_after_initialization_ = false; |
709 | 687 |
710 if (is_initialized()) { | 688 if (is_initialized()) { |
711 BeginNavigate(); | 689 BeginNavigate(); |
712 } else { | 690 } else { |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 | 1008 |
1031 PostTask( | 1009 PostTask( |
1032 FROM_HERE, | 1010 FROM_HERE, |
1033 base::Bind( | 1011 base::Bind( |
1034 base::IgnoreResult( | 1012 base::IgnoreResult( |
1035 &ChromeFrameAutomationClient::ProcessUrlRequestMessage), | 1013 &ChromeFrameAutomationClient::ProcessUrlRequestMessage), |
1036 base::Unretained(this), tab, msg, true)); | 1014 base::Unretained(this), tab, msg, true)); |
1037 return true; | 1015 return true; |
1038 } | 1016 } |
1039 | 1017 |
1040 void ChromeFrameAutomationClient::InitializeFieldTrials() { | |
1041 static base::FieldTrial* trial = NULL; | |
1042 if (!trial) { | |
1043 // Do one-time initialization of the field trial here. | |
1044 // TODO(robertshield): End the field trial before March 7th 2013. | |
1045 scoped_refptr<base::FieldTrial> new_trial = | |
1046 base::FieldTrialList::FactoryGetFieldTrial( | |
1047 "ChromeShutdownDelay", 1000, kWithDelayFieldTrialName, | |
1048 2013, 3, 7, NULL); | |
1049 | |
1050 // Be consistent for this client. Note that this will only have an effect | |
1051 // once the client id is persisted. See http://crbug.com/117188 | |
1052 new_trial->UseOneTimeRandomization(); | |
1053 | |
1054 new_trial->AppendGroup(kNoDelayFieldTrialName, 500); // 50% without. | |
1055 | |
1056 trial = new_trial.get(); | |
1057 } | |
1058 | |
1059 // Take action depending of which group we randomly land in. | |
1060 if (trial->group_name() == kWithDelayFieldTrialName) | |
1061 send_shutdown_delay_switch_ = true; | |
1062 else | |
1063 send_shutdown_delay_switch_ = false; | |
1064 | |
1065 } | |
1066 | |
1067 // These are invoked in channel's background thread. | 1018 // These are invoked in channel's background thread. |
1068 // Cannot call any method of the activex here since it is a STA kind of being. | 1019 // Cannot call any method of the activex here since it is a STA kind of being. |
1069 // By default we marshal the IPC message to the main/GUI thread and from there | 1020 // By default we marshal the IPC message to the main/GUI thread and from there |
1070 // we safely invoke chrome_frame_delegate_->OnMessageReceived(msg). | 1021 // we safely invoke chrome_frame_delegate_->OnMessageReceived(msg). |
1071 bool ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab, | 1022 bool ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab, |
1072 const IPC::Message& msg) { | 1023 const IPC::Message& msg) { |
1073 DCHECK(tab == tab_.get()); | 1024 DCHECK(tab == tab_.get()); |
1074 // Quickly process network related messages. | 1025 // Quickly process network related messages. |
1075 if (url_fetcher_ && ProcessUrlRequestMessage(tab, msg, false)) | 1026 if (url_fetcher_ && ProcessUrlRequestMessage(tab, msg, false)) |
1076 return true; | 1027 return true; |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 const net::URLRequestStatus& status) { | 1287 const net::URLRequestStatus& status) { |
1337 automation_server_->Send(new AutomationMsg_RequestEnd( | 1288 automation_server_->Send(new AutomationMsg_RequestEnd( |
1338 tab_->handle(), request_id, status)); | 1289 tab_->handle(), request_id, status)); |
1339 } | 1290 } |
1340 | 1291 |
1341 void ChromeFrameAutomationClient::OnCookiesRetrieved(bool success, | 1292 void ChromeFrameAutomationClient::OnCookiesRetrieved(bool success, |
1342 const GURL& url, const std::string& cookie_string, int cookie_id) { | 1293 const GURL& url, const std::string& cookie_string, int cookie_id) { |
1343 automation_server_->Send(new AutomationMsg_GetCookiesHostResponse( | 1294 automation_server_->Send(new AutomationMsg_GetCookiesHostResponse( |
1344 tab_->handle(), success, url, cookie_string, cookie_id)); | 1295 tab_->handle(), success, url, cookie_string, cookie_id)); |
1345 } | 1296 } |
OLD | NEW |