| Index: chrome/browser/browser_main.cc
|
| diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
|
| index 347de8ca8613744a02b959598a5baf9e82115dd8..7d6bbfb92f4d86348f76ce0526855cb261e395d1 100644
|
| --- a/chrome/browser/browser_main.cc
|
| +++ b/chrome/browser/browser_main.cc
|
| @@ -217,450 +217,6 @@ class NetLog;
|
| } // namespace net
|
|
|
| namespace {
|
| -void SetSocketReusePolicy(int warmest_socket_trial_group,
|
| - const int socket_policy[],
|
| - int num_groups);
|
| -} // namespace
|
| -
|
| -// BrowserMainParts ------------------------------------------------------------
|
| -
|
| -BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters)
|
| - : parameters_(parameters),
|
| - parsed_command_line_(parameters.command_line_) {
|
| -}
|
| -
|
| -BrowserMainParts::~BrowserMainParts() {
|
| -}
|
| -
|
| -// BrowserMainParts: |EarlyInitialization()| and related -----------------------
|
| -
|
| -void BrowserMainParts::EarlyInitialization() {
|
| - PreEarlyInitialization();
|
| -
|
| - if (parsed_command_line().HasSwitch(switches::kEnableBenchmarking))
|
| - base::FieldTrial::EnableBenchmarking();
|
| -
|
| - InitializeSSL();
|
| -
|
| - if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart))
|
| - net::SSLConfigService::DisableFalseStart();
|
| - if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo))
|
| - net::SSLConfigService::EnableCachedInfo();
|
| - if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts))
|
| - net::SSLConfigService::EnableOriginBoundCerts();
|
| - if (parsed_command_line().HasSwitch(
|
| - switches::kEnableDNSCertProvenanceChecking)) {
|
| - net::SSLConfigService::EnableDNSCertProvenanceChecking();
|
| - }
|
| -
|
| - // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
|
| - // seem dependent on InitializeSSL().
|
| - if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen))
|
| - net::set_tcp_fastopen_enabled(true);
|
| -
|
| - PostEarlyInitialization();
|
| -}
|
| -
|
| -// This will be called after the command-line has been mutated by about:flags
|
| -MetricsService* BrowserMainParts::SetupMetricsAndFieldTrials(
|
| - const CommandLine& parsed_command_line,
|
| - PrefService* local_state) {
|
| - // Must initialize metrics after labs have been converted into switches,
|
| - // but before field trials are set up (so that client ID is available for
|
| - // one-time randomized field trials).
|
| - MetricsService* metrics = InitializeMetrics(parsed_command_line, local_state);
|
| -
|
| - // Initialize FieldTrialList to support FieldTrials that use one-time
|
| - // randomization. The client ID will be empty if the user has not opted
|
| - // to send metrics.
|
| - field_trial_list_.reset(new base::FieldTrialList(metrics->GetClientId()));
|
| -
|
| - SetupFieldTrials(metrics->recording_active(),
|
| - local_state->IsManagedPreference(
|
| - prefs::kMaxConnectionsPerProxy));
|
| -
|
| - // Initialize FieldTrialSynchronizer system. This is a singleton and is used
|
| - // for posting tasks via NewRunnableMethod. Its deleted when it goes out of
|
| - // scope. Even though NewRunnableMethod does AddRef and Release, the object
|
| - // will not be deleted after the Task is executed.
|
| - field_trial_synchronizer_ = new FieldTrialSynchronizer();
|
| -
|
| - return metrics;
|
| -}
|
| -
|
| -// This is an A/B test for the maximum number of persistent connections per
|
| -// host. Currently Chrome, Firefox, and IE8 have this value set at 6. Safari
|
| -// uses 4, and Fasterfox (a plugin for Firefox that supposedly configures it to
|
| -// run faster) uses 8. We would like to see how much of an effect this value has
|
| -// on browsing. Too large a value might cause us to run into SYN flood detection
|
| -// mechanisms.
|
| -void BrowserMainParts::ConnectionFieldTrial() {
|
| - const base::FieldTrial::Probability kConnectDivisor = 100;
|
| - const base::FieldTrial::Probability kConnectProbability = 1; // 1% prob.
|
| -
|
| - // After June 30, 2011 builds, it will always be in default group.
|
| - scoped_refptr<base::FieldTrial> connect_trial(
|
| - new base::FieldTrial(
|
| - "ConnCountImpact", kConnectDivisor, "conn_count_6", 2011, 6, 30));
|
| -
|
| - // This (6) is the current default value. Having this group declared here
|
| - // makes it straightforward to modify |kConnectProbability| such that the same
|
| - // probability value will be assigned to all the other groups, while
|
| - // preserving the remainder of the of probability space to the default value.
|
| - const int connect_6 = connect_trial->kDefaultGroupNumber;
|
| -
|
| - const int connect_5 = connect_trial->AppendGroup("conn_count_5",
|
| - kConnectProbability);
|
| - const int connect_7 = connect_trial->AppendGroup("conn_count_7",
|
| - kConnectProbability);
|
| - const int connect_8 = connect_trial->AppendGroup("conn_count_8",
|
| - kConnectProbability);
|
| - const int connect_9 = connect_trial->AppendGroup("conn_count_9",
|
| - kConnectProbability);
|
| -
|
| - const int connect_trial_group = connect_trial->group();
|
| -
|
| - if (connect_trial_group == connect_5) {
|
| - net::ClientSocketPoolManager::set_max_sockets_per_group(5);
|
| - } else if (connect_trial_group == connect_6) {
|
| - net::ClientSocketPoolManager::set_max_sockets_per_group(6);
|
| - } else if (connect_trial_group == connect_7) {
|
| - net::ClientSocketPoolManager::set_max_sockets_per_group(7);
|
| - } else if (connect_trial_group == connect_8) {
|
| - net::ClientSocketPoolManager::set_max_sockets_per_group(8);
|
| - } else if (connect_trial_group == connect_9) {
|
| - net::ClientSocketPoolManager::set_max_sockets_per_group(9);
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -}
|
| -
|
| -// A/B test for determining a value for unused socket timeout. Currently the
|
| -// timeout defaults to 10 seconds. Having this value set too low won't allow us
|
| -// to take advantage of idle sockets. Setting it to too high could possibly
|
| -// result in more ERR_CONNECTION_RESETs, since some servers will kill a socket
|
| -// before we time it out. Since these are "unused" sockets, we won't retry the
|
| -// connection and instead show an error to the user. So we need to be
|
| -// conservative here. We've seen that some servers will close the socket after
|
| -// as short as 10 seconds. See http://crbug.com/84313 for more details.
|
| -void BrowserMainParts::SocketTimeoutFieldTrial() {
|
| - const base::FieldTrial::Probability kIdleSocketTimeoutDivisor = 100;
|
| - // 1% probability for all experimental settings.
|
| - const base::FieldTrial::Probability kSocketTimeoutProbability = 1;
|
| -
|
| - // After June 30, 2011 builds, it will always be in default group.
|
| - scoped_refptr<base::FieldTrial> socket_timeout_trial(
|
| - new base::FieldTrial("IdleSktToImpact", kIdleSocketTimeoutDivisor,
|
| - "idle_timeout_10", 2011, 6, 30));
|
| - const int socket_timeout_10 = socket_timeout_trial->kDefaultGroupNumber;
|
| -
|
| - const int socket_timeout_5 =
|
| - socket_timeout_trial->AppendGroup("idle_timeout_5",
|
| - kSocketTimeoutProbability);
|
| - const int socket_timeout_20 =
|
| - socket_timeout_trial->AppendGroup("idle_timeout_20",
|
| - kSocketTimeoutProbability);
|
| -
|
| - const int idle_to_trial_group = socket_timeout_trial->group();
|
| -
|
| - if (idle_to_trial_group == socket_timeout_5) {
|
| - net::ClientSocketPool::set_unused_idle_socket_timeout(5);
|
| - } else if (idle_to_trial_group == socket_timeout_10) {
|
| - net::ClientSocketPool::set_unused_idle_socket_timeout(10);
|
| - } else if (idle_to_trial_group == socket_timeout_20) {
|
| - net::ClientSocketPool::set_unused_idle_socket_timeout(20);
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -}
|
| -
|
| -void BrowserMainParts::ProxyConnectionsFieldTrial() {
|
| - const base::FieldTrial::Probability kProxyConnectionsDivisor = 100;
|
| - // 25% probability
|
| - const base::FieldTrial::Probability kProxyConnectionProbability = 1;
|
| -
|
| - // After June 30, 2011 builds, it will always be in default group.
|
| - scoped_refptr<base::FieldTrial> proxy_connection_trial(
|
| - new base::FieldTrial("ProxyConnectionImpact", kProxyConnectionsDivisor,
|
| - "proxy_connections_32", 2011, 6, 30));
|
| -
|
| - // This (32 connections per proxy server) is the current default value.
|
| - // Declaring it here allows us to easily re-assign the probability space while
|
| - // maintaining that the default group always has the remainder of the "share",
|
| - // which allows for cleaner and quicker changes down the line if needed.
|
| - const int proxy_connections_32 = proxy_connection_trial->kDefaultGroupNumber;
|
| -
|
| - // The number of max sockets per group cannot be greater than the max number
|
| - // of sockets per proxy server. We tried using 8, and it can easily
|
| - // lead to total browser stalls.
|
| - const int proxy_connections_16 =
|
| - proxy_connection_trial->AppendGroup("proxy_connections_16",
|
| - kProxyConnectionProbability);
|
| - const int proxy_connections_64 =
|
| - proxy_connection_trial->AppendGroup("proxy_connections_64",
|
| - kProxyConnectionProbability);
|
| -
|
| - const int proxy_connections_trial_group = proxy_connection_trial->group();
|
| -
|
| - if (proxy_connections_trial_group == proxy_connections_16) {
|
| - net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(16);
|
| - } else if (proxy_connections_trial_group == proxy_connections_32) {
|
| - net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(32);
|
| - } else if (proxy_connections_trial_group == proxy_connections_64) {
|
| - net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(64);
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -}
|
| -
|
| -// When --use-spdy not set, users will be in A/B test for spdy.
|
| -// group A (npn_with_spdy): this means npn and spdy are enabled. In case server
|
| -// supports spdy, browser will use spdy.
|
| -// group B (npn_with_http): this means npn is enabled but spdy won't be used.
|
| -// Http is still used for all requests.
|
| -// default group: no npn or spdy is involved. The "old" non-spdy
|
| -// chrome behavior.
|
| -void BrowserMainParts::SpdyFieldTrial() {
|
| - if (parsed_command_line().HasSwitch(switches::kUseSpdy)) {
|
| - std::string spdy_mode =
|
| - parsed_command_line().GetSwitchValueASCII(switches::kUseSpdy);
|
| - net::HttpNetworkLayer::EnableSpdy(spdy_mode);
|
| - } else {
|
| -#if !defined(OS_CHROMEOS)
|
| - bool is_spdy_trial = false;
|
| - const base::FieldTrial::Probability kSpdyDivisor = 100;
|
| - base::FieldTrial::Probability npnhttp_probability = 5;
|
| -
|
| - // After June 30, 2011 builds, it will always be in default group.
|
| - scoped_refptr<base::FieldTrial> trial(
|
| - new base::FieldTrial(
|
| - "SpdyImpact", kSpdyDivisor, "npn_with_spdy", 2011, 6, 30));
|
| -
|
| - // npn with spdy support is the default.
|
| - int npn_spdy_grp = trial->kDefaultGroupNumber;
|
| -
|
| - // npn with only http support, no spdy.
|
| - int npn_http_grp = trial->AppendGroup("npn_with_http", npnhttp_probability);
|
| -
|
| - int trial_grp = trial->group();
|
| - if (trial_grp == npn_http_grp) {
|
| - is_spdy_trial = true;
|
| - net::HttpNetworkLayer::EnableSpdy("npn-http");
|
| - } else if (trial_grp == npn_spdy_grp) {
|
| - is_spdy_trial = true;
|
| - net::HttpNetworkLayer::EnableSpdy("npn");
|
| - } else {
|
| - CHECK(!is_spdy_trial);
|
| - }
|
| -#else
|
| - // Always enable SPDY on Chrome OS
|
| - net::HttpNetworkLayer::EnableSpdy("npn");
|
| -#endif // !defined(OS_CHROMEOS)
|
| - }
|
| -
|
| - // Setup SPDY CWND Field trial.
|
| - const base::FieldTrial::Probability kSpdyCwndDivisor = 100;
|
| - const base::FieldTrial::Probability kSpdyCwnd16 = 20; // fixed at 16
|
| - const base::FieldTrial::Probability kSpdyCwnd10 = 20; // fixed at 10
|
| - const base::FieldTrial::Probability kSpdyCwndMin16 = 20; // no less than 16
|
| - const base::FieldTrial::Probability kSpdyCwndMin10 = 20; // no less than 10
|
| -
|
| - // After June 30, 2011 builds, it will always be in default group
|
| - // (cwndDynamic).
|
| - scoped_refptr<base::FieldTrial> trial(
|
| - new base::FieldTrial(
|
| - "SpdyCwnd", kSpdyCwndDivisor, "cwndDynamic", 2011, 6, 30));
|
| -
|
| - trial->AppendGroup("cwnd10", kSpdyCwnd10);
|
| - trial->AppendGroup("cwnd16", kSpdyCwnd16);
|
| - trial->AppendGroup("cwndMin16", kSpdyCwndMin16);
|
| - trial->AppendGroup("cwndMin10", kSpdyCwndMin10);
|
| -
|
| - if (parsed_command_line().HasSwitch(switches::kMaxSpdyConcurrentStreams)) {
|
| - int value = 0;
|
| - base::StringToInt(parsed_command_line().GetSwitchValueASCII(
|
| - switches::kMaxSpdyConcurrentStreams),
|
| - &value);
|
| - if (value > 0)
|
| - net::SpdySession::set_max_concurrent_streams(value);
|
| - }
|
| -}
|
| -
|
| -// If --socket-reuse-policy is not specified, run an A/B test for choosing the
|
| -// warmest socket.
|
| -void BrowserMainParts::WarmConnectionFieldTrial() {
|
| - const CommandLine& command_line = parsed_command_line();
|
| - if (command_line.HasSwitch(switches::kSocketReusePolicy)) {
|
| - std::string socket_reuse_policy_str = command_line.GetSwitchValueASCII(
|
| - switches::kSocketReusePolicy);
|
| - int policy = -1;
|
| - base::StringToInt(socket_reuse_policy_str, &policy);
|
| -
|
| - const int policy_list[] = { 0, 1, 2 };
|
| - VLOG(1) << "Setting socket_reuse_policy = " << policy;
|
| - SetSocketReusePolicy(policy, policy_list, arraysize(policy_list));
|
| - return;
|
| - }
|
| -
|
| - const base::FieldTrial::Probability kWarmSocketDivisor = 100;
|
| - const base::FieldTrial::Probability kWarmSocketProbability = 33;
|
| -
|
| - // After January 30, 2013 builds, it will always be in default group.
|
| - scoped_refptr<base::FieldTrial> warmest_socket_trial(
|
| - new base::FieldTrial(
|
| - "WarmSocketImpact", kWarmSocketDivisor, "last_accessed_socket",
|
| - 2013, 1, 30));
|
| -
|
| - // Default value is USE_LAST_ACCESSED_SOCKET.
|
| - const int last_accessed_socket = warmest_socket_trial->kDefaultGroupNumber;
|
| - const int warmest_socket = warmest_socket_trial->AppendGroup(
|
| - "warmest_socket", kWarmSocketProbability);
|
| - const int warm_socket = warmest_socket_trial->AppendGroup(
|
| - "warm_socket", kWarmSocketProbability);
|
| -
|
| - const int warmest_socket_trial_group = warmest_socket_trial->group();
|
| -
|
| - const int policy_list[] = { warmest_socket, warm_socket,
|
| - last_accessed_socket };
|
| - SetSocketReusePolicy(warmest_socket_trial_group, policy_list,
|
| - arraysize(policy_list));
|
| -}
|
| -
|
| -// If neither --enable-connect-backup-jobs or --disable-connect-backup-jobs is
|
| -// specified, run an A/B test for automatically establishing backup TCP
|
| -// connections when a certain timeout value is exceeded.
|
| -void BrowserMainParts::ConnectBackupJobsFieldTrial() {
|
| - if (parsed_command_line().HasSwitch(switches::kEnableConnectBackupJobs)) {
|
| - net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
|
| - true);
|
| - } else if (parsed_command_line().HasSwitch(
|
| - switches::kDisableConnectBackupJobs)) {
|
| - net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
|
| - false);
|
| - } else {
|
| - const base::FieldTrial::Probability kConnectBackupJobsDivisor = 100;
|
| - // 1% probability.
|
| - const base::FieldTrial::Probability kConnectBackupJobsProbability = 1;
|
| - // After June 30, 2011 builds, it will always be in default group.
|
| - scoped_refptr<base::FieldTrial> trial(
|
| - new base::FieldTrial("ConnnectBackupJobs",
|
| - kConnectBackupJobsDivisor, "ConnectBackupJobsEnabled", 2011, 6,
|
| - 30));
|
| - const int connect_backup_jobs_enabled = trial->kDefaultGroupNumber;
|
| - trial->AppendGroup("ConnectBackupJobsDisabled",
|
| - kConnectBackupJobsProbability);
|
| - const int trial_group = trial->group();
|
| - net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
|
| - trial_group == connect_backup_jobs_enabled);
|
| - }
|
| -}
|
| -
|
| -// Test the impact on subsequent Google searches of getting suggestions from
|
| -// www.google.TLD instead of clients1.google.TLD.
|
| -void BrowserMainParts::SuggestPrefixFieldTrial() {
|
| - const base::FieldTrial::Probability kSuggestPrefixDivisor = 100;
|
| - // 50% probability.
|
| - const base::FieldTrial::Probability kSuggestPrefixProbability = 50;
|
| - // After Jan 1, 2012, it will always be in default group.
|
| - scoped_refptr<base::FieldTrial> trial(
|
| - new base::FieldTrial("SuggestHostPrefix",
|
| - kSuggestPrefixDivisor, "Default_Prefix", 2012, 1, 1));
|
| - trial->AppendGroup("Www_Prefix", kSuggestPrefixProbability);
|
| - // The field trial is detected directly, so we don't need to call anything.
|
| -}
|
| -
|
| -// BrowserMainParts: |MainMessageLoopStart()| and related ----------------------
|
| -
|
| -void BrowserMainParts::MainMessageLoopStart() {
|
| - PreMainMessageLoopStart();
|
| -
|
| - main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
|
| -
|
| - // TODO(viettrungluu): should these really go before setting the thread name?
|
| - system_monitor_.reset(new base::SystemMonitor);
|
| - hi_res_timer_manager_.reset(new HighResolutionTimerManager);
|
| -
|
| - InitializeMainThread();
|
| -
|
| - network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
|
| -
|
| - PostMainMessageLoopStart();
|
| - Profiling::MainMessageLoopStarted();
|
| -}
|
| -
|
| -void BrowserMainParts::InitializeMainThread() {
|
| - const char* kThreadName = "CrBrowserMain";
|
| - base::PlatformThread::SetName(kThreadName);
|
| - main_message_loop().set_thread_name(kThreadName);
|
| -
|
| - // Register the main thread by instantiating it, but don't call any methods.
|
| - main_thread_.reset(new BrowserThread(BrowserThread::UI,
|
| - MessageLoop::current()));
|
| -}
|
| -
|
| -// BrowserMainParts: |SetupMetricsAndFieldTrials()| related --------------------
|
| -
|
| -// Initializes the metrics service with the configuration for this process,
|
| -// returning the created service (guaranteed non-NULL).
|
| -MetricsService* BrowserMainParts::InitializeMetrics(
|
| - const CommandLine& parsed_command_line,
|
| - const PrefService* local_state) {
|
| -#if defined(OS_WIN)
|
| - if (parsed_command_line.HasSwitch(switches::kChromeFrame))
|
| - MetricsLog::set_version_extension("-F");
|
| -#elif defined(ARCH_CPU_64_BITS)
|
| - MetricsLog::set_version_extension("-64");
|
| -#endif // defined(OS_WIN)
|
| -
|
| - MetricsService* metrics = g_browser_process->metrics_service();
|
| -
|
| - if (parsed_command_line.HasSwitch(switches::kMetricsRecordingOnly) ||
|
| - parsed_command_line.HasSwitch(switches::kEnableBenchmarking)) {
|
| - // If we're testing then we don't care what the user preference is, we turn
|
| - // on recording, but not reporting, otherwise tests fail.
|
| - metrics->StartRecordingOnly();
|
| - return metrics;
|
| - }
|
| -
|
| - // If the user permits metrics reporting with the checkbox in the
|
| - // prefs, we turn on recording. We disable metrics completely for
|
| - // non-official builds.
|
| -#if defined(GOOGLE_CHROME_BUILD)
|
| -#if defined(OS_CHROMEOS)
|
| - bool enabled = chromeos::UserCrosSettingsProvider::cached_reporting_enabled();
|
| -#else
|
| - bool enabled = local_state->GetBoolean(prefs::kMetricsReportingEnabled);
|
| -#endif // #if defined(OS_CHROMEOS)
|
| - if (enabled) {
|
| - metrics->Start();
|
| - }
|
| -#endif // defined(GOOGLE_CHROME_BUILD)
|
| -
|
| - return metrics;
|
| -}
|
| -
|
| -void BrowserMainParts::SetupFieldTrials(bool metrics_recording_enabled,
|
| - bool proxy_policy_is_set) {
|
| - // Note: make sure to call ConnectionFieldTrial() before
|
| - // ProxyConnectionsFieldTrial().
|
| - ConnectionFieldTrial();
|
| - SocketTimeoutFieldTrial();
|
| - // If a policy is defining the number of active connections this field test
|
| - // shoud not be performed.
|
| - if (!proxy_policy_is_set)
|
| - ProxyConnectionsFieldTrial();
|
| - prerender::ConfigurePrefetchAndPrerender(parsed_command_line());
|
| - InstantFieldTrial::Activate();
|
| - SpdyFieldTrial();
|
| - ConnectBackupJobsFieldTrial();
|
| - SuggestPrefixFieldTrial();
|
| - WarmConnectionFieldTrial();
|
| -}
|
| -
|
| -// -----------------------------------------------------------------------------
|
| -// TODO(viettrungluu): move more/rest of BrowserMain() into above structure
|
| -
|
| -namespace {
|
|
|
| // This function provides some ways to test crash and assertion handling
|
| // behavior of the program.
|
| @@ -1274,6 +830,444 @@ bool IsCrashReportingEnabled(const PrefService* local_state) {
|
|
|
| } // namespace
|
|
|
| +// BrowserMainParts ------------------------------------------------------------
|
| +
|
| +BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters)
|
| + : parameters_(parameters),
|
| + parsed_command_line_(parameters.command_line_) {
|
| +}
|
| +
|
| +BrowserMainParts::~BrowserMainParts() {
|
| +}
|
| +
|
| +// BrowserMainParts: |EarlyInitialization()| and related -----------------------
|
| +
|
| +void BrowserMainParts::EarlyInitialization() {
|
| + PreEarlyInitialization();
|
| +
|
| + if (parsed_command_line().HasSwitch(switches::kEnableBenchmarking))
|
| + base::FieldTrial::EnableBenchmarking();
|
| +
|
| + InitializeSSL();
|
| +
|
| + if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart))
|
| + net::SSLConfigService::DisableFalseStart();
|
| + if (parsed_command_line().HasSwitch(switches::kEnableSSLCachedInfo))
|
| + net::SSLConfigService::EnableCachedInfo();
|
| + if (parsed_command_line().HasSwitch(switches::kEnableOriginBoundCerts))
|
| + net::SSLConfigService::EnableOriginBoundCerts();
|
| + if (parsed_command_line().HasSwitch(
|
| + switches::kEnableDNSCertProvenanceChecking)) {
|
| + net::SSLConfigService::EnableDNSCertProvenanceChecking();
|
| + }
|
| +
|
| + // TODO(abarth): Should this move to InitializeNetworkOptions? This doesn't
|
| + // seem dependent on InitializeSSL().
|
| + if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen))
|
| + net::set_tcp_fastopen_enabled(true);
|
| +
|
| + PostEarlyInitialization();
|
| +}
|
| +
|
| +// This will be called after the command-line has been mutated by about:flags
|
| +MetricsService* BrowserMainParts::SetupMetricsAndFieldTrials(
|
| + const CommandLine& parsed_command_line,
|
| + PrefService* local_state) {
|
| + // Must initialize metrics after labs have been converted into switches,
|
| + // but before field trials are set up (so that client ID is available for
|
| + // one-time randomized field trials).
|
| + MetricsService* metrics = InitializeMetrics(parsed_command_line, local_state);
|
| +
|
| + // Initialize FieldTrialList to support FieldTrials that use one-time
|
| + // randomization. The client ID will be empty if the user has not opted
|
| + // to send metrics.
|
| + field_trial_list_.reset(new base::FieldTrialList(metrics->GetClientId()));
|
| +
|
| + SetupFieldTrials(metrics->recording_active(),
|
| + local_state->IsManagedPreference(
|
| + prefs::kMaxConnectionsPerProxy));
|
| +
|
| + // Initialize FieldTrialSynchronizer system. This is a singleton and is used
|
| + // for posting tasks via NewRunnableMethod. Its deleted when it goes out of
|
| + // scope. Even though NewRunnableMethod does AddRef and Release, the object
|
| + // will not be deleted after the Task is executed.
|
| + field_trial_synchronizer_ = new FieldTrialSynchronizer();
|
| +
|
| + return metrics;
|
| +}
|
| +
|
| +// This is an A/B test for the maximum number of persistent connections per
|
| +// host. Currently Chrome, Firefox, and IE8 have this value set at 6. Safari
|
| +// uses 4, and Fasterfox (a plugin for Firefox that supposedly configures it to
|
| +// run faster) uses 8. We would like to see how much of an effect this value has
|
| +// on browsing. Too large a value might cause us to run into SYN flood detection
|
| +// mechanisms.
|
| +void BrowserMainParts::ConnectionFieldTrial() {
|
| + const base::FieldTrial::Probability kConnectDivisor = 100;
|
| + const base::FieldTrial::Probability kConnectProbability = 1; // 1% prob.
|
| +
|
| + // After June 30, 2011 builds, it will always be in default group.
|
| + scoped_refptr<base::FieldTrial> connect_trial(
|
| + new base::FieldTrial(
|
| + "ConnCountImpact", kConnectDivisor, "conn_count_6", 2011, 6, 30));
|
| +
|
| + // This (6) is the current default value. Having this group declared here
|
| + // makes it straightforward to modify |kConnectProbability| such that the same
|
| + // probability value will be assigned to all the other groups, while
|
| + // preserving the remainder of the of probability space to the default value.
|
| + const int connect_6 = connect_trial->kDefaultGroupNumber;
|
| +
|
| + const int connect_5 = connect_trial->AppendGroup("conn_count_5",
|
| + kConnectProbability);
|
| + const int connect_7 = connect_trial->AppendGroup("conn_count_7",
|
| + kConnectProbability);
|
| + const int connect_8 = connect_trial->AppendGroup("conn_count_8",
|
| + kConnectProbability);
|
| + const int connect_9 = connect_trial->AppendGroup("conn_count_9",
|
| + kConnectProbability);
|
| +
|
| + const int connect_trial_group = connect_trial->group();
|
| +
|
| + if (connect_trial_group == connect_5) {
|
| + net::ClientSocketPoolManager::set_max_sockets_per_group(5);
|
| + } else if (connect_trial_group == connect_6) {
|
| + net::ClientSocketPoolManager::set_max_sockets_per_group(6);
|
| + } else if (connect_trial_group == connect_7) {
|
| + net::ClientSocketPoolManager::set_max_sockets_per_group(7);
|
| + } else if (connect_trial_group == connect_8) {
|
| + net::ClientSocketPoolManager::set_max_sockets_per_group(8);
|
| + } else if (connect_trial_group == connect_9) {
|
| + net::ClientSocketPoolManager::set_max_sockets_per_group(9);
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| +// A/B test for determining a value for unused socket timeout. Currently the
|
| +// timeout defaults to 10 seconds. Having this value set too low won't allow us
|
| +// to take advantage of idle sockets. Setting it to too high could possibly
|
| +// result in more ERR_CONNECTION_RESETs, since some servers will kill a socket
|
| +// before we time it out. Since these are "unused" sockets, we won't retry the
|
| +// connection and instead show an error to the user. So we need to be
|
| +// conservative here. We've seen that some servers will close the socket after
|
| +// as short as 10 seconds. See http://crbug.com/84313 for more details.
|
| +void BrowserMainParts::SocketTimeoutFieldTrial() {
|
| + const base::FieldTrial::Probability kIdleSocketTimeoutDivisor = 100;
|
| + // 1% probability for all experimental settings.
|
| + const base::FieldTrial::Probability kSocketTimeoutProbability = 1;
|
| +
|
| + // After June 30, 2011 builds, it will always be in default group.
|
| + scoped_refptr<base::FieldTrial> socket_timeout_trial(
|
| + new base::FieldTrial("IdleSktToImpact", kIdleSocketTimeoutDivisor,
|
| + "idle_timeout_10", 2011, 6, 30));
|
| + const int socket_timeout_10 = socket_timeout_trial->kDefaultGroupNumber;
|
| +
|
| + const int socket_timeout_5 =
|
| + socket_timeout_trial->AppendGroup("idle_timeout_5",
|
| + kSocketTimeoutProbability);
|
| + const int socket_timeout_20 =
|
| + socket_timeout_trial->AppendGroup("idle_timeout_20",
|
| + kSocketTimeoutProbability);
|
| +
|
| + const int idle_to_trial_group = socket_timeout_trial->group();
|
| +
|
| + if (idle_to_trial_group == socket_timeout_5) {
|
| + net::ClientSocketPool::set_unused_idle_socket_timeout(5);
|
| + } else if (idle_to_trial_group == socket_timeout_10) {
|
| + net::ClientSocketPool::set_unused_idle_socket_timeout(10);
|
| + } else if (idle_to_trial_group == socket_timeout_20) {
|
| + net::ClientSocketPool::set_unused_idle_socket_timeout(20);
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| +void BrowserMainParts::ProxyConnectionsFieldTrial() {
|
| + const base::FieldTrial::Probability kProxyConnectionsDivisor = 100;
|
| + // 25% probability
|
| + const base::FieldTrial::Probability kProxyConnectionProbability = 1;
|
| +
|
| + // After June 30, 2011 builds, it will always be in default group.
|
| + scoped_refptr<base::FieldTrial> proxy_connection_trial(
|
| + new base::FieldTrial("ProxyConnectionImpact", kProxyConnectionsDivisor,
|
| + "proxy_connections_32", 2011, 6, 30));
|
| +
|
| + // This (32 connections per proxy server) is the current default value.
|
| + // Declaring it here allows us to easily re-assign the probability space while
|
| + // maintaining that the default group always has the remainder of the "share",
|
| + // which allows for cleaner and quicker changes down the line if needed.
|
| + const int proxy_connections_32 = proxy_connection_trial->kDefaultGroupNumber;
|
| +
|
| + // The number of max sockets per group cannot be greater than the max number
|
| + // of sockets per proxy server. We tried using 8, and it can easily
|
| + // lead to total browser stalls.
|
| + const int proxy_connections_16 =
|
| + proxy_connection_trial->AppendGroup("proxy_connections_16",
|
| + kProxyConnectionProbability);
|
| + const int proxy_connections_64 =
|
| + proxy_connection_trial->AppendGroup("proxy_connections_64",
|
| + kProxyConnectionProbability);
|
| +
|
| + const int proxy_connections_trial_group = proxy_connection_trial->group();
|
| +
|
| + if (proxy_connections_trial_group == proxy_connections_16) {
|
| + net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(16);
|
| + } else if (proxy_connections_trial_group == proxy_connections_32) {
|
| + net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(32);
|
| + } else if (proxy_connections_trial_group == proxy_connections_64) {
|
| + net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(64);
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| +// When --use-spdy not set, users will be in A/B test for spdy.
|
| +// group A (npn_with_spdy): this means npn and spdy are enabled. In case server
|
| +// supports spdy, browser will use spdy.
|
| +// group B (npn_with_http): this means npn is enabled but spdy won't be used.
|
| +// Http is still used for all requests.
|
| +// default group: no npn or spdy is involved. The "old" non-spdy
|
| +// chrome behavior.
|
| +void BrowserMainParts::SpdyFieldTrial() {
|
| + if (parsed_command_line().HasSwitch(switches::kUseSpdy)) {
|
| + std::string spdy_mode =
|
| + parsed_command_line().GetSwitchValueASCII(switches::kUseSpdy);
|
| + net::HttpNetworkLayer::EnableSpdy(spdy_mode);
|
| + } else {
|
| +#if !defined(OS_CHROMEOS)
|
| + bool is_spdy_trial = false;
|
| + const base::FieldTrial::Probability kSpdyDivisor = 100;
|
| + base::FieldTrial::Probability npnhttp_probability = 5;
|
| +
|
| + // After June 30, 2011 builds, it will always be in default group.
|
| + scoped_refptr<base::FieldTrial> trial(
|
| + new base::FieldTrial(
|
| + "SpdyImpact", kSpdyDivisor, "npn_with_spdy", 2011, 6, 30));
|
| +
|
| + // npn with spdy support is the default.
|
| + int npn_spdy_grp = trial->kDefaultGroupNumber;
|
| +
|
| + // npn with only http support, no spdy.
|
| + int npn_http_grp = trial->AppendGroup("npn_with_http", npnhttp_probability);
|
| +
|
| + int trial_grp = trial->group();
|
| + if (trial_grp == npn_http_grp) {
|
| + is_spdy_trial = true;
|
| + net::HttpNetworkLayer::EnableSpdy("npn-http");
|
| + } else if (trial_grp == npn_spdy_grp) {
|
| + is_spdy_trial = true;
|
| + net::HttpNetworkLayer::EnableSpdy("npn");
|
| + } else {
|
| + CHECK(!is_spdy_trial);
|
| + }
|
| +#else
|
| + // Always enable SPDY on Chrome OS
|
| + net::HttpNetworkLayer::EnableSpdy("npn");
|
| +#endif // !defined(OS_CHROMEOS)
|
| + }
|
| +
|
| + // Setup SPDY CWND Field trial.
|
| + const base::FieldTrial::Probability kSpdyCwndDivisor = 100;
|
| + const base::FieldTrial::Probability kSpdyCwnd16 = 20; // fixed at 16
|
| + const base::FieldTrial::Probability kSpdyCwnd10 = 20; // fixed at 10
|
| + const base::FieldTrial::Probability kSpdyCwndMin16 = 20; // no less than 16
|
| + const base::FieldTrial::Probability kSpdyCwndMin10 = 20; // no less than 10
|
| +
|
| + // After June 30, 2011 builds, it will always be in default group
|
| + // (cwndDynamic).
|
| + scoped_refptr<base::FieldTrial> trial(
|
| + new base::FieldTrial(
|
| + "SpdyCwnd", kSpdyCwndDivisor, "cwndDynamic", 2011, 6, 30));
|
| +
|
| + trial->AppendGroup("cwnd10", kSpdyCwnd10);
|
| + trial->AppendGroup("cwnd16", kSpdyCwnd16);
|
| + trial->AppendGroup("cwndMin16", kSpdyCwndMin16);
|
| + trial->AppendGroup("cwndMin10", kSpdyCwndMin10);
|
| +
|
| + if (parsed_command_line().HasSwitch(switches::kMaxSpdyConcurrentStreams)) {
|
| + int value = 0;
|
| + base::StringToInt(parsed_command_line().GetSwitchValueASCII(
|
| + switches::kMaxSpdyConcurrentStreams),
|
| + &value);
|
| + if (value > 0)
|
| + net::SpdySession::set_max_concurrent_streams(value);
|
| + }
|
| +}
|
| +
|
| +// If --socket-reuse-policy is not specified, run an A/B test for choosing the
|
| +// warmest socket.
|
| +void BrowserMainParts::WarmConnectionFieldTrial() {
|
| + const CommandLine& command_line = parsed_command_line();
|
| + if (command_line.HasSwitch(switches::kSocketReusePolicy)) {
|
| + std::string socket_reuse_policy_str = command_line.GetSwitchValueASCII(
|
| + switches::kSocketReusePolicy);
|
| + int policy = -1;
|
| + base::StringToInt(socket_reuse_policy_str, &policy);
|
| +
|
| + const int policy_list[] = { 0, 1, 2 };
|
| + VLOG(1) << "Setting socket_reuse_policy = " << policy;
|
| + SetSocketReusePolicy(policy, policy_list, arraysize(policy_list));
|
| + return;
|
| + }
|
| +
|
| + const base::FieldTrial::Probability kWarmSocketDivisor = 100;
|
| + const base::FieldTrial::Probability kWarmSocketProbability = 33;
|
| +
|
| + // After January 30, 2013 builds, it will always be in default group.
|
| + scoped_refptr<base::FieldTrial> warmest_socket_trial(
|
| + new base::FieldTrial(
|
| + "WarmSocketImpact", kWarmSocketDivisor, "last_accessed_socket",
|
| + 2013, 1, 30));
|
| +
|
| + // Default value is USE_LAST_ACCESSED_SOCKET.
|
| + const int last_accessed_socket = warmest_socket_trial->kDefaultGroupNumber;
|
| + const int warmest_socket = warmest_socket_trial->AppendGroup(
|
| + "warmest_socket", kWarmSocketProbability);
|
| + const int warm_socket = warmest_socket_trial->AppendGroup(
|
| + "warm_socket", kWarmSocketProbability);
|
| +
|
| + const int warmest_socket_trial_group = warmest_socket_trial->group();
|
| +
|
| + const int policy_list[] = { warmest_socket, warm_socket,
|
| + last_accessed_socket };
|
| + SetSocketReusePolicy(warmest_socket_trial_group, policy_list,
|
| + arraysize(policy_list));
|
| +}
|
| +
|
| +// If neither --enable-connect-backup-jobs or --disable-connect-backup-jobs is
|
| +// specified, run an A/B test for automatically establishing backup TCP
|
| +// connections when a certain timeout value is exceeded.
|
| +void BrowserMainParts::ConnectBackupJobsFieldTrial() {
|
| + if (parsed_command_line().HasSwitch(switches::kEnableConnectBackupJobs)) {
|
| + net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
|
| + true);
|
| + } else if (parsed_command_line().HasSwitch(
|
| + switches::kDisableConnectBackupJobs)) {
|
| + net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
|
| + false);
|
| + } else {
|
| + const base::FieldTrial::Probability kConnectBackupJobsDivisor = 100;
|
| + // 1% probability.
|
| + const base::FieldTrial::Probability kConnectBackupJobsProbability = 1;
|
| + // After June 30, 2011 builds, it will always be in default group.
|
| + scoped_refptr<base::FieldTrial> trial(
|
| + new base::FieldTrial("ConnnectBackupJobs",
|
| + kConnectBackupJobsDivisor, "ConnectBackupJobsEnabled", 2011, 6,
|
| + 30));
|
| + const int connect_backup_jobs_enabled = trial->kDefaultGroupNumber;
|
| + trial->AppendGroup("ConnectBackupJobsDisabled",
|
| + kConnectBackupJobsProbability);
|
| + const int trial_group = trial->group();
|
| + net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
|
| + trial_group == connect_backup_jobs_enabled);
|
| + }
|
| +}
|
| +
|
| +// Test the impact on subsequent Google searches of getting suggestions from
|
| +// www.google.TLD instead of clients1.google.TLD.
|
| +void BrowserMainParts::SuggestPrefixFieldTrial() {
|
| + const base::FieldTrial::Probability kSuggestPrefixDivisor = 100;
|
| + // 50% probability.
|
| + const base::FieldTrial::Probability kSuggestPrefixProbability = 50;
|
| + // After Jan 1, 2012, it will always be in default group.
|
| + scoped_refptr<base::FieldTrial> trial(
|
| + new base::FieldTrial("SuggestHostPrefix",
|
| + kSuggestPrefixDivisor, "Default_Prefix", 2012, 1, 1));
|
| + trial->AppendGroup("Www_Prefix", kSuggestPrefixProbability);
|
| + // The field trial is detected directly, so we don't need to call anything.
|
| +}
|
| +
|
| +// BrowserMainParts: |MainMessageLoopStart()| and related ----------------------
|
| +
|
| +void BrowserMainParts::MainMessageLoopStart() {
|
| + PreMainMessageLoopStart();
|
| +
|
| + main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI));
|
| +
|
| + // TODO(viettrungluu): should these really go before setting the thread name?
|
| + system_monitor_.reset(new base::SystemMonitor);
|
| + hi_res_timer_manager_.reset(new HighResolutionTimerManager);
|
| +
|
| + InitializeMainThread();
|
| +
|
| + network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
|
| +
|
| + PostMainMessageLoopStart();
|
| + Profiling::MainMessageLoopStarted();
|
| +}
|
| +
|
| +void BrowserMainParts::InitializeMainThread() {
|
| + const char* kThreadName = "CrBrowserMain";
|
| + base::PlatformThread::SetName(kThreadName);
|
| + main_message_loop().set_thread_name(kThreadName);
|
| +
|
| + // Register the main thread by instantiating it, but don't call any methods.
|
| + main_thread_.reset(new BrowserThread(BrowserThread::UI,
|
| + MessageLoop::current()));
|
| +}
|
| +
|
| +// BrowserMainParts: |SetupMetricsAndFieldTrials()| related --------------------
|
| +
|
| +// Initializes the metrics service with the configuration for this process,
|
| +// returning the created service (guaranteed non-NULL).
|
| +MetricsService* BrowserMainParts::InitializeMetrics(
|
| + const CommandLine& parsed_command_line,
|
| + const PrefService* local_state) {
|
| +#if defined(OS_WIN)
|
| + if (parsed_command_line.HasSwitch(switches::kChromeFrame))
|
| + MetricsLog::set_version_extension("-F");
|
| +#elif defined(ARCH_CPU_64_BITS)
|
| + MetricsLog::set_version_extension("-64");
|
| +#endif // defined(OS_WIN)
|
| +
|
| + MetricsService* metrics = g_browser_process->metrics_service();
|
| +
|
| + if (parsed_command_line.HasSwitch(switches::kMetricsRecordingOnly) ||
|
| + parsed_command_line.HasSwitch(switches::kEnableBenchmarking)) {
|
| + // If we're testing then we don't care what the user preference is, we turn
|
| + // on recording, but not reporting, otherwise tests fail.
|
| + metrics->StartRecordingOnly();
|
| + return metrics;
|
| + }
|
| +
|
| + // If the user permits metrics reporting with the checkbox in the
|
| + // prefs, we turn on recording. We disable metrics completely for
|
| + // non-official builds.
|
| +#if defined(GOOGLE_CHROME_BUILD)
|
| +#if defined(OS_CHROMEOS)
|
| + bool enabled = chromeos::UserCrosSettingsProvider::cached_reporting_enabled();
|
| +#else
|
| + bool enabled = local_state->GetBoolean(prefs::kMetricsReportingEnabled);
|
| +#endif // #if defined(OS_CHROMEOS)
|
| + if (enabled) {
|
| + metrics->Start();
|
| + }
|
| +#endif // defined(GOOGLE_CHROME_BUILD)
|
| +
|
| + return metrics;
|
| +}
|
| +
|
| +void BrowserMainParts::SetupFieldTrials(bool metrics_recording_enabled,
|
| + bool proxy_policy_is_set) {
|
| + // Note: make sure to call ConnectionFieldTrial() before
|
| + // ProxyConnectionsFieldTrial().
|
| + ConnectionFieldTrial();
|
| + SocketTimeoutFieldTrial();
|
| + // If a policy is defining the number of active connections this field test
|
| + // shoud not be performed.
|
| + if (!proxy_policy_is_set)
|
| + ProxyConnectionsFieldTrial();
|
| + prerender::ConfigurePrefetchAndPrerender(parsed_command_line());
|
| + InstantFieldTrial::Activate();
|
| + SpdyFieldTrial();
|
| + ConnectBackupJobsFieldTrial();
|
| + SuggestPrefixFieldTrial();
|
| + WarmConnectionFieldTrial();
|
| +}
|
| +
|
| +// -----------------------------------------------------------------------------
|
| +// TODO(viettrungluu): move more/rest of BrowserMain() into BrowserMainParts.
|
| +
|
| #if defined(OS_CHROMEOS)
|
| // Allows authenticator to be invoked without adding refcounting. The instances
|
| // will delete themselves upon completion.
|
|
|