[email protected] | c4ff495 | 2010-01-08 19:12:47 | [diff] [blame] | 1 | // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
[email protected] | 1152b7e | 2009-09-14 03:26:03 | [diff] [blame] | 5 | #include "chrome/browser/browser_main.h" |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 6 | |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 7 | #include <algorithm> |
[email protected] | 01109dcf | 2010-03-27 00:56:43 | [diff] [blame] | 8 | #include <string> |
| 9 | #include <vector> |
[email protected] | a1a130f7d | 2009-01-09 20:28:44 | [diff] [blame] | 10 | |
[email protected] | 097ae5a | 2009-11-26 19:48:34 | [diff] [blame] | 11 | #include "app/hi_res_timer_manager.h" |
[email protected] | a92b864 | 2009-05-05 23:38:56 | [diff] [blame] | 12 | #include "app/l10n_util.h" |
[email protected] | 9929da9 | 2009-05-05 02:05:11 | [diff] [blame] | 13 | #include "app/resource_bundle.h" |
[email protected] | 097ae5a | 2009-11-26 19:48:34 | [diff] [blame] | 14 | #include "app/system_monitor.h" |
[email protected] | e2cc2e6 | 2010-08-28 00:26:37 | [diff] [blame] | 15 | #include "base/at_exit.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 16 | #include "base/command_line.h" |
[email protected] | 5858035 | 2010-10-26 04:07:50 | [diff] [blame] | 17 | #include "base/debug/trace_event.h" |
[email protected] | f805fe8 | 2010-08-03 22:47:10 | [diff] [blame] | 18 | #include "base/file_path.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 19 | #include "base/file_util.h" |
[email protected] | c2818d4 | 2010-10-18 02:47:39 | [diff] [blame] | 20 | #include "base/mac/scoped_nsautorelease_pool.h" |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 21 | #include "base/metrics/field_trial.h" |
| 22 | #include "base/metrics/histogram.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 23 | #include "base/path_service.h" |
[email protected] | 206d3c4 | 2010-01-19 23:59:20 | [diff] [blame] | 24 | #include "base/platform_thread.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 25 | #include "base/process_util.h" |
[email protected] | e83326f | 2010-07-31 17:29:25 | [diff] [blame] | 26 | #include "base/string_number_conversions.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 27 | #include "base/string_piece.h" |
[email protected] | 4e5ae20f | 2010-09-24 04:52:11 | [diff] [blame] | 28 | #include "base/string_split.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 29 | #include "base/string_util.h" |
[email protected] | 4efe77c | 2009-07-18 03:25:32 | [diff] [blame] | 30 | #include "base/sys_string_conversions.h" |
[email protected] | 6b5f21d | 2009-04-13 17:01:35 | [diff] [blame] | 31 | #include "base/time.h" |
[email protected] | be1ce6a7 | 2010-08-03 14:35:22 | [diff] [blame] | 32 | #include "base/utf_string_conversions.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 33 | #include "base/values.h" |
[email protected] | 01109dcf | 2010-03-27 00:56:43 | [diff] [blame] | 34 | #include "build/build_config.h" |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 35 | #include "chrome/browser/browser.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 36 | #include "chrome/browser/browser_main_win.h" |
[email protected] | a814d863 | 2009-01-31 20:18:52 | [diff] [blame] | 37 | #include "chrome/browser/browser_init.h" |
[email protected] | 37858e5 | 2010-08-26 00:22:02 | [diff] [blame] | 38 | #include "chrome/browser/prefs/browser_prefs.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 39 | #include "chrome/browser/browser_process.h" |
[email protected] | b112a4c | 2009-02-01 20:24:01 | [diff] [blame] | 40 | #include "chrome/browser/browser_process_impl.h" |
[email protected] | 7f0ebc9 | 2009-02-05 18:34:21 | [diff] [blame] | 41 | #include "chrome/browser/browser_shutdown.h" |
[email protected] | ed7e6dd | 2010-10-12 02:02:45 | [diff] [blame] | 42 | #include "chrome/browser/browser_thread.h" |
[email protected] | 62c185a | 2009-02-16 16:59:05 | [diff] [blame] | 43 | #include "chrome/browser/dom_ui/chrome_url_data_manager.h" |
[email protected] | f7e615a | 2009-06-26 19:50:52 | [diff] [blame] | 44 | #include "chrome/browser/extensions/extension_protocols.h" |
[email protected] | c5ae74ab | 2010-04-15 18:14:37 | [diff] [blame] | 45 | #include "chrome/browser/extensions/extensions_service.h" |
[email protected] | 6aeac834 | 2010-10-01 20:21:18 | [diff] [blame] | 46 | #include "chrome/browser/extensions/extensions_startup.h" |
[email protected] | 82073579 | 2010-07-29 23:40:01 | [diff] [blame] | 47 | #include "chrome/browser/first_run/first_run.h" |
[email protected] | 86230b9 | 2009-11-23 20:38:38 | [diff] [blame] | 48 | #include "chrome/browser/jankometer.h" |
[email protected] | 7c927b6 | 2010-02-24 09:54:13 | [diff] [blame] | 49 | #include "chrome/browser/metrics/histogram_synchronizer.h" |
[email protected] | 67908205 | 2010-07-21 21:30:13 | [diff] [blame] | 50 | #include "chrome/browser/metrics/metrics_log.h" |
[email protected] | dc6f496 | 2009-02-13 01:25:50 | [diff] [blame] | 51 | #include "chrome/browser/metrics/metrics_service.h" |
[email protected] | 8107004 | 2010-08-31 02:42:36 | [diff] [blame] | 52 | #include "chrome/browser/net/blob_url_request_job_factory.h" |
[email protected] | 929935b | 2010-09-28 00:40:11 | [diff] [blame] | 53 | #include "chrome/browser/net/predictor_api.h" |
[email protected] | 06fb185 | 2010-09-28 04:52:10 | [diff] [blame] | 54 | #include "chrome/browser/net/metadata_url_request.h" |
[email protected] | 6eb8bc81 | 2009-06-18 21:32:27 | [diff] [blame] | 55 | #include "chrome/browser/net/sdch_dictionary_fetcher.h" |
[email protected] | 7c7377a | 2009-11-11 06:59:38 | [diff] [blame] | 56 | #include "chrome/browser/net/websocket_experiment/websocket_experiment_runner.h" |
[email protected] | fd49e2d | 2009-02-20 17:21:30 | [diff] [blame] | 57 | #include "chrome/browser/plugin_service.h" |
[email protected] | 37858e5 | 2010-08-26 00:22:02 | [diff] [blame] | 58 | #include "chrome/browser/prefs/pref_service.h" |
| 59 | #include "chrome/browser/prefs/pref_value_store.h" |
[email protected] | 17543d6 | 2010-10-07 22:37:38 | [diff] [blame] | 60 | #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" |
[email protected] | e3db4fab | 2009-04-21 21:47:40 | [diff] [blame] | 61 | #include "chrome/browser/process_singleton.h" |
[email protected] | cec1b8d | 2010-03-24 00:21:34 | [diff] [blame] | 62 | #include "chrome/browser/profile.h" |
[email protected] | f7011fcb | 2009-01-28 21:54:32 | [diff] [blame] | 63 | #include "chrome/browser/profile_manager.h" |
[email protected] | 5c23875 | 2009-06-13 10:29:07 | [diff] [blame] | 64 | #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
[email protected] | 2387290 | 2010-10-26 03:43:59 | [diff] [blame] | 65 | #include "chrome/browser/search_engines/search_engine_type.h" |
[email protected] | 8b62334b | 2010-08-31 22:37:11 | [diff] [blame] | 66 | #include "chrome/browser/search_engines/template_url.h" |
[email protected] | 96b3c5c | 2010-04-16 20:30:14 | [diff] [blame] | 67 | #include "chrome/browser/search_engines/template_url_model.h" |
[email protected] | e96bf0c5 | 2010-08-23 23:20:57 | [diff] [blame] | 68 | #include "chrome/browser/service/service_process_control.h" |
| 69 | #include "chrome/browser/service/service_process_control_manager.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 70 | #include "chrome/browser/shell_integration.h" |
[email protected] | 509acb8e | 2010-07-01 20:35:31 | [diff] [blame] | 71 | #include "chrome/browser/translate/translate_manager.h" |
[email protected] | 332e121 | 2010-06-23 22:49:49 | [diff] [blame] | 72 | #include "chrome/common/child_process.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 73 | #include "chrome/common/chrome_constants.h" |
| 74 | #include "chrome/common/chrome_paths.h" |
| 75 | #include "chrome/common/chrome_switches.h" |
[email protected] | 1b084b5e | 2010-08-03 07:58:19 | [diff] [blame] | 76 | #include "chrome/common/env_vars.h" |
[email protected] | ea587b0 | 2010-05-21 15:01:35 | [diff] [blame] | 77 | #include "chrome/common/json_pref_store.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 78 | #include "chrome/common/jstemplate_builder.h" |
[email protected] | 30f547c | 2010-08-04 01:00:01 | [diff] [blame] | 79 | #include "chrome/common/logging_chrome.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 80 | #include "chrome/common/main_function_params.h" |
[email protected] | 64d50ed | 2009-09-22 21:05:47 | [diff] [blame] | 81 | #include "chrome/common/net/net_resource_provider.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 82 | #include "chrome/common/pref_names.h" |
[email protected] | 74d1bb0 | 2009-03-03 00:41:23 | [diff] [blame] | 83 | #include "chrome/common/result_codes.h" |
[email protected] | 1e7377d | 2009-05-28 20:23:06 | [diff] [blame] | 84 | #include "chrome/installer/util/google_update_settings.h" |
[email protected] | cd1c783 | 2009-07-06 20:19:29 | [diff] [blame] | 85 | #include "chrome/installer/util/master_preferences.h" |
[email protected] | ea500fc6 | 2010-03-22 21:34:29 | [diff] [blame] | 86 | #include "grit/app_locale_settings.h" |
[email protected] | 34ac8f3 | 2009-02-22 23:03:27 | [diff] [blame] | 87 | #include "grit/chromium_strings.h" |
| 88 | #include "grit/generated_resources.h" |
[email protected] | 47accfd6 | 2009-05-14 18:46:21 | [diff] [blame] | 89 | #include "net/base/cookie_monster.h" |
[email protected] | 698cccb1 | 2009-03-11 18:47:24 | [diff] [blame] | 90 | #include "net/base/net_module.h" |
[email protected] | 66761b95 | 2010-06-25 21:30:38 | [diff] [blame] | 91 | #include "net/base/network_change_notifier.h" |
[email protected] | 65041fa | 2010-05-21 06:56:53 | [diff] [blame] | 92 | #include "net/http/http_network_layer.h" |
[email protected] | 8e6441ca | 2010-08-19 05:56:38 | [diff] [blame] | 93 | #include "net/http/http_stream_factory.h" |
[email protected] | 1fa4759 | 2009-07-27 22:45:00 | [diff] [blame] | 94 | #include "net/socket/client_socket_pool_base.h" |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 95 | #include "net/socket/client_socket_pool_manager.h" |
[email protected] | 7f7e9239 | 2010-10-26 18:29:29 | [diff] [blame] | 96 | #include "net/socket/tcp_client_socket.h" |
[email protected] | f90a3a5e | 2010-10-25 05:17:24 | [diff] [blame] | 97 | #include "net/spdy/spdy_session.h" |
[email protected] | 4a5e178 | 2010-03-05 20:49:02 | [diff] [blame] | 98 | #include "net/spdy/spdy_session_pool.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 99 | |
[email protected] | ba80aa7 | 2009-09-23 22:12:23 | [diff] [blame] | 100 | #if defined(USE_LINUX_BREAKPAD) |
[email protected] | 7a2ee20 | 2009-10-28 22:54:47 | [diff] [blame] | 101 | #include "base/linux_util.h" |
[email protected] | 9a5d2a5 | 2009-05-22 03:37:45 | [diff] [blame] | 102 | #include "chrome/app/breakpad_linux.h" |
| 103 | #endif |
| 104 | |
[email protected] | 25d47c7b | 2010-02-03 20:13:06 | [diff] [blame] | 105 | #if defined(OS_POSIX) && !defined(OS_MACOSX) |
[email protected] | c6032e8 | 2010-09-13 20:06:05 | [diff] [blame] | 106 | #include "chrome/browser/browser_main_gtk.h" |
[email protected] | 16d51df | 2010-03-02 09:16:44 | [diff] [blame] | 107 | #include "chrome/browser/gtk/gtk_util.h" |
[email protected] | ba80aa7 | 2009-09-23 22:12:23 | [diff] [blame] | 108 | #endif |
| 109 | |
[email protected] | d4fe1fbc | 2010-05-19 17:36:06 | [diff] [blame] | 110 | #if defined(OS_CHROMEOS) |
| 111 | #include "chrome/browser/chromeos/boot_times_loader.h" |
| 112 | #endif |
| 113 | |
[email protected] | 022614ef9 | 2008-12-30 20:50:01 | [diff] [blame] | 114 | // TODO(port): several win-only methods have been pulled out of this, but |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 115 | // BrowserMain() as a whole needs to be broken apart so that it's usable by |
[email protected] | 022614ef9 | 2008-12-30 20:50:01 | [diff] [blame] | 116 | // other platforms. For now, it's just a stub. This is a serious work in |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 117 | // progress and should not be taken as an indication of a real refactoring. |
| 118 | |
| 119 | #if defined(OS_WIN) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 120 | #include <windows.h> |
[email protected] | 1e7377d | 2009-05-28 20:23:06 | [diff] [blame] | 121 | #include <commctrl.h> |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 122 | #include <shellapi.h> |
| 123 | |
[email protected] | ea500fc6 | 2010-03-22 21:34:29 | [diff] [blame] | 124 | #include "app/l10n_util_win.h" |
[email protected] | 4a0765a | 2009-05-08 23:12:25 | [diff] [blame] | 125 | #include "app/win_util.h" |
[email protected] | ac262c9f | 2008-10-19 17:45:21 | [diff] [blame] | 126 | #include "chrome/browser/browser_trial.h" |
[email protected] | cd1adc2 | 2009-01-16 01:29:22 | [diff] [blame] | 127 | #include "chrome/browser/metrics/user_metrics.h" |
[email protected] | f870a32 | 2009-01-16 21:47:27 | [diff] [blame] | 128 | #include "chrome/browser/net/url_fixer_upper.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 129 | #include "chrome/browser/rlz/rlz.h" |
[email protected] | fb8f5e9 | 2008-09-13 19:40:50 | [diff] [blame] | 130 | #include "chrome/browser/views/user_data_dir_dialog.h" |
[email protected] | 6e64343 | 2010-03-10 18:32:14 | [diff] [blame] | 131 | #include "chrome/common/sandbox_policy.h" |
[email protected] | 68c921f | 2008-10-15 21:37:46 | [diff] [blame] | 132 | #include "chrome/installer/util/helper.h" |
| 133 | #include "chrome/installer/util/install_util.h" |
[email protected] | 67da235a | 2008-10-24 16:18:27 | [diff] [blame] | 134 | #include "chrome/installer/util/shell_util.h" |
[email protected] | 68c921f | 2008-10-15 21:37:46 | [diff] [blame] | 135 | #include "chrome/installer/util/version.h" |
[email protected] | c6ac841 | 2010-08-13 16:43:03 | [diff] [blame] | 136 | #include "gfx/platform_font_win.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 137 | #include "net/base/net_util.h" |
[email protected] | 6088942 | 2008-09-23 01:18:16 | [diff] [blame] | 138 | #include "net/base/sdch_manager.h" |
[email protected] | 8ff1d42 | 2009-07-07 21:31:39 | [diff] [blame] | 139 | #include "printing/printed_document.h" |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 140 | #include "sandbox/src/sandbox.h" |
[email protected] | 7f0ebc9 | 2009-02-05 18:34:21 | [diff] [blame] | 141 | #endif // defined(OS_WIN) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 142 | |
[email protected] | 0a357e63 | 2010-04-02 21:26:58 | [diff] [blame] | 143 | #if defined(OS_MACOSX) |
[email protected] | a1e1d490 | 2010-04-02 22:02:30 | [diff] [blame] | 144 | #include <Security/Security.h> |
[email protected] | 0a357e63 | 2010-04-02 21:26:58 | [diff] [blame] | 145 | #include "chrome/browser/cocoa/install_from_dmg.h" |
[email protected] | 3dd6f5e | 2010-06-01 20:28:03 | [diff] [blame] | 146 | #endif |
| 147 | |
[email protected] | fc9c69bf | 2009-08-27 01:10:44 | [diff] [blame] | 148 | #if defined(TOOLKIT_VIEWS) |
[email protected] | a5176da | 2009-07-02 16:21:17 | [diff] [blame] | 149 | #include "chrome/browser/views/chrome_views_delegate.h" |
[email protected] | 148d105 | 2009-07-31 22:53:37 | [diff] [blame] | 150 | #include "views/focus/accelerator_handler.h" |
[email protected] | dd09215 | 2009-05-18 21:20:33 | [diff] [blame] | 151 | #endif |
| 152 | |
[email protected] | 2125f7df | 2009-08-21 01:47:41 | [diff] [blame] | 153 | #if defined(OS_CHROMEOS) |
[email protected] | 268b02f | 2010-02-04 21:07:15 | [diff] [blame] | 154 | #include "chrome/browser/chromeos/cros/cros_library.h" |
[email protected] | a39c2d1 | 2010-05-14 23:48:27 | [diff] [blame] | 155 | #include "chrome/browser/chromeos/cros/screen_lock_library.h" |
[email protected] | c7db33a | 2010-10-06 18:57:25 | [diff] [blame] | 156 | #include "chrome/browser/chromeos/cros_settings_provider_stats.h" |
[email protected] | 368ad4ca | 2010-06-15 16:07:45 | [diff] [blame] | 157 | #include "chrome/browser/chromeos/customization_document.h" |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 158 | #include "chrome/browser/chromeos/external_metrics.h" |
[email protected] | 617fd0d | 2010-08-04 20:05:17 | [diff] [blame] | 159 | #include "chrome/browser/chromeos/login/authenticator.h" |
| 160 | #include "chrome/browser/chromeos/login/login_utils.h" |
[email protected] | a39c2d1 | 2010-05-14 23:48:27 | [diff] [blame] | 161 | #include "chrome/browser/chromeos/login/screen_locker.h" |
[email protected] | ddf8a4b0 | 2010-03-22 23:08:30 | [diff] [blame] | 162 | #include "chrome/browser/chromeos/login/user_manager.h" |
[email protected] | 08e6f6d | 2009-12-14 17:42:12 | [diff] [blame] | 163 | #include "chrome/browser/views/browser_dialogs.h" |
[email protected] | 2125f7df | 2009-08-21 01:47:41 | [diff] [blame] | 164 | #endif |
| 165 | |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 166 | // BrowserMainParts ------------------------------------------------------------ |
| 167 | |
| 168 | BrowserMainParts::BrowserMainParts(const MainFunctionParams& parameters) |
| 169 | : parameters_(parameters), |
| 170 | parsed_command_line_(parameters.command_line_) { |
| 171 | } |
| 172 | |
[email protected] | 1fec6435 | 2010-07-27 13:55:21 | [diff] [blame] | 173 | BrowserMainParts::~BrowserMainParts() { |
| 174 | } |
| 175 | |
| 176 | // BrowserMainParts: |EarlyInitialization()| and related ----------------------- |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 177 | |
| 178 | void BrowserMainParts::EarlyInitialization() { |
| 179 | PreEarlyInitialization(); |
| 180 | |
[email protected] | bba3823 | 2010-08-06 22:55:46 | [diff] [blame] | 181 | // Note: make sure to call ConnectionFieldTrial() before |
| 182 | // ProxyConnectionsFieldTrial(). |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 183 | ConnectionFieldTrial(); |
| 184 | SocketTimeoutFieldTrial(); |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 185 | ProxyConnectionsFieldTrial(); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 186 | SpdyFieldTrial(); |
[email protected] | 8a3125a71 | 2010-08-09 18:58:51 | [diff] [blame] | 187 | PrefetchFieldTrial(); |
[email protected] | 06d9404 | 2010-08-25 01:45:22 | [diff] [blame] | 188 | ConnectBackupJobsFieldTrial(); |
[email protected] | d7dbe28c | 2010-07-29 04:33:47 | [diff] [blame] | 189 | InitializeSSL(); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 190 | |
[email protected] | b2471359 | 2010-08-11 19:50:02 | [diff] [blame] | 191 | if (parsed_command_line().HasSwitch(switches::kEnableDNSSECCerts)) |
| 192 | net::SSLConfigService::EnableDNSSEC(); |
[email protected] | a0deaecf | 2010-08-18 23:39:52 | [diff] [blame] | 193 | if (parsed_command_line().HasSwitch(switches::kDisableSSLFalseStart)) |
| 194 | net::SSLConfigService::DisableFalseStart(); |
[email protected] | 944a0a1 | 2010-08-19 20:02:28 | [diff] [blame] | 195 | if (parsed_command_line().HasSwitch(switches::kAllowSSLMITMProxies)) |
| 196 | net::SSLConfigService::AllowMITMProxies(); |
[email protected] | 4d52f19 | 2010-10-11 17:00:30 | [diff] [blame] | 197 | if (parsed_command_line().HasSwitch(switches::kEnableSnapStart)) |
| 198 | net::SSLConfigService::EnableSnapStart(); |
[email protected] | b2471359 | 2010-08-11 19:50:02 | [diff] [blame] | 199 | |
[email protected] | 7f7e9239 | 2010-10-26 18:29:29 | [diff] [blame] | 200 | if (parsed_command_line().HasSwitch(switches::kEnableTcpFastOpen)) |
| 201 | net::set_tcp_fastopen_enabled(true); |
| 202 | |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 203 | PostEarlyInitialization(); |
| 204 | } |
| 205 | |
| 206 | // This is an A/B test for the maximum number of persistent connections per |
| 207 | // host. Currently Chrome, Firefox, and IE8 have this value set at 6. Safari |
| 208 | // uses 4, and Fasterfox (a plugin for Firefox that supposedly configures it to |
| 209 | // run faster) uses 8. We would like to see how much of an effect this value has |
| 210 | // on browsing. Too large a value might cause us to run into SYN flood detection |
| 211 | // mechanisms. |
| 212 | void BrowserMainParts::ConnectionFieldTrial() { |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 213 | const base::FieldTrial::Probability kConnectDivisor = 100; |
| 214 | const base::FieldTrial::Probability kConnectProbability = 1; // 1% prob. |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 215 | |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 216 | scoped_refptr<base::FieldTrial> connect_trial = |
| 217 | new base::FieldTrial("ConnCountImpact", kConnectDivisor); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 218 | |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 219 | const int connect_5 = connect_trial->AppendGroup("conn_count_5", |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 220 | kConnectProbability); |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 221 | const int connect_7 = connect_trial->AppendGroup("conn_count_7", |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 222 | kConnectProbability); |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 223 | const int connect_8 = connect_trial->AppendGroup("conn_count_8", |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 224 | kConnectProbability); |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 225 | const int connect_9 = connect_trial->AppendGroup("conn_count_9", |
[email protected] | bdf40d1 | 2010-07-28 01:29:41 | [diff] [blame] | 226 | kConnectProbability); |
| 227 | // This (6) is the current default value. Having this group declared here |
| 228 | // makes it straightforward to modify |kConnectProbability| such that the same |
| 229 | // probability value will be assigned to all the other groups, while |
| 230 | // preserving the remainder of the of probability space to the default value. |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 231 | const int connect_6 = connect_trial->AppendGroup("conn_count_6", |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 232 | base::FieldTrial::kAllRemainingProbability); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 233 | |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 234 | const int connect_trial_group = connect_trial->group(); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 235 | |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 236 | if (connect_trial_group == connect_5) { |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 237 | net::ClientSocketPoolManager::set_max_sockets_per_group(5); |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 238 | } else if (connect_trial_group == connect_6) { |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 239 | net::ClientSocketPoolManager::set_max_sockets_per_group(6); |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 240 | } else if (connect_trial_group == connect_7) { |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 241 | net::ClientSocketPoolManager::set_max_sockets_per_group(7); |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 242 | } else if (connect_trial_group == connect_8) { |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 243 | net::ClientSocketPoolManager::set_max_sockets_per_group(8); |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 244 | } else if (connect_trial_group == connect_9) { |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 245 | net::ClientSocketPoolManager::set_max_sockets_per_group(9); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 246 | } else { |
| 247 | NOTREACHED(); |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | // A/B test for determining a value for unused socket timeout. Currently the |
| 252 | // timeout defaults to 10 seconds. Having this value set too low won't allow us |
| 253 | // to take advantage of idle sockets. Setting it to too high could possibly |
| 254 | // result in more ERR_CONNECT_RESETs, requiring one RTT to receive the RST |
| 255 | // packet and possibly another RTT to re-establish the connection. |
| 256 | void BrowserMainParts::SocketTimeoutFieldTrial() { |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 257 | const base::FieldTrial::Probability kIdleSocketTimeoutDivisor = 100; |
[email protected] | 780f849 | 2010-09-16 04:12:15 | [diff] [blame] | 258 | // 1% probability for all experimental settings. |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 259 | const base::FieldTrial::Probability kSocketTimeoutProbability = 1; |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 260 | |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 261 | scoped_refptr<base::FieldTrial> socket_timeout_trial = |
| 262 | new base::FieldTrial("IdleSktToImpact", kIdleSocketTimeoutDivisor); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 263 | |
| 264 | const int socket_timeout_5 = |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 265 | socket_timeout_trial->AppendGroup("idle_timeout_5", |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 266 | kSocketTimeoutProbability); |
[email protected] | 780f849 | 2010-09-16 04:12:15 | [diff] [blame] | 267 | const int socket_timeout_10 = |
| 268 | socket_timeout_trial->AppendGroup("idle_timeout_10", |
| 269 | kSocketTimeoutProbability); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 270 | const int socket_timeout_20 = |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 271 | socket_timeout_trial->AppendGroup("idle_timeout_20", |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 272 | kSocketTimeoutProbability); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 273 | const int socket_timeout_60 = |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 274 | socket_timeout_trial->AppendGroup("idle_timeout_60", |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 275 | base::FieldTrial::kAllRemainingProbability); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 276 | |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 277 | const int idle_to_trial_group = socket_timeout_trial->group(); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 278 | |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 279 | if (idle_to_trial_group == socket_timeout_5) { |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 280 | net::ClientSocketPool::set_unused_idle_socket_timeout(5); |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 281 | } else if (idle_to_trial_group == socket_timeout_10) { |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 282 | net::ClientSocketPool::set_unused_idle_socket_timeout(10); |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 283 | } else if (idle_to_trial_group == socket_timeout_20) { |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 284 | net::ClientSocketPool::set_unused_idle_socket_timeout(20); |
[email protected] | 81c3bae | 2010-07-27 20:13:51 | [diff] [blame] | 285 | } else if (idle_to_trial_group == socket_timeout_60) { |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 286 | net::ClientSocketPool::set_unused_idle_socket_timeout(60); |
| 287 | } else { |
| 288 | NOTREACHED(); |
| 289 | } |
| 290 | } |
| 291 | |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 292 | void BrowserMainParts::ProxyConnectionsFieldTrial() { |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 293 | const base::FieldTrial::Probability kProxyConnectionsDivisor = 100; |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 294 | // 25% probability |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 295 | const base::FieldTrial::Probability kProxyConnectionProbability = 1; |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 296 | |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 297 | scoped_refptr<base::FieldTrial> proxy_connection_trial = |
| 298 | new base::FieldTrial("ProxyConnectionImpact", kProxyConnectionsDivisor); |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 299 | |
[email protected] | bba3823 | 2010-08-06 22:55:46 | [diff] [blame] | 300 | // The number of max sockets per group cannot be greater than the max number |
[email protected] | 8fa6f7d9 | 2010-09-14 16:29:33 | [diff] [blame] | 301 | // of sockets per proxy server. We tried using 8, and it can easily |
| 302 | // lead to total browser stalls. |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 303 | const int proxy_connections_16 = |
[email protected] | 9754649 | 2010-08-09 05:14:49 | [diff] [blame] | 304 | proxy_connection_trial->AppendGroup("proxy_connections_16", |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 305 | kProxyConnectionProbability); |
| 306 | const int proxy_connections_64 = |
[email protected] | 9754649 | 2010-08-09 05:14:49 | [diff] [blame] | 307 | proxy_connection_trial->AppendGroup("proxy_connections_64", |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 308 | kProxyConnectionProbability); |
| 309 | |
| 310 | // This (32 connections per proxy server) is the current default value. |
| 311 | // Declaring it here allows us to easily re-assign the probability space while |
| 312 | // maintaining that the default group always has the remainder of the "share", |
| 313 | // which allows for cleaner and quicker changes down the line if needed. |
| 314 | const int proxy_connections_32 = |
[email protected] | 9754649 | 2010-08-09 05:14:49 | [diff] [blame] | 315 | proxy_connection_trial->AppendGroup("proxy_connections_32", |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 316 | base::FieldTrial::kAllRemainingProbability); |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 317 | |
| 318 | const int proxy_connections_trial_group = proxy_connection_trial->group(); |
| 319 | |
[email protected] | 8fa6f7d9 | 2010-09-14 16:29:33 | [diff] [blame] | 320 | if (proxy_connections_trial_group == proxy_connections_16) { |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 321 | net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(16); |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 322 | } else if (proxy_connections_trial_group == proxy_connections_32) { |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 323 | net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(32); |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 324 | } else if (proxy_connections_trial_group == proxy_connections_64) { |
[email protected] | 2431756e | 2010-09-29 20:26:13 | [diff] [blame] | 325 | net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(64); |
[email protected] | 78a258a | 2010-08-02 16:34:26 | [diff] [blame] | 326 | } else { |
| 327 | NOTREACHED(); |
| 328 | } |
| 329 | } |
| 330 | |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 331 | // When --use-spdy not set, users will be in A/B test for spdy. |
[email protected] | 789d04a | 2010-07-15 21:15:13 | [diff] [blame] | 332 | // group A (npn_with_spdy): this means npn and spdy are enabled. In case server |
| 333 | // supports spdy, browser will use spdy. |
| 334 | // group B (npn_with_http): this means npn is enabled but spdy won't be used. |
| 335 | // Http is still used for all requests. |
| 336 | // default group: no npn or spdy is involved. The "old" non-spdy |
| 337 | // chrome behavior. |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 338 | void BrowserMainParts::SpdyFieldTrial() { |
| 339 | bool is_spdy_trial = false; |
| 340 | if (parsed_command_line().HasSwitch(switches::kUseSpdy)) { |
| 341 | std::string spdy_mode = |
| 342 | parsed_command_line().GetSwitchValueASCII(switches::kUseSpdy); |
| 343 | net::HttpNetworkLayer::EnableSpdy(spdy_mode); |
| 344 | } else { |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 345 | const base::FieldTrial::Probability kSpdyDivisor = 100; |
| 346 | // 10% to preclude SPDY. |
| 347 | base::FieldTrial::Probability npnhttp_probability = 10; |
| 348 | scoped_refptr<base::FieldTrial> trial = |
| 349 | new base::FieldTrial("SpdyImpact", kSpdyDivisor); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 350 | // npn with only http support, no spdy. |
[email protected] | 780f849 | 2010-09-16 04:12:15 | [diff] [blame] | 351 | int npn_http_grp = trial->AppendGroup("npn_with_http", npnhttp_probability); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 352 | // npn with spdy support. |
[email protected] | 780f849 | 2010-09-16 04:12:15 | [diff] [blame] | 353 | int npn_spdy_grp = trial->AppendGroup("npn_with_spdy", |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 354 | base::FieldTrial::kAllRemainingProbability); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 355 | int trial_grp = trial->group(); |
| 356 | if (trial_grp == npn_http_grp) { |
| 357 | is_spdy_trial = true; |
| 358 | net::HttpNetworkLayer::EnableSpdy("npn-http"); |
| 359 | } else if (trial_grp == npn_spdy_grp) { |
| 360 | is_spdy_trial = true; |
| 361 | net::HttpNetworkLayer::EnableSpdy("npn"); |
| 362 | } else { |
| 363 | CHECK(!is_spdy_trial); |
| 364 | } |
| 365 | } |
[email protected] | f90a3a5e | 2010-10-25 05:17:24 | [diff] [blame] | 366 | if (parsed_command_line().HasSwitch(switches::kMaxSpdyConcurrentStreams)) { |
| 367 | int value = 0; |
| 368 | base::StringToInt(parsed_command_line().GetSwitchValueASCII( |
| 369 | switches::kMaxSpdyConcurrentStreams), |
| 370 | &value); |
| 371 | if (value > 0) |
| 372 | net::SpdySession::set_max_concurrent_streams(value); |
| 373 | } |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 374 | } |
| 375 | |
[email protected] | 8a3125a71 | 2010-08-09 18:58:51 | [diff] [blame] | 376 | // If neither --enable-content-prefetch or --disable-content-prefetch |
[email protected] | 780f849 | 2010-09-16 04:12:15 | [diff] [blame] | 377 | // is set, users will not be in an A/B test for prefetching. |
[email protected] | 8a3125a71 | 2010-08-09 18:58:51 | [diff] [blame] | 378 | void BrowserMainParts::PrefetchFieldTrial() { |
| 379 | if (parsed_command_line().HasSwitch(switches::kEnableContentPrefetch)) |
| 380 | ResourceDispatcherHost::set_is_prefetch_enabled(true); |
| 381 | else if (parsed_command_line().HasSwitch(switches::kDisableContentPrefetch)) { |
| 382 | ResourceDispatcherHost::set_is_prefetch_enabled(false); |
| 383 | } else { |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 384 | const base::FieldTrial::Probability kPrefetchDivisor = 1000; |
| 385 | const base::FieldTrial::Probability no_prefetch_probability = 500; |
| 386 | scoped_refptr<base::FieldTrial> trial = |
| 387 | new base::FieldTrial("Prefetch", kPrefetchDivisor); |
[email protected] | 8a3125a71 | 2010-08-09 18:58:51 | [diff] [blame] | 388 | trial->AppendGroup("ContentPrefetchDisabled", no_prefetch_probability); |
| 389 | const int yes_prefetch_grp = |
| 390 | trial->AppendGroup("ContentPrefetchEnabled", |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 391 | base::FieldTrial::kAllRemainingProbability); |
[email protected] | 8a3125a71 | 2010-08-09 18:58:51 | [diff] [blame] | 392 | const int trial_grp = trial->group(); |
| 393 | ResourceDispatcherHost::set_is_prefetch_enabled( |
| 394 | trial_grp == yes_prefetch_grp); |
| 395 | } |
| 396 | } |
| 397 | |
[email protected] | 06d9404 | 2010-08-25 01:45:22 | [diff] [blame] | 398 | // If neither --enable-connect-backup-jobs or --disable-connect-backup-jobs is |
| 399 | // specified, run an A/B test for automatically establishing backup TCP |
| 400 | // connections when a certain timeout value is exceeded. |
| 401 | void BrowserMainParts::ConnectBackupJobsFieldTrial() { |
| 402 | if (parsed_command_line().HasSwitch(switches::kEnableConnectBackupJobs)) { |
| 403 | net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled( |
| 404 | true); |
| 405 | } else if (parsed_command_line().HasSwitch( |
| 406 | switches::kDisableConnectBackupJobs)) { |
| 407 | net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled( |
| 408 | false); |
| 409 | } else { |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 410 | const base::FieldTrial::Probability kConnectBackupJobsDivisor = 100; |
| 411 | // 1% probability. |
| 412 | const base::FieldTrial::Probability kConnectBackupJobsProbability = 1; |
| 413 | scoped_refptr<base::FieldTrial> trial = |
| 414 | new base::FieldTrial("ConnnectBackupJobs", |
| 415 | kConnectBackupJobsDivisor); |
[email protected] | 780f849 | 2010-09-16 04:12:15 | [diff] [blame] | 416 | trial->AppendGroup("ConnectBackupJobsDisabled", |
| 417 | kConnectBackupJobsProbability); |
[email protected] | 06d9404 | 2010-08-25 01:45:22 | [diff] [blame] | 418 | const int connect_backup_jobs_enabled = |
| 419 | trial->AppendGroup("ConnectBackupJobsEnabled", |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 420 | base::FieldTrial::kAllRemainingProbability); |
[email protected] | 06d9404 | 2010-08-25 01:45:22 | [diff] [blame] | 421 | const int trial_group = trial->group(); |
| 422 | net::internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled( |
| 423 | trial_group == connect_backup_jobs_enabled); |
| 424 | } |
| 425 | } |
| 426 | |
[email protected] | 1fec6435 | 2010-07-27 13:55:21 | [diff] [blame] | 427 | // BrowserMainParts: |MainMessageLoopStart()| and related ---------------------- |
| 428 | |
| 429 | void BrowserMainParts::MainMessageLoopStart() { |
| 430 | PreMainMessageLoopStart(); |
| 431 | |
| 432 | main_message_loop_.reset(new MessageLoop(MessageLoop::TYPE_UI)); |
| 433 | |
| 434 | // TODO(viettrungluu): should these really go before setting the thread name? |
| 435 | system_monitor_.reset(new SystemMonitor); |
| 436 | hi_res_timer_manager_.reset(new HighResolutionTimerManager); |
| 437 | network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
| 438 | |
| 439 | InitializeMainThread(); |
| 440 | |
| 441 | PostMainMessageLoopStart(); |
| 442 | } |
| 443 | |
| 444 | void BrowserMainParts::InitializeMainThread() { |
| 445 | const char* kThreadName = "CrBrowserMain"; |
| 446 | PlatformThread::SetName(kThreadName); |
| 447 | main_message_loop().set_thread_name(kThreadName); |
| 448 | |
| 449 | // Register the main thread by instantiating it, but don't call any methods. |
[email protected] | d04e766 | 2010-10-10 22:24:48 | [diff] [blame] | 450 | main_thread_.reset(new BrowserThread(BrowserThread::UI, |
| 451 | MessageLoop::current())); |
[email protected] | 1fec6435 | 2010-07-27 13:55:21 | [diff] [blame] | 452 | } |
| 453 | |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 454 | // ----------------------------------------------------------------------------- |
| 455 | // TODO(viettrungluu): move more/rest of BrowserMain() into above structure |
| 456 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 457 | namespace { |
| 458 | |
| 459 | // This function provides some ways to test crash and assertion handling |
| 460 | // behavior of the program. |
[email protected] | 9bade09 | 2009-11-13 17:04:42 | [diff] [blame] | 461 | void HandleTestParameters(const CommandLine& command_line) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 462 | // This parameter causes an assertion. |
| 463 | if (command_line.HasSwitch(switches::kBrowserAssertTest)) { |
| 464 | DCHECK(false); |
| 465 | } |
| 466 | |
| 467 | // This parameter causes a null pointer crash (crash reporter trigger). |
| 468 | if (command_line.HasSwitch(switches::kBrowserCrashTest)) { |
| 469 | int* bad_pointer = NULL; |
| 470 | *bad_pointer = 0; |
| 471 | } |
[email protected] | 9bade09 | 2009-11-13 17:04:42 | [diff] [blame] | 472 | |
| 473 | #if defined(OS_CHROMEOS) |
| 474 | // Test loading libcros and exit. We return 0 if the library could be loaded, |
| 475 | // and 1 if it can't be. This is for validation that the library is installed |
| 476 | // and versioned properly for Chrome to find. |
| 477 | if (command_line.HasSwitch(switches::kTestLoadLibcros)) |
[email protected] | 62c7ef3 | 2010-03-23 23:44:24 | [diff] [blame] | 478 | exit(!chromeos::CrosLibrary::Get()->EnsureLoaded()); |
[email protected] | 9bade09 | 2009-11-13 17:04:42 | [diff] [blame] | 479 | #endif |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 480 | } |
| 481 | |
[email protected] | d4515eb | 2009-01-30 00:40:43 | [diff] [blame] | 482 | void RunUIMessageLoop(BrowserProcess* browser_process) { |
[email protected] | a872ea1f | 2010-08-11 04:45:33 | [diff] [blame] | 483 | TRACE_EVENT_BEGIN("BrowserMain:MESSAGE_LOOP", 0, ""); |
| 484 | |
[email protected] | 148d105 | 2009-07-31 22:53:37 | [diff] [blame] | 485 | #if defined(TOOLKIT_VIEWS) |
[email protected] | 047f622 | 2009-07-29 23:34:56 | [diff] [blame] | 486 | views::AcceleratorHandler accelerator_handler; |
| 487 | MessageLoopForUI::current()->Run(&accelerator_handler); |
[email protected] | 25d47c7b | 2010-02-03 20:13:06 | [diff] [blame] | 488 | #elif defined(USE_X11) |
[email protected] | 148d105 | 2009-07-31 22:53:37 | [diff] [blame] | 489 | MessageLoopForUI::current()->Run(NULL); |
[email protected] | d4515eb | 2009-01-30 00:40:43 | [diff] [blame] | 490 | #elif defined(OS_POSIX) |
| 491 | MessageLoopForUI::current()->Run(); |
| 492 | #endif |
[email protected] | a872ea1f | 2010-08-11 04:45:33 | [diff] [blame] | 493 | |
| 494 | TRACE_EVENT_END("BrowserMain:MESSAGE_LOOP", 0, ""); |
[email protected] | d4515eb | 2009-01-30 00:40:43 | [diff] [blame] | 495 | } |
| 496 | |
[email protected] | 1188a6c | 2009-05-09 00:27:42 | [diff] [blame] | 497 | void AddFirstRunNewTabs(BrowserInit* browser_init, |
[email protected] | f988638 | 2010-03-10 04:45:54 | [diff] [blame] | 498 | const std::vector<GURL>& new_tabs) { |
| 499 | for (std::vector<GURL>::const_iterator it = new_tabs.begin(); |
[email protected] | 201028d | 2010-02-12 21:28:01 | [diff] [blame] | 500 | it != new_tabs.end(); ++it) { |
[email protected] | f988638 | 2010-03-10 04:45:54 | [diff] [blame] | 501 | if (it->is_valid()) |
| 502 | browser_init->AddFirstRunTab(*it); |
[email protected] | 1188a6c | 2009-05-09 00:27:42 | [diff] [blame] | 503 | } |
| 504 | } |
[email protected] | 1188a6c | 2009-05-09 00:27:42 | [diff] [blame] | 505 | |
[email protected] | ba80aa7 | 2009-09-23 22:12:23 | [diff] [blame] | 506 | #if defined(USE_LINUX_BREAKPAD) |
| 507 | class GetLinuxDistroTask : public Task { |
| 508 | public: |
| 509 | explicit GetLinuxDistroTask() {} |
| 510 | |
| 511 | virtual void Run() { |
| 512 | base::GetLinuxDistro(); // Initialize base::linux_distro if needed. |
| 513 | } |
| 514 | |
| 515 | DISALLOW_COPY_AND_ASSIGN(GetLinuxDistroTask); |
| 516 | }; |
| 517 | #endif // USE_LINUX_BREAKPAD |
[email protected] | ea500fc6 | 2010-03-22 21:34:29 | [diff] [blame] | 518 | |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 519 | void InitializeNetworkOptions(const CommandLine& parsed_command_line) { |
| 520 | if (parsed_command_line.HasSwitch(switches::kEnableFileCookies)) { |
| 521 | // Enable cookie storage for file:// URLs. Must do this before the first |
| 522 | // Profile (and therefore the first CookieMonster) is created. |
| 523 | net::CookieMonster::EnableFileScheme(); |
| 524 | } |
| 525 | |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 526 | if (parsed_command_line.HasSwitch(switches::kIgnoreCertificateErrors)) |
[email protected] | 8e6441ca | 2010-08-19 05:56:38 | [diff] [blame] | 527 | net::HttpStreamFactory::set_ignore_certificate_errors(true); |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 528 | |
[email protected] | b6a5018 | 2010-05-12 22:47:14 | [diff] [blame] | 529 | if (parsed_command_line.HasSwitch(switches::kHostRules)) |
[email protected] | 8e6441ca | 2010-08-19 05:56:38 | [diff] [blame] | 530 | net::HttpStreamFactory::SetHostMappingRules( |
[email protected] | b6a5018 | 2010-05-12 22:47:14 | [diff] [blame] | 531 | parsed_command_line.GetSwitchValueASCII(switches::kHostRules)); |
| 532 | |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 533 | if (parsed_command_line.HasSwitch(switches::kMaxSpdySessionsPerDomain)) { |
[email protected] | e83326f | 2010-07-31 17:29:25 | [diff] [blame] | 534 | int value; |
| 535 | base::StringToInt(parsed_command_line.GetSwitchValueASCII( |
| 536 | switches::kMaxSpdySessionsPerDomain), |
| 537 | &value); |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 538 | net::SpdySessionPool::set_max_sessions_per_domain(value); |
| 539 | } |
| 540 | } |
| 541 | |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 542 | // Creates key child threads. We need to do this explicitly since |
[email protected] | d04e766 | 2010-10-10 22:24:48 | [diff] [blame] | 543 | // BrowserThread::PostTask silently deletes a posted task if the target message |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 544 | // loop isn't created. |
| 545 | void CreateChildThreads(BrowserProcessImpl* process) { |
| 546 | process->db_thread(); |
| 547 | process->file_thread(); |
| 548 | process->process_launcher_thread(); |
[email protected] | 875ee82 | 2010-05-18 20:58:01 | [diff] [blame] | 549 | process->cache_thread(); |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 550 | process->io_thread(); |
| 551 | } |
| 552 | |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 553 | // Returns the new local state object, guaranteed non-NULL. |
| 554 | PrefService* InitializeLocalState(const CommandLine& parsed_command_line, |
| 555 | bool is_first_run) { |
| 556 | FilePath local_state_path; |
| 557 | PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); |
| 558 | bool local_state_file_exists = file_util::PathExists(local_state_path); |
| 559 | |
| 560 | // Load local state. This includes the application locale so we know which |
| 561 | // locale dll to load. |
| 562 | PrefService* local_state = g_browser_process->local_state(); |
| 563 | DCHECK(local_state); |
| 564 | |
| 565 | // Initialize ResourceBundle which handles files loaded from external |
| 566 | // sources. This has to be done before uninstall code path and before prefs |
| 567 | // are registered. |
[email protected] | 20ce516d | 2010-06-18 02:20:04 | [diff] [blame] | 568 | local_state->RegisterStringPref(prefs::kApplicationLocale, ""); |
[email protected] | c7db33a | 2010-10-06 18:57:25 | [diff] [blame] | 569 | #if !defined(OS_CHROMEOS) |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 570 | local_state->RegisterBooleanPref(prefs::kMetricsReportingEnabled, |
| 571 | GoogleUpdateSettings::GetCollectStatsConsent()); |
[email protected] | c7db33a | 2010-10-06 18:57:25 | [diff] [blame] | 572 | #endif // !defined(OS_CHROMEOS) |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 573 | |
| 574 | if (is_first_run) { |
| 575 | #if defined(OS_WIN) |
| 576 | // During first run we read the google_update registry key to find what |
| 577 | // language the user selected when downloading the installer. This |
| 578 | // becomes our default language in the prefs. |
| 579 | // Other platforms obey the system locale. |
| 580 | std::wstring install_lang; |
[email protected] | ddd231e | 2010-06-29 20:35:19 | [diff] [blame] | 581 | if (GoogleUpdateSettings::GetLanguage(&install_lang)) { |
| 582 | local_state->SetString(prefs::kApplicationLocale, |
| 583 | WideToASCII(install_lang)); |
| 584 | } |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 585 | #endif // defined(OS_WIN) |
| 586 | } |
| 587 | |
| 588 | // If the local state file for the current profile doesn't exist and the |
| 589 | // parent profile command line flag is present, then we should inherit some |
| 590 | // local state from the parent profile. |
| 591 | // Checking that the local state file for the current profile doesn't exist |
| 592 | // is the most robust way to determine whether we need to inherit or not |
| 593 | // since the parent profile command line flag can be present even when the |
| 594 | // current profile is not a new one, and in that case we do not want to |
| 595 | // inherit and reset the user's setting. |
| 596 | if (!local_state_file_exists && |
| 597 | parsed_command_line.HasSwitch(switches::kParentProfile)) { |
| 598 | FilePath parent_profile = |
| 599 | parsed_command_line.GetSwitchValuePath(switches::kParentProfile); |
[email protected] | d8b08c9 | 2010-06-07 13:13:28 | [diff] [blame] | 600 | scoped_ptr<PrefService> parent_local_state( |
[email protected] | a9c23a5 | 2010-08-04 09:13:44 | [diff] [blame] | 601 | PrefService::CreatePrefService(parent_profile, NULL)); |
[email protected] | d8b08c9 | 2010-06-07 13:13:28 | [diff] [blame] | 602 | parent_local_state->RegisterStringPref(prefs::kApplicationLocale, |
[email protected] | 20ce516d | 2010-06-18 02:20:04 | [diff] [blame] | 603 | std::string()); |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 604 | // Right now, we only inherit the locale setting from the parent profile. |
| 605 | local_state->SetString( |
| 606 | prefs::kApplicationLocale, |
[email protected] | d8b08c9 | 2010-06-07 13:13:28 | [diff] [blame] | 607 | parent_local_state->GetString(prefs::kApplicationLocale)); |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 608 | } |
| 609 | |
| 610 | return local_state; |
| 611 | } |
| 612 | |
[email protected] | 60626da | 2010-03-25 17:06:53 | [diff] [blame] | 613 | // Windows-specific initialization code for the sandbox broker services. This |
| 614 | // is just a NOP on non-Windows platforms to reduce ifdefs later on. |
| 615 | void InitializeBrokerServices(const MainFunctionParams& parameters, |
| 616 | const CommandLine& parsed_command_line) { |
| 617 | #if defined(OS_WIN) |
| 618 | sandbox::BrokerServices* broker_services = |
| 619 | parameters.sandbox_info_.BrokerServices(); |
| 620 | if (broker_services) { |
| 621 | sandbox::InitBrokerServices(broker_services); |
| 622 | if (!parsed_command_line.HasSwitch(switches::kNoSandbox)) { |
| 623 | bool use_winsta = !parsed_command_line.HasSwitch( |
| 624 | switches::kDisableAltWinstation); |
| 625 | // Precreate the desktop and window station used by the renderers. |
| 626 | sandbox::TargetPolicy* policy = broker_services->CreatePolicy(); |
| 627 | sandbox::ResultCode result = policy->CreateAlternateDesktop(use_winsta); |
| 628 | CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result); |
| 629 | policy->Release(); |
| 630 | } |
| 631 | } |
| 632 | #endif |
| 633 | } |
| 634 | |
| 635 | // Initializes the metrics service with the configuration for this process, |
| 636 | // returning the created service (guaranteed non-NULL). |
[email protected] | 838e1a9 | 2010-03-25 17:47:45 | [diff] [blame] | 637 | MetricsService* InitializeMetrics(const CommandLine& parsed_command_line, |
| 638 | const PrefService* local_state) { |
[email protected] | 60626da | 2010-03-25 17:06:53 | [diff] [blame] | 639 | #if defined(OS_WIN) |
| 640 | if (InstallUtil::IsChromeFrameProcess()) |
| 641 | MetricsLog::set_version_extension("-F"); |
| 642 | #elif defined(ARCH_CPU_64_BITS) |
| 643 | MetricsLog::set_version_extension("-64"); |
| 644 | #endif // defined(OS_WIN) |
| 645 | |
| 646 | MetricsService* metrics = g_browser_process->metrics_service(); |
| 647 | |
| 648 | if (parsed_command_line.HasSwitch(switches::kMetricsRecordingOnly)) { |
| 649 | // If we're testing then we don't care what the user preference is, we turn |
| 650 | // on recording, but not reporting, otherwise tests fail. |
| 651 | metrics->StartRecordingOnly(); |
| 652 | } else { |
| 653 | // If the user permits metrics reporting with the checkbox in the |
| 654 | // prefs, we turn on recording. We disable metrics completely for |
| 655 | // non-official builds. |
| 656 | #if defined(GOOGLE_CHROME_BUILD) |
[email protected] | c7db33a | 2010-10-06 18:57:25 | [diff] [blame] | 657 | #if defined(OS_CHROMEOS) |
| 658 | bool enabled = chromeos::MetricsCrosSettingsProvider::GetMetricsStatus(); |
| 659 | #else |
[email protected] | 60626da | 2010-03-25 17:06:53 | [diff] [blame] | 660 | bool enabled = local_state->GetBoolean(prefs::kMetricsReportingEnabled); |
[email protected] | c7db33a | 2010-10-06 18:57:25 | [diff] [blame] | 661 | #endif // #if defined(OS_CHROMEOS) |
[email protected] | 60626da | 2010-03-25 17:06:53 | [diff] [blame] | 662 | metrics->SetUserPermitsUpload(enabled); |
[email protected] | f48ef03 | 2010-05-20 04:53:11 | [diff] [blame] | 663 | if (enabled) { |
[email protected] | 60626da | 2010-03-25 17:06:53 | [diff] [blame] | 664 | metrics->Start(); |
[email protected] | f48ef03 | 2010-05-20 04:53:11 | [diff] [blame] | 665 | chrome_browser_net_websocket_experiment:: |
| 666 | WebSocketExperimentRunner::Start(); |
| 667 | } |
[email protected] | 60626da | 2010-03-25 17:06:53 | [diff] [blame] | 668 | #endif |
| 669 | } |
| 670 | |
| 671 | return metrics; |
| 672 | } |
| 673 | |
[email protected] | 20271f3 | 2010-03-26 03:04:51 | [diff] [blame] | 674 | // Initializes the profile, possibly doing some user prompting to pick a |
| 675 | // fallback profile. Returns the newly created profile, or NULL if startup |
| 676 | // should not continue. |
| 677 | Profile* CreateProfile(const MainFunctionParams& parameters, |
| 678 | const FilePath& user_data_dir) { |
| 679 | Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile( |
| 680 | user_data_dir); |
| 681 | if (profile) |
| 682 | return profile; |
| 683 | |
| 684 | #if defined(OS_WIN) |
| 685 | // Ideally, we should be able to run w/o access to disk. For now, we |
| 686 | // prompt the user to pick a different user-data-dir and restart chrome |
| 687 | // with the new dir. |
| 688 | // http://code.google.com/p/chromium/issues/detail?id=11510 |
| 689 | FilePath new_user_data_dir = UserDataDirDialog::RunUserDataDirDialog( |
| 690 | user_data_dir); |
| 691 | if (!parameters.ui_task && browser_shutdown::delete_resources_on_shutdown) { |
| 692 | // Only delete the resources if we're not running tests. If we're running |
| 693 | // tests the resources need to be reused as many places in the UI cache |
| 694 | // SkBitmaps from the ResourceBundle. |
| 695 | ResourceBundle::CleanupSharedInstance(); |
| 696 | } |
| 697 | |
| 698 | if (!new_user_data_dir.empty()) { |
| 699 | // Because of the way CommandLine parses, it's sufficient to append a new |
| 700 | // --user-data-dir switch. The last flag of the same name wins. |
| 701 | // TODO(tc): It would be nice to remove the flag we don't want, but that |
| 702 | // sounds risky if we parse differently than CommandLineToArgvW. |
| 703 | CommandLine new_command_line = parameters.command_line_; |
[email protected] | 4f08c83f | 2010-07-29 23:02:34 | [diff] [blame] | 704 | new_command_line.AppendSwitchPath(switches::kUserDataDir, |
| 705 | new_user_data_dir); |
[email protected] | 20271f3 | 2010-03-26 03:04:51 | [diff] [blame] | 706 | base::LaunchApp(new_command_line, false, false, NULL); |
| 707 | } |
| 708 | #else |
| 709 | // TODO(port): fix this. See comments near the definition of |
| 710 | // user_data_dir. It is better to CHECK-fail here than it is to |
| 711 | // silently exit because of missing code in the above test. |
| 712 | CHECK(profile) << "Cannot get default profile."; |
| 713 | #endif |
| 714 | |
| 715 | return NULL; |
| 716 | } |
| 717 | |
[email protected] | ea500fc6 | 2010-03-22 21:34:29 | [diff] [blame] | 718 | #if defined(OS_WIN) |
| 719 | |
| 720 | // gfx::Font callbacks |
| 721 | void AdjustUIFont(LOGFONT* logfont) { |
| 722 | l10n_util::AdjustUIFont(logfont); |
| 723 | } |
| 724 | |
| 725 | int GetMinimumFontSize() { |
[email protected] | b1a71cc | 2010-08-03 15:21:27 | [diff] [blame] | 726 | int min_font_size; |
| 727 | base::StringToInt(l10n_util::GetStringUTF16(IDS_MINIMUM_UI_FONT_SIZE), |
| 728 | &min_font_size); |
| 729 | return min_font_size; |
[email protected] | ea500fc6 | 2010-03-22 21:34:29 | [diff] [blame] | 730 | } |
| 731 | |
[email protected] | c9e1715c | 2010-09-09 04:36:52 | [diff] [blame] | 732 | #elif defined(OS_CHROMEOS) |
| 733 | // Changes the UI font if non-default font name is specified in |
| 734 | // IDS_UI_FONT_FAMILY_CROS. This is necessary as the default font |
| 735 | // specified in /etc/gtk-2.0/gtrkc may not work well for some languages |
| 736 | // For instance, ChromeDroidSans does not work well for Japanese users, |
| 737 | // since Chinese glyphs are used for Kanji characters. |
| 738 | void MaybeChangeUIFont() { |
| 739 | const std::string font_name = |
| 740 | l10n_util::GetStringUTF8(IDS_UI_FONT_FAMILY_CROS); |
| 741 | // The font name should not be empty here, but just in case. |
| 742 | if (font_name == "default" || font_name.empty()) { |
| 743 | return; |
| 744 | } |
| 745 | gtk_util::SetGtkFont(font_name); |
| 746 | } |
[email protected] | ea500fc6 | 2010-03-22 21:34:29 | [diff] [blame] | 747 | #endif |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 748 | |
| 749 | #if defined(TOOLKIT_GTK) |
| 750 | void InitializeToolkit() { |
| 751 | // It is important for this to happen before the first run dialog, as it |
| 752 | // styles the dialog as well. |
| 753 | gtk_util::InitRCStyles(); |
| 754 | } |
| 755 | #elif defined(TOOLKIT_VIEWS) |
| 756 | void InitializeToolkit() { |
| 757 | // The delegate needs to be set before any UI is created so that windows |
| 758 | // display the correct icon. |
| 759 | if (!views::ViewsDelegate::views_delegate) |
| 760 | views::ViewsDelegate::views_delegate = new ChromeViewsDelegate; |
| 761 | |
| 762 | #if defined(OS_WIN) |
[email protected] | c6ac841 | 2010-08-13 16:43:03 | [diff] [blame] | 763 | gfx::PlatformFontWin::adjust_font_callback = &AdjustUIFont; |
| 764 | gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize; |
[email protected] | 20271f3 | 2010-03-26 03:04:51 | [diff] [blame] | 765 | |
| 766 | // Init common control sex. |
| 767 | INITCOMMONCONTROLSEX config; |
| 768 | config.dwSize = sizeof(config); |
| 769 | config.dwICC = ICC_WIN95_CLASSES; |
| 770 | InitCommonControlsEx(&config); |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 771 | #endif |
| 772 | } |
| 773 | #else |
| 774 | void InitializeToolkit() { |
| 775 | } |
| 776 | #endif |
| 777 | |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 778 | #if defined(OS_CHROMEOS) |
[email protected] | 368ad4ca | 2010-06-15 16:07:45 | [diff] [blame] | 779 | |
[email protected] | 617fd0d | 2010-08-04 20:05:17 | [diff] [blame] | 780 | // Class is used to login using passed username and password. |
| 781 | // The instance will be deleted upon success or failure. |
| 782 | class StubLogin : public chromeos::LoginStatusConsumer { |
| 783 | public: |
| 784 | explicit StubLogin(std::string username, std::string password) { |
| 785 | authenticator_ = chromeos::LoginUtils::Get()->CreateAuthenticator(this); |
| 786 | authenticator_.get()->AuthenticateToLogin( |
| 787 | g_browser_process->profile_manager()->GetDefaultProfile(), |
| 788 | username, |
| 789 | password, |
| 790 | std::string(), |
| 791 | std::string()); |
| 792 | } |
| 793 | |
[email protected] | 99074c5 | 2010-08-19 18:44:19 | [diff] [blame] | 794 | void OnLoginFailure(const chromeos::LoginFailure& error) { |
| 795 | LOG(ERROR) << "Login Failure: " << error.GetErrorString(); |
[email protected] | 617fd0d | 2010-08-04 20:05:17 | [diff] [blame] | 796 | delete this; |
| 797 | } |
| 798 | |
| 799 | void OnLoginSuccess(const std::string& username, |
[email protected] | 22b33744 | 2010-10-05 16:27:37 | [diff] [blame] | 800 | const GaiaAuthConsumer::ClientLoginResult& credentials, |
| 801 | bool pending_requests) { |
[email protected] | 617fd0d | 2010-08-04 20:05:17 | [diff] [blame] | 802 | chromeos::LoginUtils::Get()->CompleteLogin(username, credentials); |
| 803 | delete this; |
| 804 | } |
| 805 | |
| 806 | scoped_refptr<chromeos::Authenticator> authenticator_; |
| 807 | }; |
| 808 | |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 809 | void OptionallyRunChromeOSLoginManager(const CommandLine& parsed_command_line) { |
| 810 | if (parsed_command_line.HasSwitch(switches::kLoginManager)) { |
| 811 | std::string first_screen = |
| 812 | parsed_command_line.GetSwitchValueASCII(switches::kLoginScreen); |
| 813 | std::string size_arg = |
| 814 | parsed_command_line.GetSwitchValueASCII( |
| 815 | switches::kLoginScreenSize); |
| 816 | gfx::Size size(0, 0); |
| 817 | // Allow the size of the login window to be set explicitly. If not set, |
| 818 | // default to the entire screen. This is mostly useful for testing. |
| 819 | if (size_arg.size()) { |
| 820 | std::vector<std::string> dimensions; |
[email protected] | 76eb024 | 2010-10-14 00:35:36 | [diff] [blame] | 821 | base::SplitString(size_arg, ',', &dimensions); |
[email protected] | e83326f | 2010-07-31 17:29:25 | [diff] [blame] | 822 | if (dimensions.size() == 2) { |
| 823 | int width, height; |
| 824 | if (base::StringToInt(dimensions[0], &width) && |
| 825 | base::StringToInt(dimensions[1], &height)) |
| 826 | size.SetSize(width, height); |
| 827 | } |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 828 | } |
| 829 | browser::ShowLoginWizard(first_screen, size); |
[email protected] | 617fd0d | 2010-08-04 20:05:17 | [diff] [blame] | 830 | } else if (parsed_command_line.HasSwitch(switches::kLoginUser) && |
| 831 | parsed_command_line.HasSwitch(switches::kLoginPassword)) { |
[email protected] | cddf7b38 | 2010-10-21 22:17:38 | [diff] [blame] | 832 | chromeos::BootTimesLoader::Get()->RecordLoginAttempted(); |
[email protected] | 617fd0d | 2010-08-04 20:05:17 | [diff] [blame] | 833 | new StubLogin( |
| 834 | parsed_command_line.GetSwitchValueASCII(switches::kLoginUser), |
| 835 | parsed_command_line.GetSwitchValueASCII(switches::kLoginPassword)); |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 836 | } |
| 837 | } |
[email protected] | 368ad4ca | 2010-06-15 16:07:45 | [diff] [blame] | 838 | |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 839 | #else |
[email protected] | 368ad4ca | 2010-06-15 16:07:45 | [diff] [blame] | 840 | |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 841 | void OptionallyRunChromeOSLoginManager(const CommandLine& parsed_command_line) { |
| 842 | // Dummy empty function for non-ChromeOS builds to avoid extra ifdefs below. |
| 843 | } |
[email protected] | 368ad4ca | 2010-06-15 16:07:45 | [diff] [blame] | 844 | |
[email protected] | 368ad4ca | 2010-06-15 16:07:45 | [diff] [blame] | 845 | #endif // defined(OS_CHROMEOS) |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 846 | |
[email protected] | e457f74 | 2010-04-02 17:25:43 | [diff] [blame] | 847 | #if defined(OS_MACOSX) |
| 848 | OSStatus KeychainCallback(SecKeychainEvent keychain_event, |
| 849 | SecKeychainCallbackInfo *info, void *context) { |
| 850 | return noErr; |
| 851 | } |
| 852 | #endif |
| 853 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 854 | } // namespace |
| 855 | |
[email protected] | 617fd0d | 2010-08-04 20:05:17 | [diff] [blame] | 856 | #if defined(OS_CHROMEOS) |
| 857 | // Allows authenticator to be invoked without adding refcounting. The instances |
| 858 | // will delete themselves upon completion. |
| 859 | DISABLE_RUNNABLE_METHOD_REFCOUNT(StubLogin); |
| 860 | #endif |
| 861 | |
[email protected] | 3cdacd4 | 2010-04-30 18:55:53 | [diff] [blame] | 862 | #if defined(OS_WIN) |
| 863 | #define DLLEXPORT __declspec(dllexport) |
| 864 | |
| 865 | // We use extern C for the prototype DLLEXPORT to avoid C++ name mangling. |
| 866 | extern "C" { |
| 867 | DLLEXPORT void __cdecl RelaunchChromeBrowserWithNewCommandLineIfNeeded(); |
| 868 | } |
| 869 | |
| 870 | DLLEXPORT void __cdecl RelaunchChromeBrowserWithNewCommandLineIfNeeded() { |
[email protected] | e2cc2e6 | 2010-08-28 00:26:37 | [diff] [blame] | 871 | // Need an instance of AtExitManager to handle singleton creations and |
| 872 | // deletions. We need this new instance because, the old instance created |
| 873 | // in ChromeMain() got destructed when the function returned. |
| 874 | base::AtExitManager exit_manager; |
[email protected] | 3cdacd4 | 2010-04-30 18:55:53 | [diff] [blame] | 875 | Upgrade::RelaunchChromeBrowserWithNewCommandLineIfNeeded(); |
| 876 | } |
| 877 | #endif |
| 878 | |
[email protected] | a16579a | 2010-10-14 18:41:55 | [diff] [blame] | 879 | #if defined(USE_LINUX_BREAKPAD) |
| 880 | bool IsMetricsReportingEnabled(const PrefService* local_state) { |
| 881 | // Check whether we should initialize the crash reporter. It may be disabled |
| 882 | // through configuration policy or user preference. The kHeadless environment |
| 883 | // variable overrides the decision, but only if the crash service is under |
| 884 | // control of the user. The CHROME_HEADLESS environment variable is used by QA |
| 885 | // testing infrastructure to switch on generation of crash reports. |
| 886 | #if defined(OS_CHROMEOS) |
| 887 | bool breakpad_enabled = |
| 888 | chromeos::MetricsCrosSettingsProvider::GetMetricsStatus(); |
| 889 | #else |
| 890 | const PrefService::Preference* metrics_reporting_enabled = |
| 891 | local_state->FindPreference(prefs::kMetricsReportingEnabled); |
| 892 | CHECK(metrics_reporting_enabled); |
| 893 | bool breakpad_enabled = |
| 894 | local_state->GetBoolean(prefs::kMetricsReportingEnabled); |
| 895 | if (!breakpad_enabled && metrics_reporting_enabled->IsUserModifiable()) |
| 896 | breakpad_enabled = getenv(env_vars::kHeadless) != NULL; |
| 897 | #endif // #if defined(OS_CHROMEOS) |
| 898 | return breakpad_enabled; |
| 899 | } |
| 900 | #endif // #if defined(USE_LINUX_BREAKPAD) |
| 901 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 902 | // Main routine for running as the Browser process. |
[email protected] | a1a130f7d | 2009-01-09 20:28:44 | [diff] [blame] | 903 | int BrowserMain(const MainFunctionParams& parameters) { |
[email protected] | a872ea1f | 2010-08-11 04:45:33 | [diff] [blame] | 904 | TRACE_EVENT_BEGIN("BrowserMain", 0, ""); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 905 | scoped_ptr<BrowserMainParts> |
| 906 | parts(BrowserMainParts::CreateBrowserMainParts(parameters)); |
| 907 | |
| 908 | parts->EarlyInitialization(); |
[email protected] | 1fec6435 | 2010-07-27 13:55:21 | [diff] [blame] | 909 | parts->MainMessageLoopStart(); |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 910 | |
[email protected] | 1fec6435 | 2010-07-27 13:55:21 | [diff] [blame] | 911 | // WARNING: If we get a WM_ENDSESSION, objects created on the stack here |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 912 | // are NOT deleted. If you need something to run during WM_ENDSESSION add it |
| 913 | // to browser_shutdown::Shutdown or BrowserProcess::EndSession. |
| 914 | |
[email protected] | d7dbe28c | 2010-07-29 04:33:47 | [diff] [blame] | 915 | // !!!!!!!!!! READ ME !!!!!!!!!! |
| 916 | // I (viettrungluu) am in the process of refactoring |BrowserMain()|. If you |
| 917 | // need to add something above this comment, read the documentation in |
| 918 | // browser_main.h. If you need to add something below, please do the |
| 919 | // following: |
| 920 | // - Figure out where you should add your code. Do NOT just pick a random |
| 921 | // location "which works". |
| 922 | // - Document the dependencies apart from compile-time-checkable ones. What |
| 923 | // must happen before your new code is executed? Does your new code need to |
| 924 | // run before something else? Are there performance reasons for executing |
| 925 | // your code at that point? |
| 926 | // - If you need to create a (persistent) object, heap allocate it and keep a |
| 927 | // |scoped_ptr| to it rather than allocating it on the stack. Otherwise |
| 928 | // I'll have to convert your code when I refactor. |
| 929 | // - Unless your new code is just a couple of lines, factor it out into a |
| 930 | // function with a well-defined purpose. Do NOT just add it inline in |
| 931 | // |BrowserMain()|. |
| 932 | // Thanks! |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 933 | |
[email protected] | 1fec6435 | 2010-07-27 13:55:21 | [diff] [blame] | 934 | // TODO(viettrungluu): put the remainder into BrowserMainParts |
| 935 | const CommandLine& parsed_command_line = parameters.command_line_; |
[email protected] | c2818d4 | 2010-10-18 02:47:39 | [diff] [blame] | 936 | base::mac::ScopedNSAutoreleasePool* pool = parameters.autorelease_pool_; |
[email protected] | 206d3c4 | 2010-01-19 23:59:20 | [diff] [blame] | 937 | |
[email protected] | f7011fcb | 2009-01-28 21:54:32 | [diff] [blame] | 938 | FilePath user_data_dir; |
[email protected] | 0c298a5 | 2009-09-25 21:33:52 | [diff] [blame] | 939 | #if defined(OS_WIN) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 940 | PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
[email protected] | 0c298a5 | 2009-09-25 21:33:52 | [diff] [blame] | 941 | #else |
| 942 | // Getting the user data dir can fail if the directory isn't |
| 943 | // creatable, for example; on Windows in code below we bring up a |
| 944 | // dialog prompting the user to pick a different directory. |
| 945 | // However, ProcessSingleton needs a real user_data_dir on Mac/Linux, |
| 946 | // so it's better to fail here than fail mysteriously elsewhere. |
| 947 | CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) |
| 948 | << "Must be able to get user data directory!"; |
| 949 | #endif |
| 950 | |
[email protected] | 7c47ae3e | 2009-02-18 00:34:21 | [diff] [blame] | 951 | ProcessSingleton process_singleton(user_data_dir); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 952 | |
[email protected] | 1d1a51b | 2009-01-29 23:25:08 | [diff] [blame] | 953 | bool is_first_run = FirstRun::IsChromeFirstRun() || |
| 954 | parsed_command_line.HasSwitch(switches::kFirstRun); |
[email protected] | 1d1a51b | 2009-01-29 23:25:08 | [diff] [blame] | 955 | |
[email protected] | 91451171 | 2009-11-23 19:42:33 | [diff] [blame] | 956 | scoped_ptr<BrowserProcessImpl> browser_process; |
[email protected] | 02aae3f | 2010-03-22 22:31:27 | [diff] [blame] | 957 | if (parsed_command_line.HasSwitch(switches::kImport) || |
| 958 | parsed_command_line.HasSwitch(switches::kImportFromFile)) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 959 | // We use different BrowserProcess when importing so no GoogleURLTracker is |
| 960 | // instantiated (as it makes a URLRequest and we don't have an IO thread, |
| 961 | // see bug #1292702). |
| 962 | browser_process.reset(new FirstRunBrowserProcess(parsed_command_line)); |
[email protected] | 1d1a51b | 2009-01-29 23:25:08 | [diff] [blame] | 963 | is_first_run = false; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 964 | } else { |
| 965 | browser_process.reset(new BrowserProcessImpl(parsed_command_line)); |
| 966 | } |
| 967 | |
| 968 | // BrowserProcessImpl's constructor should set g_browser_process. |
| 969 | DCHECK(g_browser_process); |
| 970 | |
[email protected] | 0b4d338 | 2010-07-14 16:13:04 | [diff] [blame] | 971 | // This forces the TabCloseableStateWatcher to be created and, on chromeos, |
| 972 | // register for the notifications it needs to track the closeable state of |
| 973 | // tabs. |
| 974 | g_browser_process->tab_closeable_state_watcher(); |
| 975 | |
[email protected] | 60626da | 2010-03-25 17:06:53 | [diff] [blame] | 976 | // The broker service initialization needs to run early because it will |
| 977 | // initialize the sandbox broker, which requires the process to swap its |
| 978 | // window station. During this time all the UI will be broken. This has to |
| 979 | // run before threads and windows are created. |
| 980 | InitializeBrokerServices(parameters, parsed_command_line); |
[email protected] | ff608eb | 2009-05-20 16:05:56 | [diff] [blame] | 981 | |
[email protected] | a2dd1a60 | 2010-09-20 23:09:27 | [diff] [blame] | 982 | // Initialize histogram statistics gathering system. |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 983 | base::StatisticsRecorder statistics; |
[email protected] | a2dd1a60 | 2010-09-20 23:09:27 | [diff] [blame] | 984 | |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 985 | PrefService* local_state = InitializeLocalState(parsed_command_line, |
| 986 | is_first_run); |
[email protected] | f253006 | 2008-12-03 23:52:03 | [diff] [blame] | 987 | |
[email protected] | 1b084b5e | 2010-08-03 07:58:19 | [diff] [blame] | 988 | #if defined(USE_LINUX_BREAKPAD) |
| 989 | // Needs to be called after we have chrome::DIR_USER_DATA and |
| 990 | // g_browser_process. |
| 991 | g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE, |
| 992 | new GetLinuxDistroTask()); |
| 993 | |
[email protected] | a16579a | 2010-10-14 18:41:55 | [diff] [blame] | 994 | if (IsMetricsReportingEnabled(local_state)) |
[email protected] | 1b084b5e | 2010-08-03 07:58:19 | [diff] [blame] | 995 | InitCrashReporter(); |
| 996 | #endif |
| 997 | |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 998 | InitializeToolkit(); // Must happen before we try to display any UI. |
[email protected] | f253006 | 2008-12-03 23:52:03 | [diff] [blame] | 999 | |
[email protected] | d4515eb | 2009-01-30 00:40:43 | [diff] [blame] | 1000 | // If we're running tests (ui_task is non-null), then the ResourceBundle |
| 1001 | // has already been initialized. |
[email protected] | ce4b6a9 | 2009-12-10 00:04:48 | [diff] [blame] | 1002 | if (parameters.ui_task) { |
[email protected] | f1b6de2 | 2010-03-06 12:13:47 | [diff] [blame] | 1003 | g_browser_process->SetApplicationLocale("en-US"); |
[email protected] | ce4b6a9 | 2009-12-10 00:04:48 | [diff] [blame] | 1004 | } else { |
[email protected] | 1fec6435 | 2010-07-27 13:55:21 | [diff] [blame] | 1005 | // Mac starts it earlier in |PreMainMessageLoopStart()| (because it is |
| 1006 | // needed when loading the MainMenu.nib and the language doesn't depend on |
| 1007 | // anything since it comes from Cocoa. |
[email protected] | ce4b6a9 | 2009-12-10 00:04:48 | [diff] [blame] | 1008 | #if defined(OS_MACOSX) |
[email protected] | f1b6de2 | 2010-03-06 12:13:47 | [diff] [blame] | 1009 | g_browser_process->SetApplicationLocale(l10n_util::GetLocaleOverride()); |
[email protected] | ce4b6a9 | 2009-12-10 00:04:48 | [diff] [blame] | 1010 | #else |
[email protected] | d90de1c0 | 2010-07-19 19:50:48 | [diff] [blame] | 1011 | // On a POSIX OS other than ChromeOS, the parameter that is passed to the |
| 1012 | // method InitSharedInstance is ignored. |
[email protected] | ce4b6a9 | 2009-12-10 00:04:48 | [diff] [blame] | 1013 | std::string app_locale = ResourceBundle::InitSharedInstance( |
[email protected] | ff622aa | 2010-08-04 17:07:46 | [diff] [blame] | 1014 | local_state->GetString(prefs::kApplicationLocale)); |
[email protected] | f1b6de2 | 2010-03-06 12:13:47 | [diff] [blame] | 1015 | g_browser_process->SetApplicationLocale(app_locale); |
[email protected] | e1cb0e9 | 2010-06-15 07:23:59 | [diff] [blame] | 1016 | |
| 1017 | FilePath resources_pack_path; |
| 1018 | PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path); |
| 1019 | ResourceBundle::AddDataPackToSharedInstance(resources_pack_path); |
[email protected] | 885b727 | 2009-08-12 20:33:05 | [diff] [blame] | 1020 | #endif // !defined(OS_MACOSX) |
[email protected] | ce4b6a9 | 2009-12-10 00:04:48 | [diff] [blame] | 1021 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1022 | |
[email protected] | 0f13d43 | 2010-07-22 21:30:30 | [diff] [blame] | 1023 | #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_CHROMEOS) |
| 1024 | // gdk_pixbuf_loader_write always fails on chromeos device. |
| 1025 | // Disabling for chromeos as well because chromeos is not using them. |
| 1026 | // http://crosbug.com/4996 . |
[email protected] | d0646f3 | 2009-08-27 00:58:46 | [diff] [blame] | 1027 | gtk_util::SetDefaultWindowIcon(); |
| 1028 | #endif |
| 1029 | |
[email protected] | 5d39e314 | 2009-12-17 05:54:10 | [diff] [blame] | 1030 | std::string try_chrome = |
| 1031 | parsed_command_line.GetSwitchValueASCII(switches::kTryChromeAgain); |
[email protected] | c4b3858c | 2009-09-09 19:35:31 | [diff] [blame] | 1032 | if (!try_chrome.empty()) { |
[email protected] | 28de7d94 | 2010-02-23 01:43:04 | [diff] [blame] | 1033 | #if defined(OS_WIN) |
[email protected] | b1a71cc | 2010-08-03 15:21:27 | [diff] [blame] | 1034 | int try_chrome_int; |
| 1035 | base::StringToInt(try_chrome, &try_chrome_int); |
| 1036 | Upgrade::TryResult answer = Upgrade::ShowTryChromeDialog(try_chrome_int); |
[email protected] | 37a24e0 | 2009-06-12 21:34:14 | [diff] [blame] | 1037 | if (answer == Upgrade::TD_NOT_NOW) |
[email protected] | 42d7510c | 2009-12-19 01:48:30 | [diff] [blame] | 1038 | return ResultCodes::NORMAL_EXIT_CANCEL; |
[email protected] | 37a24e0 | 2009-06-12 21:34:14 | [diff] [blame] | 1039 | if (answer == Upgrade::TD_UNINSTALL_CHROME) |
[email protected] | 3c30f4c1 | 2009-06-19 22:55:47 | [diff] [blame] | 1040 | return ResultCodes::NORMAL_EXIT_EXP2; |
[email protected] | 28de7d94 | 2010-02-23 01:43:04 | [diff] [blame] | 1041 | #else |
| 1042 | // We don't support retention experiments on Mac or Linux. |
| 1043 | return ResultCodes::NORMAL_EXIT; |
| 1044 | #endif // defined(OS_WIN) |
[email protected] | 37a24e0 | 2009-06-12 21:34:14 | [diff] [blame] | 1045 | } |
[email protected] | 37a24e0 | 2009-06-12 21:34:14 | [diff] [blame] | 1046 | |
[email protected] | 1188a6c | 2009-05-09 00:27:42 | [diff] [blame] | 1047 | BrowserInit browser_init; |
| 1048 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 1049 | // On first run, we need to process the predictor preferences before the |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 1050 | // browser's profile_manager object is created, but after ResourceBundle |
| 1051 | // is initialized. |
[email protected] | 2858bbf | 2010-10-05 23:46:02 | [diff] [blame] | 1052 | FirstRun::MasterPrefs master_prefs; |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 1053 | bool first_run_ui_bypass = false; // True to skip first run UI. |
[email protected] | fe247ac | 2009-03-19 00:10:48 | [diff] [blame] | 1054 | if (is_first_run) { |
[email protected] | a5391559 | 2010-02-26 20:21:40 | [diff] [blame] | 1055 | first_run_ui_bypass = |
[email protected] | f851288 | 2010-05-27 00:47:56 | [diff] [blame] | 1056 | !FirstRun::ProcessMasterPreferences(user_data_dir, &master_prefs); |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 1057 | AddFirstRunNewTabs(&browser_init, master_prefs.new_tabs); |
[email protected] | fe247ac | 2009-03-19 00:10:48 | [diff] [blame] | 1058 | |
| 1059 | // If we are running in App mode, we do not want to show the importer |
| 1060 | // (first run) UI. |
[email protected] | 6cf2af2e | 2009-05-05 20:17:25 | [diff] [blame] | 1061 | if (!first_run_ui_bypass && |
| 1062 | (parsed_command_line.HasSwitch(switches::kApp) || |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 1063 | parsed_command_line.HasSwitch(switches::kNoFirstRun))) |
[email protected] | fe247ac | 2009-03-19 00:10:48 | [diff] [blame] | 1064 | first_run_ui_bypass = true; |
| 1065 | } |
| 1066 | |
[email protected] | f8abf72 | 2010-07-07 19:46:24 | [diff] [blame] | 1067 | // TODO(viettrungluu): why don't we run this earlier? |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 1068 | if (!parsed_command_line.HasSwitch(switches::kNoErrorDialogs)) |
| 1069 | WarnAboutMinimumSystemRequirements(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1070 | |
[email protected] | 7e59cff | 2010-03-23 16:12:40 | [diff] [blame] | 1071 | InitializeNetworkOptions(parsed_command_line); |
[email protected] | 4a5e178 | 2010-03-05 20:49:02 | [diff] [blame] | 1072 | |
[email protected] | c9a3ef8 | 2009-05-28 22:02:46 | [diff] [blame] | 1073 | // Initialize histogram synchronizer system. This is a singleton and is used |
| 1074 | // for posting tasks via NewRunnableMethod. Its deleted when it goes out of |
| 1075 | // scope. Even though NewRunnableMethod does AddRef and Release, the object |
| 1076 | // will not be deleted after the Task is executed. |
| 1077 | scoped_refptr<HistogramSynchronizer> histogram_synchronizer = |
| 1078 | new HistogramSynchronizer(); |
| 1079 | |
[email protected] | 9acc4860 | 2009-11-30 21:18:51 | [diff] [blame] | 1080 | // Initialize the prefs of the local state. |
| 1081 | browser::RegisterLocalState(local_state); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1082 | |
[email protected] | 6b5f21d | 2009-04-13 17:01:35 | [diff] [blame] | 1083 | // Now that all preferences have been registered, set the install date |
| 1084 | // for the uninstall metrics if this is our first run. This only actually |
| 1085 | // gets used if the user has metrics reporting enabled at uninstall time. |
| 1086 | int64 install_date = |
| 1087 | local_state->GetInt64(prefs::kUninstallMetricsInstallDate); |
| 1088 | if (install_date == 0) { |
| 1089 | local_state->SetInt64(prefs::kUninstallMetricsInstallDate, |
| 1090 | base::Time::Now().ToTimeT()); |
| 1091 | } |
| 1092 | |
[email protected] | e457f74 | 2010-04-02 17:25:43 | [diff] [blame] | 1093 | #if defined(OS_MACOSX) |
| 1094 | // Get the Keychain API to register for distributed notifications on the main |
| 1095 | // thread, which has a proper CFRunloop, instead of later on the I/O thread, |
| 1096 | // which doesn't. This ensures those notifications will get delivered |
| 1097 | // properly. See issue 37766. |
| 1098 | // (Note that the callback mask here is empty. I don't want to register for |
| 1099 | // any callbacks, I just want to initialize the mechanism.) |
| 1100 | SecKeychainAddCallback(&KeychainCallback, 0, NULL); |
| 1101 | #endif |
| 1102 | |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 1103 | CreateChildThreads(browser_process.get()); |
[email protected] | 61e9572 | 2009-11-25 06:54:11 | [diff] [blame] | 1104 | |
[email protected] | d4fe1fbc | 2010-05-19 17:36:06 | [diff] [blame] | 1105 | #if defined(OS_CHROMEOS) |
| 1106 | // Now that the file thread exists we can record our stats. |
[email protected] | 445a971 | 2010-07-21 15:55:48 | [diff] [blame] | 1107 | chromeos::BootTimesLoader::Get()->RecordChromeMainStats(); |
[email protected] | c9e1715c | 2010-09-09 04:36:52 | [diff] [blame] | 1108 | // Change the UI font if necessary. This has to be done after |
| 1109 | // InitSharedInstance() is called, as it depends on resource data. |
| 1110 | MaybeChangeUIFont(); |
[email protected] | d4fe1fbc | 2010-05-19 17:36:06 | [diff] [blame] | 1111 | #endif |
| 1112 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1113 | // Record last shutdown time into a histogram. |
| 1114 | browser_shutdown::ReadLastShutdownInfo(); |
[email protected] | 04999e6 | 2009-09-25 01:27:31 | [diff] [blame] | 1115 | |
[email protected] | 01109dcf | 2010-03-27 00:56:43 | [diff] [blame] | 1116 | #if defined(OS_WIN) |
[email protected] | 04999e6 | 2009-09-25 01:27:31 | [diff] [blame] | 1117 | // On Windows, we use our startup as an opportunity to do upgrade/uninstall |
| 1118 | // tasks. Those care whether the browser is already running. On Linux/Mac, |
| 1119 | // upgrade/uninstall happen separately. |
| 1120 | bool already_running = Upgrade::IsBrowserAlreadyRunning(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1121 | |
| 1122 | // If the command line specifies 'uninstall' then we need to work here |
| 1123 | // unless we detect another chrome browser running. |
[email protected] | 53c38d23 | 2009-02-13 20:52:18 | [diff] [blame] | 1124 | if (parsed_command_line.HasSwitch(switches::kUninstall)) |
| 1125 | return DoUninstallTasks(already_running); |
[email protected] | 04999e6 | 2009-09-25 01:27:31 | [diff] [blame] | 1126 | #endif |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1127 | |
| 1128 | if (parsed_command_line.HasSwitch(switches::kHideIcons) || |
[email protected] | 201028d | 2010-02-12 21:28:01 | [diff] [blame] | 1129 | parsed_command_line.HasSwitch(switches::kShowIcons)) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1130 | return HandleIconsCommands(parsed_command_line); |
[email protected] | 201028d | 2010-02-12 21:28:01 | [diff] [blame] | 1131 | if (parsed_command_line.HasSwitch(switches::kMakeDefaultBrowser)) { |
| 1132 | return ShellIntegration::SetAsDefaultBrowser() ? |
| 1133 | ResultCodes::NORMAL_EXIT : ResultCodes::SHELL_INTEGRATION_FAILED; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1134 | } |
| 1135 | |
[email protected] | 6aeac834 | 2010-10-01 20:21:18 | [diff] [blame] | 1136 | // If the command line specifies --pack-extension, attempt the pack extension |
| 1137 | // startup action and exit. |
| 1138 | if (parsed_command_line.HasSwitch(switches::kPackExtension)) { |
| 1139 | extensions_startup::HandlePackExtension(parsed_command_line); |
| 1140 | return ResultCodes::NORMAL_EXIT; |
| 1141 | } |
| 1142 | |
[email protected] | 5425d06 | 2010-04-11 23:16:02 | [diff] [blame] | 1143 | #if !defined(OS_MACOSX) |
| 1144 | // In environments other than Mac OS X we support import of settings |
| 1145 | // from other browsers. In case this process is a short-lived "import" |
| 1146 | // process that another browser runs just to import the settings, we |
| 1147 | // don't want to be checking for another browser process, by design. |
[email protected] | a788ae1 | 2010-06-21 20:41:06 | [diff] [blame] | 1148 | if (!(parsed_command_line.HasSwitch(switches::kImport) || |
| 1149 | parsed_command_line.HasSwitch(switches::kImportFromFile))) { |
[email protected] | bd48c2b0 | 2010-04-09 20:32:42 | [diff] [blame] | 1150 | #endif |
[email protected] | 5425d06 | 2010-04-11 23:16:02 | [diff] [blame] | 1151 | // When another process is running, use that process instead of starting a |
| 1152 | // new one. NotifyOtherProcess will currently give the other process up to |
| 1153 | // 20 seconds to respond. Note that this needs to be done before we attempt |
| 1154 | // to read the profile. |
[email protected] | 4a44bc3 | 2010-05-28 22:22:44 | [diff] [blame] | 1155 | switch (process_singleton.NotifyOtherProcessOrCreate()) { |
[email protected] | 5425d06 | 2010-04-11 23:16:02 | [diff] [blame] | 1156 | case ProcessSingleton::PROCESS_NONE: |
| 1157 | // No process already running, fall through to starting a new one. |
| 1158 | break; |
[email protected] | bd48c2b0 | 2010-04-09 20:32:42 | [diff] [blame] | 1159 | |
[email protected] | 5425d06 | 2010-04-11 23:16:02 | [diff] [blame] | 1160 | case ProcessSingleton::PROCESS_NOTIFIED: |
| 1161 | #if defined(OS_POSIX) && !defined(OS_MACOSX) |
| 1162 | printf("%s\n", base::SysWideToNativeMB( |
| 1163 | l10n_util::GetString(IDS_USED_EXISTING_BROWSER)).c_str()); |
| 1164 | #endif |
| 1165 | return ResultCodes::NORMAL_EXIT; |
[email protected] | bd48c2b0 | 2010-04-09 20:32:42 | [diff] [blame] | 1166 | |
[email protected] | 5425d06 | 2010-04-11 23:16:02 | [diff] [blame] | 1167 | case ProcessSingleton::PROFILE_IN_USE: |
| 1168 | return ResultCodes::PROFILE_IN_USE; |
| 1169 | |
[email protected] | 4a44bc3 | 2010-05-28 22:22:44 | [diff] [blame] | 1170 | case ProcessSingleton::LOCK_ERROR: |
| 1171 | LOG(ERROR) << "Failed to create a ProcessSingleton for your profile " |
| 1172 | "directory. This means that running multiple instances " |
| 1173 | "would start multiple browser processes rather than " |
| 1174 | "opening a new window in the existing process. Aborting " |
| 1175 | "now to avoid profile corruption."; |
| 1176 | return ResultCodes::PROFILE_IN_USE; |
| 1177 | |
[email protected] | 5425d06 | 2010-04-11 23:16:02 | [diff] [blame] | 1178 | default: |
| 1179 | NOTREACHED(); |
| 1180 | } |
| 1181 | #if !defined(OS_MACOSX) // closing brace for if |
[email protected] | bd48c2b0 | 2010-04-09 20:32:42 | [diff] [blame] | 1182 | } |
[email protected] | 5425d06 | 2010-04-11 23:16:02 | [diff] [blame] | 1183 | #endif |
[email protected] | bd48c2b0 | 2010-04-09 20:32:42 | [diff] [blame] | 1184 | |
[email protected] | 20271f3 | 2010-03-26 03:04:51 | [diff] [blame] | 1185 | // Profile creation ---------------------------------------------------------- |
[email protected] | 08e6f6d | 2009-12-14 17:42:12 | [diff] [blame] | 1186 | |
[email protected] | d7e4b59d6 | 2010-04-22 21:36:23 | [diff] [blame] | 1187 | #if defined(OS_CHROMEOS) |
[email protected] | 617fd0d | 2010-08-04 20:05:17 | [diff] [blame] | 1188 | // Stub out chromeos implementations. |
| 1189 | if (parsed_command_line.HasSwitch(switches::kStubCros)) |
| 1190 | chromeos::CrosLibrary::Get()->GetTestApi()->SetUseStubImpl(); |
| 1191 | |
[email protected] | 4f51932 | 2010-06-02 22:16:39 | [diff] [blame] | 1192 | // Initialize the screen locker now so that it can receive |
| 1193 | // LOGIN_USER_CHANGED notification from UserManager. |
| 1194 | chromeos::ScreenLocker::InitClass(); |
| 1195 | |
[email protected] | 1172ba7 | 2010-05-21 22:21:11 | [diff] [blame] | 1196 | // This forces the ProfileManager to be created and register for the |
| 1197 | // notification it needs to track the logged in user. |
| 1198 | g_browser_process->profile_manager()->GetDefaultProfile(); |
[email protected] | d7e4b59d6 | 2010-04-22 21:36:23 | [diff] [blame] | 1199 | |
[email protected] | e4d285a | 2010-08-05 21:33:02 | [diff] [blame] | 1200 | // There are two use cases for kLoginUser: |
| 1201 | // 1) if passed in tandem with kLoginPassword, to drive a "StubLogin" |
| 1202 | // 2) if passed alone, to signal that the indicated user has already |
| 1203 | // logged in and we should behave accordingly. |
| 1204 | // This handles case 2. |
| 1205 | if (parsed_command_line.HasSwitch(switches::kLoginUser) && |
| 1206 | !parsed_command_line.HasSwitch(switches::kLoginPassword)) { |
[email protected] | d7e4b59d6 | 2010-04-22 21:36:23 | [diff] [blame] | 1207 | std::string username = |
| 1208 | parsed_command_line.GetSwitchValueASCII(switches::kLoginUser); |
[email protected] | 8e96e50 | 2010-10-21 20:57:12 | [diff] [blame] | 1209 | VLOG(1) << "Relaunching browser for user: " << username; |
[email protected] | d7e4b59d6 | 2010-04-22 21:36:23 | [diff] [blame] | 1210 | chromeos::UserManager::Get()->UserLoggedIn(username); |
[email protected] | 30f547c | 2010-08-04 01:00:01 | [diff] [blame] | 1211 | |
| 1212 | // Redirect logs. |
| 1213 | FilePath user_data_dir; |
| 1214 | PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
| 1215 | ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 1216 | // The default profile will have been changed because the ProfileManager |
| 1217 | // will process the notification that the UserManager sends out. |
| 1218 | |
| 1219 | logging::RedirectChromeLogging( |
| 1220 | user_data_dir.Append(profile_manager->GetCurrentProfileDir()), |
| 1221 | *(CommandLine::ForCurrentProcess()), |
| 1222 | logging::DELETE_OLD_LOG_FILE); |
[email protected] | d7e4b59d6 | 2010-04-22 21:36:23 | [diff] [blame] | 1223 | } |
| 1224 | #endif |
| 1225 | |
[email protected] | c6032e8 | 2010-09-13 20:06:05 | [diff] [blame] | 1226 | #if defined(USE_X11) |
| 1227 | SetBrowserX11ErrorHandlers(); |
| 1228 | #endif |
| 1229 | |
[email protected] | 1a47d7e | 2010-10-15 00:37:24 | [diff] [blame] | 1230 | // Modifies the current command line based on active experiments on |
| 1231 | // about:flags. |
[email protected] | 20271f3 | 2010-03-26 03:04:51 | [diff] [blame] | 1232 | Profile* profile = CreateProfile(parameters, user_data_dir); |
| 1233 | if (!profile) |
[email protected] | 9acc4860 | 2009-11-30 21:18:51 | [diff] [blame] | 1234 | return ResultCodes::NORMAL_EXIT; |
[email protected] | 20271f3 | 2010-03-26 03:04:51 | [diff] [blame] | 1235 | |
| 1236 | // Post-profile init --------------------------------------------------------- |
[email protected] | 9acc4860 | 2009-11-30 21:18:51 | [diff] [blame] | 1237 | |
| 1238 | PrefService* user_prefs = profile->GetPrefs(); |
| 1239 | DCHECK(user_prefs); |
| 1240 | |
[email protected] | 26332c6 | 2010-03-30 19:11:40 | [diff] [blame] | 1241 | // Tests should be able to tune login manager before showing it. |
| 1242 | // Thus only show login manager in normal (non-testing) mode. |
| 1243 | if (!parameters.ui_task) { |
| 1244 | OptionallyRunChromeOSLoginManager(parsed_command_line); |
| 1245 | } |
[email protected] | cf80fae | 2010-02-26 10:35:21 | [diff] [blame] | 1246 | |
[email protected] | 272709ca | 2010-04-01 00:24:47 | [diff] [blame] | 1247 | #if !defined(OS_MACOSX) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1248 | // Importing other browser settings is done in a browser-like process |
| 1249 | // that exits when this task has finished. |
[email protected] | 3ef4755e | 2010-09-27 20:25:04 | [diff] [blame] | 1250 | // TODO(port): Port the Mac's IPC-based implementation to other platforms to |
| 1251 | // replace this implementation. http://crbug.com/22142 |
[email protected] | 02aae3f | 2010-03-22 22:31:27 | [diff] [blame] | 1252 | if (parsed_command_line.HasSwitch(switches::kImport) || |
[email protected] | 272709ca | 2010-04-01 00:24:47 | [diff] [blame] | 1253 | parsed_command_line.HasSwitch(switches::kImportFromFile)) { |
[email protected] | 6cd5bff | 2008-10-31 23:44:54 | [diff] [blame] | 1254 | return FirstRun::ImportNow(profile, parsed_command_line); |
[email protected] | 272709ca | 2010-04-01 00:24:47 | [diff] [blame] | 1255 | } |
[email protected] | 7da7f343 | 2009-10-28 20:12:08 | [diff] [blame] | 1256 | #endif |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1257 | |
[email protected] | 04999e6 | 2009-09-25 01:27:31 | [diff] [blame] | 1258 | #if defined(OS_WIN) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1259 | // Do the tasks if chrome has been upgraded while it was last running. |
[email protected] | bd48c2b0 | 2010-04-09 20:32:42 | [diff] [blame] | 1260 | if (!already_running && Upgrade::DoUpgradeTasks(parsed_command_line)) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1261 | return ResultCodes::NORMAL_EXIT; |
[email protected] | 04999e6 | 2009-09-25 01:27:31 | [diff] [blame] | 1262 | #endif |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1263 | |
[email protected] | 68c921f | 2008-10-15 21:37:46 | [diff] [blame] | 1264 | // Check if there is any machine level Chrome installed on the current |
| 1265 | // machine. If yes and the current Chrome process is user level, we do not |
| 1266 | // allow the user level Chrome to run. So we notify the user and uninstall |
| 1267 | // user level Chrome. |
| 1268 | // Note this check should only happen here, after all the checks above |
| 1269 | // (uninstall, resource bundle initialization, other chrome browser |
| 1270 | // processes etc). |
| 1271 | if (CheckMachineLevelInstall()) |
| 1272 | return ResultCodes::MACHINE_LEVEL_INSTALL_EXISTS; |
| 1273 | |
[email protected] | 7e0831b | 2010-02-01 08:45:15 | [diff] [blame] | 1274 | // Create the TranslateManager singleton. |
[email protected] | 509acb8e | 2010-07-01 20:35:31 | [diff] [blame] | 1275 | Singleton<TranslateManager>::get(); |
[email protected] | 7e0831b | 2010-02-01 08:45:15 | [diff] [blame] | 1276 | |
[email protected] | 0a357e63 | 2010-04-02 21:26:58 | [diff] [blame] | 1277 | #if defined(OS_MACOSX) |
| 1278 | if (!parsed_command_line.HasSwitch(switches::kNoFirstRun)) { |
| 1279 | // Disk image installation is sort of a first-run task, so it shares the |
| 1280 | // kNoFirstRun switch. |
| 1281 | if (MaybeInstallFromDiskImage()) { |
| 1282 | // The application was installed and the installed copy has been |
| 1283 | // launched. This process is now obsolete. Exit. |
| 1284 | return ResultCodes::NORMAL_EXIT; |
| 1285 | } |
| 1286 | } |
| 1287 | #endif |
| 1288 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1289 | // Show the First Run UI if this is the first time Chrome has been run on |
| 1290 | // this computer, or we're being compelled to do so by a command line flag. |
| 1291 | // Note that this be done _after_ the PrefService is initialized and all |
| 1292 | // preferences are registered, since some of the code that the importer |
| 1293 | // touches reads preferences. |
[email protected] | 7911717 | 2009-08-28 16:11:44 | [diff] [blame] | 1294 | if (is_first_run) { |
| 1295 | if (!first_run_ui_bypass) { |
[email protected] | 2f24d29 | 2010-07-16 16:16:52 | [diff] [blame] | 1296 | FirstRun::AutoImport(profile, |
| 1297 | master_prefs.homepage_defined, |
| 1298 | master_prefs.do_import_items, |
| 1299 | master_prefs.dont_import_items, |
| 1300 | master_prefs.run_search_engine_experiment, |
| 1301 | master_prefs.randomize_search_engine_experiment, |
[email protected] | 79e165f | 2010-09-01 15:57:50 | [diff] [blame] | 1302 | master_prefs.make_chrome_default, |
[email protected] | 2f24d29 | 2010-07-16 16:16:52 | [diff] [blame] | 1303 | &process_singleton); |
[email protected] | 5ee921c | 2009-07-28 19:21:25 | [diff] [blame] | 1304 | #if defined(OS_POSIX) |
[email protected] | 7911717 | 2009-08-28 16:11:44 | [diff] [blame] | 1305 | // On Windows, the download is tagged with enable/disable stats so there |
| 1306 | // is no need for this code. |
[email protected] | 5ee921c | 2009-07-28 19:21:25 | [diff] [blame] | 1307 | |
[email protected] | 7911717 | 2009-08-28 16:11:44 | [diff] [blame] | 1308 | // If stats reporting was turned on by the first run dialog then toggle |
| 1309 | // the pref. |
| 1310 | if (GoogleUpdateSettings::GetCollectStatsConsent()) |
| 1311 | local_state->SetBoolean(prefs::kMetricsReportingEnabled, true); |
[email protected] | 5ee921c | 2009-07-28 19:21:25 | [diff] [blame] | 1312 | #endif // OS_POSIX |
[email protected] | 2f24d29 | 2010-07-16 16:16:52 | [diff] [blame] | 1313 | } // if (!first_run_ui_bypass) |
[email protected] | a5391559 | 2010-02-26 20:21:40 | [diff] [blame] | 1314 | |
[email protected] | 7911717 | 2009-08-28 16:11:44 | [diff] [blame] | 1315 | Browser::SetNewHomePagePrefs(user_prefs); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1316 | } |
| 1317 | |
| 1318 | // Sets things up so that if we crash from this point on, a dialog will |
| 1319 | // popup asking the user to restart chrome. It is done this late to avoid |
| 1320 | // testing against a bunch of special cases that are taken care early on. |
| 1321 | PrepareRestartOnCrashEnviroment(parsed_command_line); |
| 1322 | |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 1323 | // Initialize and maintain network predictor module, which handles DNS |
| 1324 | // pre-resolution, as well as TCP/IP connection pre-warming. |
| 1325 | // This also registers an observer to discard data when closing incognito |
| 1326 | // mode. |
[email protected] | d461264 | 2010-08-11 22:46:57 | [diff] [blame] | 1327 | bool preconnect_enabled = true; // Default status (easy to change!). |
| 1328 | if (parsed_command_line.HasSwitch(switches::kDisablePreconnect)) |
| 1329 | preconnect_enabled = false; |
| 1330 | else if (parsed_command_line.HasSwitch(switches::kEnablePreconnect)) |
| 1331 | preconnect_enabled = true; |
[email protected] | 74be069e8 | 2010-06-25 00:12:49 | [diff] [blame] | 1332 | chrome_browser_net::PredictorInit dns_prefetch( |
[email protected] | 760d970a | 2010-05-18 00:39:18 | [diff] [blame] | 1333 | user_prefs, |
| 1334 | local_state, |
[email protected] | e326922d | 2010-09-03 09:08:10 | [diff] [blame] | 1335 | preconnect_enabled); |
[email protected] | 0d8fa3ec | 2009-04-08 04:22:44 | [diff] [blame] | 1336 | |
[email protected] | 1933eb20 | 2009-02-19 18:23:25 | [diff] [blame] | 1337 | #if defined(OS_WIN) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1338 | win_util::ScopedCOMInitializer com_initializer; |
| 1339 | |
[email protected] | 58b6433 | 2010-08-13 16:09:39 | [diff] [blame] | 1340 | #if defined(GOOGLE_CHROME_BUILD) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1341 | // Init the RLZ library. This just binds the dll and schedules a task on the |
| 1342 | // file thread to be run sometime later. If this is the first run we record |
| 1343 | // the installation event. |
[email protected] | 1c26217 | 2010-06-10 15:25:46 | [diff] [blame] | 1344 | RLZTracker::InitRlzDelayed(is_first_run, master_prefs.ping_delay); |
[email protected] | 698cccb1 | 2009-03-11 18:47:24 | [diff] [blame] | 1345 | #endif |
[email protected] | 58b6433 | 2010-08-13 16:09:39 | [diff] [blame] | 1346 | #endif |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1347 | |
[email protected] | 64d50ed | 2009-09-22 21:05:47 | [diff] [blame] | 1348 | // Configure the network module so it has access to resources. |
| 1349 | net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1350 | |
[email protected] | 60e44898 | 2009-05-06 04:21:16 | [diff] [blame] | 1351 | // Register our global network handler for chrome:// and |
[email protected] | 9527f9c | 2009-01-29 18:35:42 | [diff] [blame] | 1352 | // chrome-extension:// URLs. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1353 | RegisterURLRequestChromeJob(); |
[email protected] | 8f704c8 | 2009-01-08 21:47:41 | [diff] [blame] | 1354 | RegisterExtensionProtocols(); |
[email protected] | 540c1497 | 2009-07-13 16:03:49 | [diff] [blame] | 1355 | RegisterMetadataURLRequestHandler(); |
[email protected] | 8107004 | 2010-08-31 02:42:36 | [diff] [blame] | 1356 | RegisterBlobURLRequestJobFactory(); |
[email protected] | ac262c9f | 2008-10-19 17:45:21 | [diff] [blame] | 1357 | |
[email protected] | 3dd1f6d5 | 2008-09-15 18:28:09 | [diff] [blame] | 1358 | // In unittest mode, this will do nothing. In normal mode, this will create |
[email protected] | 8b62334b | 2010-08-31 22:37:11 | [diff] [blame] | 1359 | // the global GoogleURLTracker and IntranetRedirectDetector instances, which |
[email protected] | c4ff495 | 2010-01-08 19:12:47 | [diff] [blame] | 1360 | // will promptly go to sleep for five and seven seconds, respectively (to |
| 1361 | // avoid slowing startup), and wake up afterwards to see if they should do |
| 1362 | // anything else. |
[email protected] | 3dd1f6d5 | 2008-09-15 18:28:09 | [diff] [blame] | 1363 | // |
| 1364 | // A simpler way of doing all this would be to have some function which could |
[email protected] | c4ff495 | 2010-01-08 19:12:47 | [diff] [blame] | 1365 | // give the time elapsed since startup, and simply have these objects check |
| 1366 | // that when asked to initialize themselves, but this doesn't seem to exist. |
[email protected] | 3dd1f6d5 | 2008-09-15 18:28:09 | [diff] [blame] | 1367 | // |
[email protected] | c4ff495 | 2010-01-08 19:12:47 | [diff] [blame] | 1368 | // These can't be created in the BrowserProcessImpl constructor because they |
| 1369 | // need to read prefs that get set after that runs. |
[email protected] | 3dd1f6d5 | 2008-09-15 18:28:09 | [diff] [blame] | 1370 | browser_process->google_url_tracker(); |
[email protected] | c4ff495 | 2010-01-08 19:12:47 | [diff] [blame] | 1371 | browser_process->intranet_redirect_detector(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1372 | |
[email protected] | cec1b8d | 2010-03-24 00:21:34 | [diff] [blame] | 1373 | // Do initialize the plug-in service (and related preferences). |
| 1374 | PluginService::InitGlobalInstance(profile); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1375 | |
[email protected] | 6088942 | 2008-09-23 01:18:16 | [diff] [blame] | 1376 | // Prepare for memory caching of SDCH dictionaries. |
[email protected] | e695fbd6 | 2009-06-30 16:31:54 | [diff] [blame] | 1377 | // Perform A/B test to measure global impact of SDCH support. |
| 1378 | // Set up a field trial to see what disabling SDCH does to latency of page |
| 1379 | // layout globally. |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 1380 | base::FieldTrial::Probability kSDCH_DIVISOR = 1000; |
| 1381 | base::FieldTrial::Probability kSDCH_DISABLE_PROBABILITY = 1; // 0.1% prob. |
| 1382 | scoped_refptr<base::FieldTrial> sdch_trial = |
| 1383 | new base::FieldTrial("GlobalSdch", kSDCH_DIVISOR); |
[email protected] | e695fbd6 | 2009-06-30 16:31:54 | [diff] [blame] | 1384 | |
[email protected] | 5156c3cf | 2009-07-09 17:23:11 | [diff] [blame] | 1385 | // Use default of "" so that all domains are supported. |
| 1386 | std::string sdch_supported_domain(""); |
[email protected] | 6088942 | 2008-09-23 01:18:16 | [diff] [blame] | 1387 | if (parsed_command_line.HasSwitch(switches::kSdchFilter)) { |
[email protected] | 5156c3cf | 2009-07-09 17:23:11 | [diff] [blame] | 1388 | sdch_supported_domain = |
[email protected] | 5d39e314 | 2009-12-17 05:54:10 | [diff] [blame] | 1389 | parsed_command_line.GetSwitchValueASCII(switches::kSdchFilter); |
[email protected] | e695fbd6 | 2009-06-30 16:31:54 | [diff] [blame] | 1390 | } else { |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 1391 | sdch_trial->AppendGroup("global_disable_sdch", |
[email protected] | e12d5059 | 2010-01-06 17:35:19 | [diff] [blame] | 1392 | kSDCH_DISABLE_PROBABILITY); |
[email protected] | 58d2d2d | 2010-08-05 22:46:33 | [diff] [blame] | 1393 | int sdch_enabled = sdch_trial->AppendGroup("global_enable_sdch", |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 1394 | base::FieldTrial::kAllRemainingProbability); |
[email protected] | 5156c3cf | 2009-07-09 17:23:11 | [diff] [blame] | 1395 | if (sdch_enabled != sdch_trial->group()) |
| 1396 | sdch_supported_domain = "never_enabled_sdch_for_any_domain"; |
[email protected] | 6088942 | 2008-09-23 01:18:16 | [diff] [blame] | 1397 | } |
[email protected] | e695fbd6 | 2009-06-30 16:31:54 | [diff] [blame] | 1398 | |
[email protected] | 5156c3cf | 2009-07-09 17:23:11 | [diff] [blame] | 1399 | SdchManager sdch_manager; // Singleton database. |
| 1400 | sdch_manager.set_sdch_fetcher(new SdchDictionaryFetcher); |
| 1401 | sdch_manager.EnableSdchSupport(sdch_supported_domain); |
[email protected] | 6088942 | 2008-09-23 01:18:16 | [diff] [blame] | 1402 | |
[email protected] | 838e1a9 | 2010-03-25 17:47:45 | [diff] [blame] | 1403 | MetricsService* metrics = InitializeMetrics(parsed_command_line, local_state); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1404 | InstallJankometer(parsed_command_line); |
| 1405 | |
[email protected] | e1504d8 | 2009-07-03 15:27:15 | [diff] [blame] | 1406 | #if defined(OS_WIN) && !defined(GOOGLE_CHROME_BUILD) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1407 | if (parsed_command_line.HasSwitch(switches::kDebugPrint)) { |
[email protected] | 884fbb7 | 2010-08-04 01:47:55 | [diff] [blame] | 1408 | FilePath path = |
| 1409 | parsed_command_line.GetSwitchValuePath(switches::kDebugPrint); |
[email protected] | d9d4299 | 2010-09-13 19:39:19 | [diff] [blame] | 1410 | printing::PrintedDocument::set_debug_dump_path(path); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1411 | } |
[email protected] | 1bcdb53 | 2009-01-16 17:47:57 | [diff] [blame] | 1412 | #endif |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1413 | |
[email protected] | 9bade09 | 2009-11-13 17:04:42 | [diff] [blame] | 1414 | HandleTestParameters(parsed_command_line); |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 1415 | RecordBreakpadStatusUMA(metrics); |
[email protected] | 3cf4f099 | 2009-02-03 23:00:30 | [diff] [blame] | 1416 | |
[email protected] | 6641bf66 | 2009-08-21 00:34:09 | [diff] [blame] | 1417 | // Stat the directory with the inspector's files so that we can know if we |
| 1418 | // should display the entry in the context menu or not. |
| 1419 | browser_process->CheckForInspectorFiles(); |
| 1420 | |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 1421 | #if defined(OS_CHROMEOS) |
[email protected] | 29cf1677 | 2010-04-21 15:13:47 | [diff] [blame] | 1422 | metrics->StartExternalMetrics(); |
[email protected] | 5ccaa41 | 2009-11-13 22:00:16 | [diff] [blame] | 1423 | #endif |
| 1424 | |
[email protected] | b3d62312b1 | 2010-10-14 21:10:18 | [diff] [blame] | 1425 | // Initialize extension event routers. Note that on Chrome OS, this will |
| 1426 | // not succeed if the user has not logged in yet, in which case the |
| 1427 | // event routers are initialized in LoginUtilsImpl::CompleteLogin instead. |
[email protected] | 1172ba7 | 2010-05-21 22:21:11 | [diff] [blame] | 1428 | if (profile->GetExtensionsService()) { |
| 1429 | // This will initialize bookmarks. Call it after bookmark import is done. |
| 1430 | // See issue 40144. |
| 1431 | profile->GetExtensionsService()->InitEventRouters(); |
| 1432 | } |
[email protected] | c5ae74ab | 2010-04-15 18:14:37 | [diff] [blame] | 1433 | |
[email protected] | 6aeac834 | 2010-10-01 20:21:18 | [diff] [blame] | 1434 | // The extension service may be available at this point. If the command line |
| 1435 | // specifies --uninstall-extension, attempt the uninstall extension startup |
| 1436 | // action. |
| 1437 | if (parsed_command_line.HasSwitch(switches::kUninstallExtension)) { |
| 1438 | if (extensions_startup::HandleUninstallExtension(parsed_command_line, |
| 1439 | profile)) { |
| 1440 | return ResultCodes::NORMAL_EXIT; |
| 1441 | } else { |
| 1442 | return ResultCodes::UNINSTALL_EXTENSION_ERROR; |
| 1443 | } |
| 1444 | } |
| 1445 | |
[email protected] | 15406b6a | 2010-04-21 00:35:01 | [diff] [blame] | 1446 | #if defined(OS_WIN) |
[email protected] | 8a9c63e | 2010-04-19 21:27:55 | [diff] [blame] | 1447 | // We check this here because if the profile is OTR (chromeos possibility) |
| 1448 | // it won't still be accessible after browser is destroyed. |
| 1449 | bool record_search_engine = is_first_run && !profile->IsOffTheRecord(); |
[email protected] | 15406b6a | 2010-04-21 00:35:01 | [diff] [blame] | 1450 | #endif |
[email protected] | 8a9c63e | 2010-04-19 21:27:55 | [diff] [blame] | 1451 | |
[email protected] | 332e121 | 2010-06-23 22:49:49 | [diff] [blame] | 1452 | // ChildProcess:: is a misnomer unless you consider context. Use |
| 1453 | // of --wait-for-debugger only makes sense when Chrome itself is a |
| 1454 | // child process (e.g. when launched by PyAuto). |
| 1455 | if (parsed_command_line.HasSwitch(switches::kWaitForDebugger)) { |
| 1456 | ChildProcess::WaitForDebugger(L"Browser"); |
| 1457 | } |
| 1458 | |
[email protected] | e96bf0c5 | 2010-08-23 23:20:57 | [diff] [blame] | 1459 | // If remoting or cloud print proxy is enabled and setup has been completed |
| 1460 | // we start the service process here. |
| 1461 | // The prerequisite for running the service process is that we have IO, UI |
| 1462 | // and PROCESS_LAUNCHER threads up and running. |
| 1463 | // TODO(hclam): Need to check for cloud print proxy too. |
| 1464 | if (parsed_command_line.HasSwitch(switches::kEnableRemoting)) { |
| 1465 | if (user_prefs->GetBoolean(prefs::kRemotingHasSetupCompleted)) { |
| 1466 | ServiceProcessControl* control = ServiceProcessControlManager::instance() |
[email protected] | de2658d5 | 2010-10-05 19:48:58 | [diff] [blame] | 1467 | ->GetProcessControl(profile); |
[email protected] | ed453c0a | 2010-10-18 21:47:17 | [diff] [blame] | 1468 | control->Launch(NULL, NULL); |
[email protected] | e96bf0c5 | 2010-08-23 23:20:57 | [diff] [blame] | 1469 | } |
| 1470 | } |
| 1471 | |
[email protected] | 17543d6 | 2010-10-07 22:37:38 | [diff] [blame] | 1472 | // Create the instance of the cloud print proxy service so that it can launch |
| 1473 | // the service process if needed. This is needed because the service process |
| 1474 | // might have shutdown because an update was available. |
| 1475 | profile->GetCloudPrintProxyService(); |
| 1476 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1477 | int result_code = ResultCodes::NORMAL_EXIT; |
[email protected] | d4515eb | 2009-01-30 00:40:43 | [diff] [blame] | 1478 | if (parameters.ui_task) { |
[email protected] | 4a8bca5 | 2009-05-07 23:37:59 | [diff] [blame] | 1479 | // We are in test mode. Run one task and enter the main message loop. |
| 1480 | if (pool) |
| 1481 | pool->Recycle(); |
[email protected] | 64f1931 | 2010-04-13 22:30:01 | [diff] [blame] | 1482 | parameters.ui_task->Run(); |
| 1483 | delete parameters.ui_task; |
[email protected] | 4a8bca5 | 2009-05-07 23:37:59 | [diff] [blame] | 1484 | } else { |
[email protected] | 30f894b | 2009-12-22 05:06:20 | [diff] [blame] | 1485 | // We are in regular browser boot sequence. Open initial stabs and enter |
| 1486 | // the main message loop. |
[email protected] | f805fe8 | 2010-08-03 22:47:10 | [diff] [blame] | 1487 | if (browser_init.Start(parsed_command_line, FilePath(), profile, |
[email protected] | 4a8bca5 | 2009-05-07 23:37:59 | [diff] [blame] | 1488 | &result_code)) { |
[email protected] | 3cdacd4 | 2010-04-30 18:55:53 | [diff] [blame] | 1489 | #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) |
[email protected] | bd48c2b0 | 2010-04-09 20:32:42 | [diff] [blame] | 1490 | // Initialize autoupdate timer. Timer callback costs basically nothing |
| 1491 | // when browser is not in persistent mode, so it's OK to let it ride on |
| 1492 | // the main thread. This needs to be done here because we don't want |
| 1493 | // to start the timer when Chrome is run inside a test harness. |
| 1494 | g_browser_process->StartAutoupdateTimer(); |
| 1495 | #endif |
| 1496 | |
[email protected] | 3cdacd4 | 2010-04-30 18:55:53 | [diff] [blame] | 1497 | #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 1498 | // On Linux, the running exe will be updated if an upgrade becomes |
| 1499 | // available while the browser is running. We need to save the last |
| 1500 | // modified time of the exe, so we can compare to determine if there is |
| 1501 | // an upgrade while the browser is kept alive by a persistent extension. |
| 1502 | Upgrade::SaveLastModifiedTimeOfExe(); |
| 1503 | #endif |
| 1504 | |
[email protected] | bf7eb2f9 | 2010-06-28 22:55:55 | [diff] [blame] | 1505 | // Record now as the last successful chrome start. |
[email protected] | fc09792 | 2010-01-28 00:41:04 | [diff] [blame] | 1506 | GoogleUpdateSettings::SetLastRunTime(); |
[email protected] | 4a8bca5 | 2009-05-07 23:37:59 | [diff] [blame] | 1507 | // Call Recycle() here as late as possible, before going into the loop |
| 1508 | // because Start() will add things to it while creating the main window. |
| 1509 | if (pool) |
| 1510 | pool->Recycle(); |
| 1511 | RunUIMessageLoop(browser_process.get()); |
| 1512 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1513 | } |
[email protected] | 96b3c5c | 2010-04-16 20:30:14 | [diff] [blame] | 1514 | |
[email protected] | 15406b6a | 2010-04-21 00:35:01 | [diff] [blame] | 1515 | #if defined(OS_WIN) |
[email protected] | 96b3c5c | 2010-04-16 20:30:14 | [diff] [blame] | 1516 | // If it's the first run, log the search engine chosen. We wait until |
| 1517 | // shutdown because otherwise we can't be sure the user has finished |
| 1518 | // selecting a search engine through the dialog reached from the first run |
| 1519 | // bubble link. |
[email protected] | 15406b6a | 2010-04-21 00:35:01 | [diff] [blame] | 1520 | if (FirstRun::InSearchExperimentLocale() && record_search_engine) { |
[email protected] | 96b3c5c | 2010-04-16 20:30:14 | [diff] [blame] | 1521 | const TemplateURL* default_search_engine = |
| 1522 | profile->GetTemplateURLModel()->GetDefaultSearchProvider(); |
[email protected] | 32cba2b | 2010-10-19 06:19:48 | [diff] [blame] | 1523 | // The default engine can be NULL if the administrator has disabled |
| 1524 | // default search. |
[email protected] | 2387290 | 2010-10-26 03:43:59 | [diff] [blame] | 1525 | SearchEngineType search_engine_type = |
[email protected] | 32cba2b | 2010-10-19 06:19:48 | [diff] [blame] | 1526 | default_search_engine ? default_search_engine->search_engine_type() : |
[email protected] | 2387290 | 2010-10-26 03:43:59 | [diff] [blame] | 1527 | SEARCH_ENGINE_OTHER; |
[email protected] | bf7eb2f9 | 2010-06-28 22:55:55 | [diff] [blame] | 1528 | // Record the search engine chosen. |
[email protected] | 96b3c5c | 2010-04-16 20:30:14 | [diff] [blame] | 1529 | if (master_prefs.run_search_engine_experiment) { |
| 1530 | UMA_HISTOGRAM_ENUMERATION( |
| 1531 | "Chrome.SearchSelectExperiment", |
[email protected] | 32cba2b | 2010-10-19 06:19:48 | [diff] [blame] | 1532 | search_engine_type, |
[email protected] | 2387290 | 2010-10-26 03:43:59 | [diff] [blame] | 1533 | SEARCH_ENGINE_MAX); |
[email protected] | bf7eb2f9 | 2010-06-28 22:55:55 | [diff] [blame] | 1534 | // If the selection has been randomized, also record the winner by slot. |
| 1535 | if (master_prefs.randomize_search_engine_experiment) { |
| 1536 | size_t engine_pos = profile->GetTemplateURLModel()-> |
| 1537 | GetSearchEngineDialogSlot(); |
| 1538 | if (engine_pos < 4) { |
| 1539 | std::string experiment_type = "Chrome.SearchSelectExperimentSlot"; |
| 1540 | // Nicer in UMA if slots are 1-based. |
| 1541 | experiment_type.push_back('1' + engine_pos); |
| 1542 | UMA_HISTOGRAM_ENUMERATION( |
| 1543 | experiment_type, |
[email protected] | 32cba2b | 2010-10-19 06:19:48 | [diff] [blame] | 1544 | search_engine_type, |
[email protected] | 2387290 | 2010-10-26 03:43:59 | [diff] [blame] | 1545 | SEARCH_ENGINE_MAX); |
[email protected] | bf7eb2f9 | 2010-06-28 22:55:55 | [diff] [blame] | 1546 | } else { |
| 1547 | NOTREACHED() << "Invalid search engine selection slot."; |
| 1548 | } |
| 1549 | } |
[email protected] | 96b3c5c | 2010-04-16 20:30:14 | [diff] [blame] | 1550 | } else { |
| 1551 | UMA_HISTOGRAM_ENUMERATION( |
| 1552 | "Chrome.SearchSelectExempt", |
[email protected] | 32cba2b | 2010-10-19 06:19:48 | [diff] [blame] | 1553 | search_engine_type, |
[email protected] | 2387290 | 2010-10-26 03:43:59 | [diff] [blame] | 1554 | SEARCH_ENGINE_MAX); |
[email protected] | 96b3c5c | 2010-04-16 20:30:14 | [diff] [blame] | 1555 | } |
| 1556 | } |
[email protected] | 15406b6a | 2010-04-21 00:35:01 | [diff] [blame] | 1557 | #endif |
[email protected] | 96b3c5c | 2010-04-16 20:30:14 | [diff] [blame] | 1558 | |
[email protected] | 7c7377a | 2009-11-11 06:59:38 | [diff] [blame] | 1559 | chrome_browser_net_websocket_experiment::WebSocketExperimentRunner::Stop(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1560 | |
[email protected] | 9f20a6d0 | 2009-08-21 01:18:37 | [diff] [blame] | 1561 | process_singleton.Cleanup(); |
| 1562 | |
[email protected] | 60626da | 2010-03-25 17:06:53 | [diff] [blame] | 1563 | metrics->Stop(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1564 | |
| 1565 | // browser_shutdown takes care of deleting browser_process, so we need to |
| 1566 | // release it. |
[email protected] | d22d873 | 2010-05-04 19:24:42 | [diff] [blame] | 1567 | ignore_result(browser_process.release()); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1568 | browser_shutdown::Shutdown(); |
| 1569 | |
[email protected] | a872ea1f | 2010-08-11 04:45:33 | [diff] [blame] | 1570 | TRACE_EVENT_END("BrowserMain", 0, 0); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 1571 | return result_code; |
| 1572 | } |