Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: chrome/browser/browser_main.cc

Issue 7634006: Refactor browser_main.cc. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/browser/browser_main.h" 5 #include "chrome/browser/browser_main.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 210
211 #if defined(TOUCH_UI) 211 #if defined(TOUCH_UI)
212 #include "views/touchui/touch_factory.h" 212 #include "views/touchui/touch_factory.h"
213 #endif 213 #endif
214 214
215 namespace net { 215 namespace net {
216 class NetLog; 216 class NetLog;
217 } // namespace net 217 } // namespace net
218 218
219 namespace { 219 namespace {
220 void SetSocketReusePolicy(int warmest_socket_trial_group,
221 const int socket_policy[],
222 int num_groups);
223 } // namespace
224
225 // BrowserMainParts ------------------------------------------------------------
226
227 BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters)
228 : parameters_(parameters),
229 parsed_command_line_(parameters.command_line_) {
230 }
231
232 BrowserMainParts::~BrowserMainParts() {
233 }
234
235 // BrowserMainParts: |EarlyInitialization()| and related -----------------------
236
237 void BrowserMainParts::EarlyInitialization() {
238 PreEarlyInitialization();
239
240 if (parsed_command_line().HasSwitch(switches::kEnableBenchmarking))
241 base::FieldTrial::EnableBenchmarking();
242
243 InitializeSSL();
244
245 if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart))
246 net::SSLConfigService::DisableFalseStart();
247 if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo))
248 net::SSLConfigService::EnableCachedInfo();
249 if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts))
250 net::SSLConfigService::EnableOriginBoundCerts();
251 if (parsed_command_line().HasSwitch(
252 switches::kEnableDNSCertProvenanceChecking)) {
253 net::SSLConfigService::EnableDNSCertProvenanceChecking();
254 }
255
256 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
257 // seem dependent on InitializeSSL().
258 if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen))
259 net::set_tcp_fastopen_enabled(true);
260
261 PostEarlyInitialization();
262 }
263
264 // This will be called after the command-line has been mutated by about:flags
265 MetricsService* BrowserMainParts::SetupMetricsAndFieldTrials(
266 const CommandLine& parsed_command_line,
267 PrefService* local_state) {
268 // Must initialize metrics after labs have been converted into switches,
269 // but before field trials are set up (so that client ID is available for
270 // one-time randomized field trials).
271 MetricsService* metrics = InitializeMetrics(parsed_command_line, local_state);
272
273 // Initialize FieldTrialList to support FieldTrials that use one-time
274 // randomization. The client ID will be empty if the user has not opted
275 // to send metrics.
276 field_trial_list_.reset(new base::FieldTrialList(metrics->GetClientId()));
277
278 SetupFieldTrials(metrics->recording_active(),
279 local_state->IsManagedPreference(
280 prefs::kMaxConnectionsPerProxy));
281
282 // Initialize FieldTrialSynchronizer system. This is a singleton and is used
283 // for posting tasks via NewRunnableMethod. Its deleted when it goes out of
284 // scope. Even though NewRunnableMethod does AddRef and Release, the object
285 // will not be deleted after the Task is executed.
286 field_trial_synchronizer_ = new FieldTrialSynchronizer();
287
288 return metrics;
289 }
290
291 // This is an A/B test for the maximum number of persistent connections per
292 // host. Currently Chrome, Firefox, and IE8 have this value set at 6. Safari
293 // uses 4, and Fasterfox (a plugin for Firefox that supposedly configures it to
294 // run faster) uses 8. We would like to see how much of an effect this value has
295 // on browsing. Too large a value might cause us to run into SYN flood detection
296 // mechanisms.
297 void BrowserMainParts::ConnectionFieldTrial() {
298 const base::FieldTrial::Probability kConnectDivisor = 100;
299 const base::FieldTrial::Probability kConnectProbability = 1; // 1% prob.
300
301 // After June 30, 2011 builds, it will always be in default group.
302 scoped_refptr<base::FieldTrial> connect_trial(
303 new base::FieldTrial(
304 "ConnCountImpact", kConnectDivisor, "conn_count_6", 2011, 6, 30));
305
306 // This (6) is the current default value. Having this group declared here
307 // makes it straightforward to modify |kConnectProbability| such that the same
308 // probability value will be assigned to all the other groups, while
309 // preserving the remainder of the of probability space to the default value.
310 const int connect_6 = connect_trial->kDefaultGroupNumber;
311
312 const int connect_5 = connect_trial->AppendGroup("conn_count_5",
313 kConnectProbability);
314 const int connect_7 = connect_trial->AppendGroup("conn_count_7",
315 kConnectProbability);
316 const int connect_8 = connect_trial->AppendGroup("conn_count_8",
317 kConnectProbability);
318 const int connect_9 = connect_trial->AppendGroup("conn_count_9",
319 kConnectProbability);
320
321 const int connect_trial_group = connect_trial->group();
322
323 if (connect_trial_group == connect_5) {
324 net::ClientSocketPoolManager::set_max_sockets_per_group(5);
325 } else if (connect_trial_group == connect_6) {
326 net::ClientSocketPoolManager::set_max_sockets_per_group(6);
327 } else if (connect_trial_group == connect_7) {
328 net::ClientSocketPoolManager::set_max_sockets_per_group(7);
329 } else if (connect_trial_group == connect_8) {
330 net::ClientSocketPoolManager::set_max_sockets_per_group(8);
331 } else if (connect_trial_group == connect_9) {
332 net::ClientSocketPoolManager::set_max_sockets_per_group(9);
333 } else {
334 NOTREACHED();
335 }
336 }
337
338 // A/B test for determining a value for unused socket timeout. Currently the
339 // timeout defaults to 10 seconds. Having this value set too low won't allow us
340 // to take advantage of idle sockets. Setting it to too high could possibly
341 // result in more ERR_CONNECTION_RESETs, since some servers will kill a socket
342 // before we time it out. Since these are "unused" sockets, we won't retry the
343 // connection and instead show an error to the user. So we need to be
344 // conservative here. We've seen that some servers will close the socket after
345 // as short as 10 seconds. See http://crbug.com/84313 for more details.
346 void BrowserMainParts::SocketTimeoutFieldTrial() {
347 const base::FieldTrial::Probability kIdleSocketTimeoutDivisor = 100;
348 // 1% probability for all experimental settings.
349 const base::FieldTrial::Probability kSocketTimeoutProbability = 1;
350
351 // After June 30, 2011 builds, it will always be in default group.
352 scoped_refptr<base::FieldTrial> socket_timeout_trial(
353 new base::FieldTrial("IdleSktToImpact", kIdleSocketTimeoutDivisor,
354 "idle_timeout_10", 2011, 6, 30));
355 const int socket_timeout_10 = socket_timeout_trial->kDefaultGroupNumber;
356
357 const int socket_timeout_5 =
358 socket_timeout_trial->AppendGroup("idle_timeout_5",
359 kSocketTimeoutProbability);
360 const int socket_timeout_20 =
361 socket_timeout_trial->AppendGroup("idle_timeout_20",
362 kSocketTimeoutProbability);
363
364 const int idle_to_trial_group = socket_timeout_trial->group();
365
366 if (idle_to_trial_group == socket_timeout_5) {
367 net::ClientSocketPool::set_unused_idle_socket_timeout(5);
368 } else if (idle_to_trial_group == socket_timeout_10) {
369 net::ClientSocketPool::set_unused_idle_socket_timeout(10);
370 } else if (idle_to_trial_group == socket_timeout_20) {
371 net::ClientSocketPool::set_unused_idle_socket_timeout(20);
372 } else {
373 NOTREACHED();
374 }
375 }
376
377 void BrowserMainParts::ProxyConnectionsFieldTrial() {
378 const base::FieldTrial::Probability kProxyConnectionsDivisor = 100;
379 // 25% probability
380 const base::FieldTrial::Probability kProxyConnectionProbability = 1;
381
382 // After June 30, 2011 builds, it will always be in default group.
383 scoped_refptr<base::FieldTrial> proxy_connection_trial(
384 new base::FieldTrial("ProxyConnectionImpact", kProxyConnectionsDivisor,
385 "proxy_connections_32", 2011, 6, 30));
386
387 // This (32 connections per proxy server) is the current default value.
388 // Declaring it here allows us to easily re-assign the probability space while
389 // maintaining that the default group always has the remainder of the "share",
390 // which allows for cleaner and quicker changes down the line if needed.
391 const int proxy_connections_32 = proxy_connection_trial->kDefaultGroupNumber;
392
393 // The number of max sockets per group cannot be greater than the max number
394 // of sockets per proxy server. We tried using 8, and it can easily
395 // lead to total browser stalls.
396 const int proxy_connections_16 =
397 proxy_connection_trial->AppendGroup("proxy_connections_16",
398 kProxyConnectionProbability);
399 const int proxy_connections_64 =
400 proxy_connection_trial->AppendGroup("proxy_connections_64",
401 kProxyConnectionProbability);
402
403 const int proxy_connections_trial_group = proxy_connection_trial->group();
404
405 if (proxy_connections_trial_group == proxy_connections_16) {
406 net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(16);
407 } else if (proxy_connections_trial_group == proxy_connections_32) {
408 net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(32);
409 } else if (proxy_connections_trial_group == proxy_connections_64) {
410 net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(64);
411 } else {
412 NOTREACHED();
413 }
414 }
415
416 // When --use-spdy not set, users will be in A/B test for spdy.
417 // group A (npn_with_spdy): this means npn and spdy are enabled. In case server
418 // supports spdy, browser will use spdy.
419 // group B (npn_with_http): this means npn is enabled but spdy won't be used.
420 // Http is still used for all requests.
421 // default group: no npn or spdy is involved. The "old" non-spdy
422 // chrome behavior.
423 void BrowserMainParts::SpdyFieldTrial() {
424 if (parsed_command_line().HasSwitch(switches::kUseSpdy)) {
425 std::string spdy_mode =
426 parsed_command_line().GetSwitchValueASCII(switches::kUseSpdy);
427 net::HttpNetworkLayer::EnableSpdy(spdy_mode);
428 } else {
429 #if !defined(OS_CHROMEOS)
430 bool is_spdy_trial = false;
431 const base::FieldTrial::Probability kSpdyDivisor = 100;
432 base::FieldTrial::Probability npnhttp_probability = 5;
433
434 // After June 30, 2011 builds, it will always be in default group.
435 scoped_refptr<base::FieldTrial> trial(
436 new base::FieldTrial(
437 "SpdyImpact", kSpdyDivisor, "npn_with_spdy", 2011, 6, 30));
438
439 // npn with spdy support is the default.
440 int npn_spdy_grp = trial->kDefaultGroupNumber;
441
442 // npn with only http support, no spdy.
443 int npn_http_grp = trial->AppendGroup("npn_with_http", npnhttp_probability);
444
445 int trial_grp = trial->group();
446 if (trial_grp == npn_http_grp) {
447 is_spdy_trial = true;
448 net::HttpNetworkLayer::EnableSpdy("npn-http");
449 } else if (trial_grp == npn_spdy_grp) {
450 is_spdy_trial = true;
451 net::HttpNetworkLayer::EnableSpdy("npn");
452 } else {
453 CHECK(!is_spdy_trial);
454 }
455 #else
456 // Always enable SPDY on Chrome OS
457 net::HttpNetworkLayer::EnableSpdy("npn");
458 #endif // !defined(OS_CHROMEOS)
459 }
460
461 // Setup SPDY CWND Field trial.
462 const base::FieldTrial::Probability kSpdyCwndDivisor = 100;
463 const base::FieldTrial::Probability kSpdyCwnd16 = 20; // fixed at 16
464 const base::FieldTrial::Probability kSpdyCwnd10 = 20; // fixed at 10
465 const base::FieldTrial::Probability kSpdyCwndMin16 = 20; // no less than 16
466 const base::FieldTrial::Probability kSpdyCwndMin10 = 20; // no less than 10
467
468 // After June 30, 2011 builds, it will always be in default group
469 // (cwndDynamic).
470 scoped_refptr<base::FieldTrial> trial(
471 new base::FieldTrial(
472 "SpdyCwnd", kSpdyCwndDivisor, "cwndDynamic", 2011, 6, 30));
473
474 trial->AppendGroup("cwnd10", kSpdyCwnd10);
475 trial->AppendGroup("cwnd16", kSpdyCwnd16);
476 trial->AppendGroup("cwndMin16", kSpdyCwndMin16);
477 trial->AppendGroup("cwndMin10", kSpdyCwndMin10);
478
479 if (parsed_command_line().HasSwitch(switches::kMaxSpdyConcurrentStreams)) {
480 int value = 0;
481 base::StringToInt(parsed_command_line().GetSwitchValueASCII(
482 switches::kMaxSpdyConcurrentStreams),
483 &value);
484 if (value > 0)
485 net::SpdySession::set_max_concurrent_streams(value);
486 }
487 }
488
489 // If --socket-reuse-policy is not specified, run an A/B test for choosing the
490 // warmest socket.
491 void BrowserMainParts::WarmConnectionFieldTrial() {
492 const CommandLine& command_line = parsed_command_line();
493 if (command_line.HasSwitch(switches::kSocketReusePolicy)) {
494 std::string socket_reuse_policy_str = command_line.GetSwitchValueASCII(
495 switches::kSocketReusePolicy);
496 int policy = -1;
497 base::StringToInt(socket_reuse_policy_str, &policy);
498
499 const int policy_list[] = { 0, 1, 2 };
500 VLOG(1) << "Setting socket_reuse_policy = " << policy;
501 SetSocketReusePolicy(policy, policy_list, arraysize(policy_list));
502 return;
503 }
504
505 const base::FieldTrial::Probability kWarmSocketDivisor = 100;
506 const base::FieldTrial::Probability kWarmSocketProbability = 33;
507
508 // After January 30, 2013 builds, it will always be in default group.
509 scoped_refptr<base::FieldTrial> warmest_socket_trial(
510 new base::FieldTrial(
511 "WarmSocketImpact", kWarmSocketDivisor, "last_accessed_socket",
512 2013, 1, 30));
513
514 // Default value is USE_LAST_ACCESSED_SOCKET.
515 const int last_accessed_socket = warmest_socket_trial->kDefaultGroupNumber;
516 const int warmest_socket = warmest_socket_trial->AppendGroup(
517 "warmest_socket", kWarmSocketProbability);
518 const int warm_socket = warmest_socket_trial->AppendGroup(
519 "warm_socket", kWarmSocketProbability);
520
521 const int warmest_socket_trial_group = warmest_socket_trial->group();
522
523 const int policy_list[] = { warmest_socket, warm_socket,
524 last_accessed_socket };
525 SetSocketReusePolicy(warmest_socket_trial_group, policy_list,
526 arraysize(policy_list));
527 }
528
529 // If neither --enable-connect-backup-jobs or --disable-connect-backup-jobs is
530 // specified, run an A/B test for automatically establishing backup TCP
531 // connections when a certain timeout value is exceeded.
532 void BrowserMainParts::ConnectBackupJobsFieldTrial() {
533 if (parsed_command_line().HasSwitch(switches::kEnableConnectBackupJobs)) {
534 net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
535 true);
536 } else if (parsed_command_line().HasSwitch(
537 switches::kDisableConnectBackupJobs)) {
538 net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
539 false);
540 } else {
541 const base::FieldTrial::Probability kConnectBackupJobsDivisor = 100;
542 // 1% probability.
543 const base::FieldTrial::Probability kConnectBackupJobsProbability = 1;
544 // After June 30, 2011 builds, it will always be in default group.
545 scoped_refptr<base::FieldTrial> trial(
546 new base::FieldTrial("ConnnectBackupJobs",
547 kConnectBackupJobsDivisor, "ConnectBackupJobsEnabled", 2011, 6,
548 30));
549 const int connect_backup_jobs_enabled = trial->kDefaultGroupNumber;
550 trial->AppendGroup("ConnectBackupJobsDisabled",
551 kConnectBackupJobsProbability);
552 const int trial_group = trial->group();
553 net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
554 trial_group == connect_backup_jobs_enabled);
555 }
556 }
557
558 // Test the impact on subsequent Google searches of getting suggestions from
559 // www.google.TLD instead of clients1.google.TLD.
560 void BrowserMainParts::SuggestPrefixFieldTrial() {
561 const base::FieldTrial::Probability kSuggestPrefixDivisor = 100;
562 // 50% probability.
563 const base::FieldTrial::Probability kSuggestPrefixProbability = 50;
564 // After Jan 1, 2012, it will always be in default group.
565 scoped_refptr<base::FieldTrial> trial(
566 new base::FieldTrial("SuggestHostPrefix",
567 kSuggestPrefixDivisor, "Default_Prefix", 2012, 1, 1));
568 trial->AppendGroup("Www_Prefix", kSuggestPrefixProbability);
569 // The field trial is detected directly, so we don't need to call anything.
570 }
571
572 // BrowserMainParts: |MainMessageLoopStart()| and related ----------------------
573
574 void BrowserMainParts::MainMessageLoopStart() {
575 PreMainMessageLoopStart();
576
577 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
578
579 // TODO(viettrungluu): should these really go before setting the thread name?
580 system_monitor_.reset(new base::SystemMonitor);
581 hi_res_timer_manager_.reset(new HighResolutionTimerManager);
582
583 InitializeMainThread();
584
585 network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
586
587 PostMainMessageLoopStart();
588 Profiling::MainMessageLoopStarted();
589 }
590
591 void BrowserMainParts::InitializeMainThread() {
592 const char* kThreadName = "CrBrowserMain";
593 base::PlatformThread::SetName(kThreadName);
594 main_message_loop().set_thread_name(kThreadName);
595
596 // Register the main thread by instantiating it, but don't call any methods.
597 main_thread_.reset(new BrowserThread(BrowserThread::UI,
598 MessageLoop::current()));
599 }
600
601 // BrowserMainParts: |SetupMetricsAndFieldTrials()| related --------------------
602
603 // Initializes the metrics service with the configuration for this process,
604 // returning the created service (guaranteed non-NULL).
605 MetricsService* BrowserMainParts::InitializeMetrics(
606 const CommandLine& parsed_command_line,
607 const PrefService* local_state) {
608 #if defined(OS_WIN)
609 if (parsed_command_line.HasSwitch(switches::kChromeFrame))
610 MetricsLog::set_version_extension("-F");
611 #elif defined(ARCH_CPU_64_BITS)
612 MetricsLog::set_version_extension("-64");
613 #endif // defined(OS_WIN)
614
615 MetricsService* metrics = g_browser_process->metrics_service();
616
617 if (parsed_command_line.HasSwitch(switches::kMetricsRecordingOnly) ||
618 parsed_command_line.HasSwitch(switches::kEnableBenchmarking)) {
619 // If we're testing then we don't care what the user preference is, we turn
620 // on recording, but not reporting, otherwise tests fail.
621 metrics->StartRecordingOnly();
622 return metrics;
623 }
624
625 // If the user permits metrics reporting with the checkbox in the
626 // prefs, we turn on recording. We disable metrics completely for
627 // non-official builds.
628 #if defined(GOOGLE_CHROME_BUILD)
629 #if defined(OS_CHROMEOS)
630 bool enabled = chromeos::UserCrosSettingsProvider::cached_reporting_enabled();
631 #else
632 bool enabled = local_state->GetBoolean(prefs::kMetricsReportingEnabled);
633 #endif // #if defined(OS_CHROMEOS)
634 if (enabled) {
635 metrics->Start();
636 }
637 #endif // defined(GOOGLE_CHROME_BUILD)
638
639 return metrics;
640 }
641
642 void BrowserMainParts::SetupFieldTrials(bool metrics_recording_enabled,
643 bool proxy_policy_is_set) {
644 // Note: make sure to call ConnectionFieldTrial() before
645 // ProxyConnectionsFieldTrial().
646 ConnectionFieldTrial();
647 SocketTimeoutFieldTrial();
648 // If a policy is defining the number of active connections this field test
649 // shoud not be performed.
650 if (!proxy_policy_is_set)
651 ProxyConnectionsFieldTrial();
652 prerender::ConfigurePrefetchAndPrerender(parsed_command_line());
653 InstantFieldTrial::Activate();
654 SpdyFieldTrial();
655 ConnectBackupJobsFieldTrial();
656 SuggestPrefixFieldTrial();
657 WarmConnectionFieldTrial();
658 }
659
660 // -----------------------------------------------------------------------------
661 // TODO(viettrungluu): move more/rest of BrowserMain() into above structure
662
663 namespace {
664 220
665 // This function provides some ways to test crash and assertion handling 221 // This function provides some ways to test crash and assertion handling
666 // behavior of the program. 222 // behavior of the program.
667 void HandleTestParameters(const CommandLine& command_line) { 223 void HandleTestParameters(const CommandLine& command_line) {
668 // This parameter causes an assertion. 224 // This parameter causes an assertion.
669 if (command_line.HasSwitch(switches::kBrowserAssertTest)) { 225 if (command_line.HasSwitch(switches::kBrowserAssertTest)) {
670 DCHECK(false); 226 DCHECK(false);
671 } 227 }
672 228
673 // This parameter causes a null pointer crash (crash reporter trigger). 229 // This parameter causes a null pointer crash (crash reporter trigger).
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 local_state->GetBoolean(prefs::kMetricsReportingEnabled); 823 local_state->GetBoolean(prefs::kMetricsReportingEnabled);
1268 if (!breakpad_enabled && metrics_reporting_enabled->IsUserModifiable()) 824 if (!breakpad_enabled && metrics_reporting_enabled->IsUserModifiable())
1269 breakpad_enabled = getenv(env_vars::kHeadless) != NULL; 825 breakpad_enabled = getenv(env_vars::kHeadless) != NULL;
1270 #endif // #if defined(OS_CHROMEOS) 826 #endif // #if defined(OS_CHROMEOS)
1271 return breakpad_enabled; 827 return breakpad_enabled;
1272 } 828 }
1273 #endif // #if defined(USE_LINUX_BREAKPAD) 829 #endif // #if defined(USE_LINUX_BREAKPAD)
1274 830
1275 } // namespace 831 } // namespace
1276 832
833 // BrowserMainParts ------------------------------------------------------------
834
835 BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters)
836 : parameters_(parameters),
837 parsed_command_line_(parameters.command_line_) {
838 }
839
840 BrowserMainParts::~BrowserMainParts() {
841 }
842
843 // BrowserMainParts: |EarlyInitialization()| and related -----------------------
844
845 void BrowserMainParts::EarlyInitialization() {
846 PreEarlyInitialization();
847
848 if (parsed_command_line().HasSwitch(switches::kEnableBenchmarking))
849 base::FieldTrial::EnableBenchmarking();
850
851 InitializeSSL();
852
853 if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart))
854 net::SSLConfigService::DisableFalseStart();
855 if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo))
856 net::SSLConfigService::EnableCachedInfo();
857 if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts))
858 net::SSLConfigService::EnableOriginBoundCerts();
859 if (parsed_command_line().HasSwitch(
860 switches::kEnableDNSCertProvenanceChecking)) {
861 net::SSLConfigService::EnableDNSCertProvenanceChecking();
862 }
863
864 // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
865 // seem dependent on InitializeSSL().
866 if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen))
867 net::set_tcp_fastopen_enabled(true);
868
869 PostEarlyInitialization();
870 }
871
872 // This will be called after the command-line has been mutated by about:flags
873 MetricsService* BrowserMainParts::SetupMetricsAndFieldTrials(
874 const CommandLine& parsed_command_line,
875 PrefService* local_state) {
876 // Must initialize metrics after labs have been converted into switches,
877 // but before field trials are set up (so that client ID is available for
878 // one-time randomized field trials).
879 MetricsService* metrics = InitializeMetrics(parsed_command_line, local_state);
880
881 // Initialize FieldTrialList to support FieldTrials that use one-time
882 // randomization. The client ID will be empty if the user has not opted
883 // to send metrics.
884 field_trial_list_.reset(new base::FieldTrialList(metrics->GetClientId()));
885
886 SetupFieldTrials(metrics->recording_active(),
887 local_state->IsManagedPreference(
888 prefs::kMaxConnectionsPerProxy));
889
890 // Initialize FieldTrialSynchronizer system. This is a singleton and is used
891 // for posting tasks via NewRunnableMethod. Its deleted when it goes out of
892 // scope. Even though NewRunnableMethod does AddRef and Release, the object
893 // will not be deleted after the Task is executed.
894 field_trial_synchronizer_ = new FieldTrialSynchronizer();
895
896 return metrics;
897 }
898
899 // This is an A/B test for the maximum number of persistent connections per
900 // host. Currently Chrome, Firefox, and IE8 have this value set at 6. Safari
901 // uses 4, and Fasterfox (a plugin for Firefox that supposedly configures it to
902 // run faster) uses 8. We would like to see how much of an effect this value has
903 // on browsing. Too large a value might cause us to run into SYN flood detection
904 // mechanisms.
905 void BrowserMainParts::ConnectionFieldTrial() {
906 const base::FieldTrial::Probability kConnectDivisor = 100;
907 const base::FieldTrial::Probability kConnectProbability = 1; // 1% prob.
908
909 // After June 30, 2011 builds, it will always be in default group.
910 scoped_refptr<base::FieldTrial> connect_trial(
911 new base::FieldTrial(
912 "ConnCountImpact", kConnectDivisor, "conn_count_6", 2011, 6, 30));
913
914 // This (6) is the current default value. Having this group declared here
915 // makes it straightforward to modify |kConnectProbability| such that the same
916 // probability value will be assigned to all the other groups, while
917 // preserving the remainder of the of probability space to the default value.
918 const int connect_6 = connect_trial->kDefaultGroupNumber;
919
920 const int connect_5 = connect_trial->AppendGroup("conn_count_5",
921 kConnectProbability);
922 const int connect_7 = connect_trial->AppendGroup("conn_count_7",
923 kConnectProbability);
924 const int connect_8 = connect_trial->AppendGroup("conn_count_8",
925 kConnectProbability);
926 const int connect_9 = connect_trial->AppendGroup("conn_count_9",
927 kConnectProbability);
928
929 const int connect_trial_group = connect_trial->group();
930
931 if (connect_trial_group == connect_5) {
932 net::ClientSocketPoolManager::set_max_sockets_per_group(5);
933 } else if (connect_trial_group == connect_6) {
934 net::ClientSocketPoolManager::set_max_sockets_per_group(6);
935 } else if (connect_trial_group == connect_7) {
936 net::ClientSocketPoolManager::set_max_sockets_per_group(7);
937 } else if (connect_trial_group == connect_8) {
938 net::ClientSocketPoolManager::set_max_sockets_per_group(8);
939 } else if (connect_trial_group == connect_9) {
940 net::ClientSocketPoolManager::set_max_sockets_per_group(9);
941 } else {
942 NOTREACHED();
943 }
944 }
945
946 // A/B test for determining a value for unused socket timeout. Currently the
947 // timeout defaults to 10 seconds. Having this value set too low won't allow us
948 // to take advantage of idle sockets. Setting it to too high could possibly
949 // result in more ERR_CONNECTION_RESETs, since some servers will kill a socket
950 // before we time it out. Since these are "unused" sockets, we won't retry the
951 // connection and instead show an error to the user. So we need to be
952 // conservative here. We've seen that some servers will close the socket after
953 // as short as 10 seconds. See http://crbug.com/84313 for more details.
954 void BrowserMainParts::SocketTimeoutFieldTrial() {
955 const base::FieldTrial::Probability kIdleSocketTimeoutDivisor = 100;
956 // 1% probability for all experimental settings.
957 const base::FieldTrial::Probability kSocketTimeoutProbability = 1;
958
959 // After June 30, 2011 builds, it will always be in default group.
960 scoped_refptr<base::FieldTrial> socket_timeout_trial(
961 new base::FieldTrial("IdleSktToImpact", kIdleSocketTimeoutDivisor,
962 "idle_timeout_10", 2011, 6, 30));
963 const int socket_timeout_10 = socket_timeout_trial->kDefaultGroupNumber;
964
965 const int socket_timeout_5 =
966 socket_timeout_trial->AppendGroup("idle_timeout_5",
967 kSocketTimeoutProbability);
968 const int socket_timeout_20 =
969 socket_timeout_trial->AppendGroup("idle_timeout_20",
970 kSocketTimeoutProbability);
971
972 const int idle_to_trial_group = socket_timeout_trial->group();
973
974 if (idle_to_trial_group == socket_timeout_5) {
975 net::ClientSocketPool::set_unused_idle_socket_timeout(5);
976 } else if (idle_to_trial_group == socket_timeout_10) {
977 net::ClientSocketPool::set_unused_idle_socket_timeout(10);
978 } else if (idle_to_trial_group == socket_timeout_20) {
979 net::ClientSocketPool::set_unused_idle_socket_timeout(20);
980 } else {
981 NOTREACHED();
982 }
983 }
984
985 void BrowserMainParts::ProxyConnectionsFieldTrial() {
986 const base::FieldTrial::Probability kProxyConnectionsDivisor = 100;
987 // 25% probability
988 const base::FieldTrial::Probability kProxyConnectionProbability = 1;
989
990 // After June 30, 2011 builds, it will always be in default group.
991 scoped_refptr<base::FieldTrial> proxy_connection_trial(
992 new base::FieldTrial("ProxyConnectionImpact", kProxyConnectionsDivisor,
993 "proxy_connections_32", 2011, 6, 30));
994
995 // This (32 connections per proxy server) is the current default value.
996 // Declaring it here allows us to easily re-assign the probability space while
997 // maintaining that the default group always has the remainder of the "share",
998 // which allows for cleaner and quicker changes down the line if needed.
999 const int proxy_connections_32 = proxy_connection_trial->kDefaultGroupNumber;
1000
1001 // The number of max sockets per group cannot be greater than the max number
1002 // of sockets per proxy server. We tried using 8, and it can easily
1003 // lead to total browser stalls.
1004 const int proxy_connections_16 =
1005 proxy_connection_trial->AppendGroup("proxy_connections_16",
1006 kProxyConnectionProbability);
1007 const int proxy_connections_64 =
1008 proxy_connection_trial->AppendGroup("proxy_connections_64",
1009 kProxyConnectionProbability);
1010
1011 const int proxy_connections_trial_group = proxy_connection_trial->group();
1012
1013 if (proxy_connections_trial_group == proxy_connections_16) {
1014 net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(16);
1015 } else if (proxy_connections_trial_group == proxy_connections_32) {
1016 net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(32);
1017 } else if (proxy_connections_trial_group == proxy_connections_64) {
1018 net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(64);
1019 } else {
1020 NOTREACHED();
1021 }
1022 }
1023
1024 // When --use-spdy not set, users will be in A/B test for spdy.
1025 // group A (npn_with_spdy): this means npn and spdy are enabled. In case server
1026 // supports spdy, browser will use spdy.
1027 // group B (npn_with_http): this means npn is enabled but spdy won't be used.
1028 // Http is still used for all requests.
1029 // default group: no npn or spdy is involved. The "old" non-spdy
1030 // chrome behavior.
1031 void BrowserMainParts::SpdyFieldTrial() {
1032 if (parsed_command_line().HasSwitch(switches::kUseSpdy)) {
1033 std::string spdy_mode =
1034 parsed_command_line().GetSwitchValueASCII(switches::kUseSpdy);
1035 net::HttpNetworkLayer::EnableSpdy(spdy_mode);
1036 } else {
1037 #if !defined(OS_CHROMEOS)
1038 bool is_spdy_trial = false;
1039 const base::FieldTrial::Probability kSpdyDivisor = 100;
1040 base::FieldTrial::Probability npnhttp_probability = 5;
1041
1042 // After June 30, 2011 builds, it will always be in default group.
1043 scoped_refptr<base::FieldTrial> trial(
1044 new base::FieldTrial(
1045 "SpdyImpact", kSpdyDivisor, "npn_with_spdy", 2011, 6, 30));
1046
1047 // npn with spdy support is the default.
1048 int npn_spdy_grp = trial->kDefaultGroupNumber;
1049
1050 // npn with only http support, no spdy.
1051 int npn_http_grp = trial->AppendGroup("npn_with_http", npnhttp_probability);
1052
1053 int trial_grp = trial->group();
1054 if (trial_grp == npn_http_grp) {
1055 is_spdy_trial = true;
1056 net::HttpNetworkLayer::EnableSpdy("npn-http");
1057 } else if (trial_grp == npn_spdy_grp) {
1058 is_spdy_trial = true;
1059 net::HttpNetworkLayer::EnableSpdy("npn");
1060 } else {
1061 CHECK(!is_spdy_trial);
1062 }
1063 #else
1064 // Always enable SPDY on Chrome OS
1065 net::HttpNetworkLayer::EnableSpdy("npn");
1066 #endif // !defined(OS_CHROMEOS)
1067 }
1068
1069 // Setup SPDY CWND Field trial.
1070 const base::FieldTrial::Probability kSpdyCwndDivisor = 100;
1071 const base::FieldTrial::Probability kSpdyCwnd16 = 20; // fixed at 16
1072 const base::FieldTrial::Probability kSpdyCwnd10 = 20; // fixed at 10
1073 const base::FieldTrial::Probability kSpdyCwndMin16 = 20; // no less than 16
1074 const base::FieldTrial::Probability kSpdyCwndMin10 = 20; // no less than 10
1075
1076 // After June 30, 2011 builds, it will always be in default group
1077 // (cwndDynamic).
1078 scoped_refptr<base::FieldTrial> trial(
1079 new base::FieldTrial(
1080 "SpdyCwnd", kSpdyCwndDivisor, "cwndDynamic", 2011, 6, 30));
1081
1082 trial->AppendGroup("cwnd10", kSpdyCwnd10);
1083 trial->AppendGroup("cwnd16", kSpdyCwnd16);
1084 trial->AppendGroup("cwndMin16", kSpdyCwndMin16);
1085 trial->AppendGroup("cwndMin10", kSpdyCwndMin10);
1086
1087 if (parsed_command_line().HasSwitch(switches::kMaxSpdyConcurrentStreams)) {
1088 int value = 0;
1089 base::StringToInt(parsed_command_line().GetSwitchValueASCII(
1090 switches::kMaxSpdyConcurrentStreams),
1091 &value);
1092 if (value > 0)
1093 net::SpdySession::set_max_concurrent_streams(value);
1094 }
1095 }
1096
1097 // If --socket-reuse-policy is not specified, run an A/B test for choosing the
1098 // warmest socket.
1099 void BrowserMainParts::WarmConnectionFieldTrial() {
1100 const CommandLine& command_line = parsed_command_line();
1101 if (command_line.HasSwitch(switches::kSocketReusePolicy)) {
1102 std::string socket_reuse_policy_str = command_line.GetSwitchValueASCII(
1103 switches::kSocketReusePolicy);
1104 int policy = -1;
1105 base::StringToInt(socket_reuse_policy_str, &policy);
1106
1107 const int policy_list[] = { 0, 1, 2 };
1108 VLOG(1) << "Setting socket_reuse_policy = " << policy;
1109 SetSocketReusePolicy(policy, policy_list, arraysize(policy_list));
1110 return;
1111 }
1112
1113 const base::FieldTrial::Probability kWarmSocketDivisor = 100;
1114 const base::FieldTrial::Probability kWarmSocketProbability = 33;
1115
1116 // After January 30, 2013 builds, it will always be in default group.
1117 scoped_refptr<base::FieldTrial> warmest_socket_trial(
1118 new base::FieldTrial(
1119 "WarmSocketImpact", kWarmSocketDivisor, "last_accessed_socket",
1120 2013, 1, 30));
1121
1122 // Default value is USE_LAST_ACCESSED_SOCKET.
1123 const int last_accessed_socket = warmest_socket_trial->kDefaultGroupNumber;
1124 const int warmest_socket = warmest_socket_trial->AppendGroup(
1125 "warmest_socket", kWarmSocketProbability);
1126 const int warm_socket = warmest_socket_trial->AppendGroup(
1127 "warm_socket", kWarmSocketProbability);
1128
1129 const int warmest_socket_trial_group = warmest_socket_trial->group();
1130
1131 const int policy_list[] = { warmest_socket, warm_socket,
1132 last_accessed_socket };
1133 SetSocketReusePolicy(warmest_socket_trial_group, policy_list,
1134 arraysize(policy_list));
1135 }
1136
1137 // If neither --enable-connect-backup-jobs or --disable-connect-backup-jobs is
1138 // specified, run an A/B test for automatically establishing backup TCP
1139 // connections when a certain timeout value is exceeded.
1140 void BrowserMainParts::ConnectBackupJobsFieldTrial() {
1141 if (parsed_command_line().HasSwitch(switches::kEnableConnectBackupJobs)) {
1142 net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
1143 true);
1144 } else if (parsed_command_line().HasSwitch(
1145 switches::kDisableConnectBackupJobs)) {
1146 net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
1147 false);
1148 } else {
1149 const base::FieldTrial::Probability kConnectBackupJobsDivisor = 100;
1150 // 1% probability.
1151 const base::FieldTrial::Probability kConnectBackupJobsProbability = 1;
1152 // After June 30, 2011 builds, it will always be in default group.
1153 scoped_refptr<base::FieldTrial> trial(
1154 new base::FieldTrial("ConnnectBackupJobs",
1155 kConnectBackupJobsDivisor, "ConnectBackupJobsEnabled", 2011, 6,
1156 30));
1157 const int connect_backup_jobs_enabled = trial->kDefaultGroupNumber;
1158 trial->AppendGroup("ConnectBackupJobsDisabled",
1159 kConnectBackupJobsProbability);
1160 const int trial_group = trial->group();
1161 net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
1162 trial_group == connect_backup_jobs_enabled);
1163 }
1164 }
1165
1166 // Test the impact on subsequent Google searches of getting suggestions from
1167 // www.google.TLD instead of clients1.google.TLD.
1168 void BrowserMainParts::SuggestPrefixFieldTrial() {
1169 const base::FieldTrial::Probability kSuggestPrefixDivisor = 100;
1170 // 50% probability.
1171 const base::FieldTrial::Probability kSuggestPrefixProbability = 50;
1172 // After Jan 1, 2012, it will always be in default group.
1173 scoped_refptr<base::FieldTrial> trial(
1174 new base::FieldTrial("SuggestHostPrefix",
1175 kSuggestPrefixDivisor, "Default_Prefix", 2012, 1, 1));
1176 trial->AppendGroup("Www_Prefix", kSuggestPrefixProbability);
1177 // The field trial is detected directly, so we don't need to call anything.
1178 }
1179
1180 // BrowserMainParts: |MainMessageLoopStart()| and related ----------------------
1181
1182 void BrowserMainParts::MainMessageLoopStart() {
1183 PreMainMessageLoopStart();
1184
1185 main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
1186
1187 // TODO(viettrungluu): should these really go before setting the thread name?
1188 system_monitor_.reset(new base::SystemMonitor);
1189 hi_res_timer_manager_.reset(new HighResolutionTimerManager);
1190
1191 InitializeMainThread();
1192
1193 network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
1194
1195 PostMainMessageLoopStart();
1196 Profiling::MainMessageLoopStarted();
1197 }
1198
1199 void BrowserMainParts::InitializeMainThread() {
1200 const char* kThreadName = "CrBrowserMain";
1201 base::PlatformThread::SetName(kThreadName);
1202 main_message_loop().set_thread_name(kThreadName);
1203
1204 // Register the main thread by instantiating it, but don't call any methods.
1205 main_thread_.reset(new BrowserThread(BrowserThread::UI,
1206 MessageLoop::current()));
1207 }
1208
1209 // BrowserMainParts: |SetupMetricsAndFieldTrials()| related --------------------
1210
1211 // Initializes the metrics service with the configuration for this process,
1212 // returning the created service (guaranteed non-NULL).
1213 MetricsService* BrowserMainParts::InitializeMetrics(
1214 const CommandLine& parsed_command_line,
1215 const PrefService* local_state) {
1216 #if defined(OS_WIN)
1217 if (parsed_command_line.HasSwitch(switches::kChromeFrame))
1218 MetricsLog::set_version_extension("-F");
1219 #elif defined(ARCH_CPU_64_BITS)
1220 MetricsLog::set_version_extension("-64");
1221 #endif // defined(OS_WIN)
1222
1223 MetricsService* metrics = g_browser_process->metrics_service();
1224
1225 if (parsed_command_line.HasSwitch(switches::kMetricsRecordingOnly) ||
1226 parsed_command_line.HasSwitch(switches::kEnableBenchmarking)) {
1227 // If we're testing then we don't care what the user preference is, we turn
1228 // on recording, but not reporting, otherwise tests fail.
1229 metrics->StartRecordingOnly();
1230 return metrics;
1231 }
1232
1233 // If the user permits metrics reporting with the checkbox in the
1234 // prefs, we turn on recording. We disable metrics completely for
1235 // non-official builds.
1236 #if defined(GOOGLE_CHROME_BUILD)
1237 #if defined(OS_CHROMEOS)
1238 bool enabled = chromeos::UserCrosSettingsProvider::cached_reporting_enabled();
1239 #else
1240 bool enabled = local_state->GetBoolean(prefs::kMetricsReportingEnabled);
1241 #endif // #if defined(OS_CHROMEOS)
1242 if (enabled) {
1243 metrics->Start();
1244 }
1245 #endif // defined(GOOGLE_CHROME_BUILD)
1246
1247 return metrics;
1248 }
1249
1250 void BrowserMainParts::SetupFieldTrials(bool metrics_recording_enabled,
1251 bool proxy_policy_is_set) {
1252 // Note: make sure to call ConnectionFieldTrial() before
1253 // ProxyConnectionsFieldTrial().
1254 ConnectionFieldTrial();
1255 SocketTimeoutFieldTrial();
1256 // If a policy is defining the number of active connections this field test
1257 // shoud not be performed.
1258 if (!proxy_policy_is_set)
1259 ProxyConnectionsFieldTrial();
1260 prerender::ConfigurePrefetchAndPrerender(parsed_command_line());
1261 InstantFieldTrial::Activate();
1262 SpdyFieldTrial();
1263 ConnectBackupJobsFieldTrial();
1264 SuggestPrefixFieldTrial();
1265 WarmConnectionFieldTrial();
1266 }
1267
1268 // -----------------------------------------------------------------------------
1269 // TODO(viettrungluu): move more/rest of BrowserMain() into BrowserMainParts.
1270
1277 #if defined(OS_CHROMEOS) 1271 #if defined(OS_CHROMEOS)
1278 // Allows authenticator to be invoked without adding refcounting. The instances 1272 // Allows authenticator to be invoked without adding refcounting. The instances
1279 // will delete themselves upon completion. 1273 // will delete themselves upon completion.
1280 DISABLE_RUNNABLE_METHOD_REFCOUNT(StubLogin); 1274 DISABLE_RUNNABLE_METHOD_REFCOUNT(StubLogin);
1281 #endif 1275 #endif
1282 1276
1283 #if defined(OS_WIN) 1277 #if defined(OS_WIN)
1284 #define DLLEXPORT __declspec(dllexport) 1278 #define DLLEXPORT __declspec(dllexport)
1285 1279
1286 // We use extern C for the prototype DLLEXPORT to avoid C++ name mangling. 1280 // We use extern C for the prototype DLLEXPORT to avoid C++ name mangling.
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 // (environment variable is set, and valid). 2156 // (environment variable is set, and valid).
2163 std::string pre_read; 2157 std::string pre_read;
2164 if (env->GetVar(kEnvVar, &pre_read) && (pre_read == "0" || pre_read == "1")) { 2158 if (env->GetVar(kEnvVar, &pre_read) && (pre_read == "0" || pre_read == "1")) {
2165 std::string uma_name(name); 2159 std::string uma_name(name);
2166 uma_name += "_PreRead"; 2160 uma_name += "_PreRead";
2167 uma_name += pre_read == "1" ? "Enabled" : "Disabled"; 2161 uma_name += pre_read == "1" ? "Enabled" : "Disabled";
2168 AddPreReadHistogramTime(uma_name.c_str(), time); 2162 AddPreReadHistogramTime(uma_name.c_str(), time);
2169 } 2163 }
2170 #endif 2164 #endif
2171 } 2165 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698