blob: 2a922850cfdd9d8af2f6d9a40be5244ddcb88301 [file] [log] [blame]
[email protected]38d0b2d42012-01-18 03:37:341// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]b48c9182011-10-26 18:03:302// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/browser_main_loop.h"
6
[email protected]820de972012-01-03 18:23:047#include "base/bind.h"
[email protected]b48c9182011-10-26 18:03:308#include "base/command_line.h"
[email protected]b48c9182011-10-26 18:03:309#include "base/logging.h"
chrishadc837f52015-05-15 03:09:0610#include "base/memory/memory_pressure_monitor.h"
[email protected]95f861e2013-07-18 02:07:1711#include "base/message_loop/message_loop.h"
[email protected]b48c9182011-10-26 18:03:3012#include "base/metrics/field_trial.h"
13#include "base/metrics/histogram.h"
[email protected]1d88aea92013-02-03 08:16:2414#include "base/pending_task.h"
[email protected]6c5905b72013-04-03 19:06:5115#include "base/power_monitor/power_monitor.h"
[email protected]9dd90152013-08-02 22:09:1316#include "base/power_monitor/power_monitor_device_source.h"
[email protected]fa20e002013-07-23 21:20:5417#include "base/process/process_metrics.h"
yiyaoliu252f915e2015-04-23 21:56:3618#include "base/profiler/scoped_profile.h"
[email protected]8e937c1e2012-06-28 22:57:3019#include "base/run_loop.h"
[email protected]10994d132013-06-11 07:16:1820#include "base/strings/string_number_conversions.h"
chrisha7a11bb82015-05-08 15:39:4021#include "base/strings/string_split.h"
[email protected]10994d132013-06-11 07:16:1822#include "base/system_monitor/system_monitor.h"
[email protected]e5a631a2013-09-18 07:33:2723#include "base/thread_task_runner_handle.h"
[email protected]b48c9182011-10-26 18:03:3024#include "base/threading/thread_restrictions.h"
[email protected]89bf27e2013-06-27 18:04:5625#include "base/timer/hi_res_timer_manager.h"
primiano9f23f382015-04-21 18:35:1126#include "base/trace_event/memory_dump_manager.h"
ssid3e765612015-01-28 04:03:4227#include "base/trace_event/trace_event.h"
[email protected]c38831a12011-10-28 12:44:4928#include "content/browser/browser_thread_impl.h"
[email protected]3cc4db82014-04-22 23:48:5329#include "content/browser/device_sensors/device_inertial_sensor_service.h"
cmumforda1f8d832015-05-10 16:44:1330#include "content/browser/dom_storage/dom_storage_area.h"
[email protected]99907362012-01-11 05:41:4031#include "content/browser/download/save_file_manager.h"
[email protected]ac671e782012-06-05 18:48:2032#include "content/browser/gamepad/gamepad_service.h"
[email protected]5b040e592012-02-10 02:56:1033#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
reveman84c4caf92015-05-01 20:10:2234#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
[email protected]15154932013-08-21 03:27:2435#include "content/browser/gpu/compositor_util.h"
[email protected]7e343152012-09-20 21:49:5336#include "content/browser/gpu/gpu_data_manager_impl.h"
[email protected]99af54b2012-03-03 01:06:5037#include "content/browser/gpu/gpu_process_host.h"
[email protected]64d69de42012-02-06 00:19:5438#include "content/browser/gpu/gpu_process_host_ui_shim.h"
[email protected]c6ff6a32012-07-17 19:01:0139#include "content/browser/histogram_synchronizer.h"
[email protected]678c0362012-12-05 08:02:4440#include "content/browser/loader/resource_dispatcher_host_impl.h"
[email protected]adba07352013-12-04 08:33:5941#include "content/browser/media/media_internals.h"
rockotb814a582015-06-05 00:30:5242#include "content/browser/mojo/mojo_shell_context.h"
[email protected]bff327f2012-03-11 22:17:1943#include "content/browser/net/browser_online_state_observer.h"
[email protected]5a3097162012-07-06 12:03:0544#include "content/browser/renderer_host/media/media_stream_manager.h"
[email protected]28df14d2012-05-16 14:51:2245#include "content/browser/speech/speech_recognition_manager_impl.h"
[email protected]57624ab2013-08-01 16:01:5146#include "content/browser/startup_task_runner.h"
[email protected]8b03c072014-04-30 15:49:2547#include "content/browser/time_zone_monitor.h"
[email protected]64ccac32013-01-29 21:40:0448#include "content/browser/webui/content_web_ui_controller_factory.h"
[email protected]33c1c26a2013-01-24 21:56:2649#include "content/browser/webui/url_data_manager.h"
wfh6575fb42015-01-28 04:05:2150#include "content/common/content_switches_internal.h"
reveman2799f7f2015-03-16 19:06:2151#include "content/common/host_discardable_shared_memory_manager.h"
revemancc84bf652015-04-29 07:50:5452#include "content/common/host_shared_bitmap_manager.h"
[email protected]b48c9182011-10-26 18:03:3053#include "content/public/browser/browser_main_parts.h"
54#include "content/public/browser/content_browser_client.h"
[email protected]a6381cb52012-02-13 22:39:3455#include "content/public/browser/render_process_host.h"
[email protected]1eb14612013-11-21 01:04:5856#include "content/public/browser/tracing_controller.h"
[email protected]b48c9182011-10-26 18:03:3057#include "content/public/common/content_switches.h"
[email protected]4573fbd2011-10-31 20:25:1858#include "content/public/common/main_function_params.h"
[email protected]b48c9182011-10-26 18:03:3059#include "content/public/common/result_codes.h"
60#include "crypto/nss_util.h"
ppi2438a3e2014-10-28 21:55:1061#include "device/battery/battery_status_service.h"
[email protected]52e456b92012-02-23 17:13:1862#include "media/audio/audio_manager.h"
[email protected]8e15369c2013-05-10 00:30:1563#include "media/base/media.h"
[email protected]61f697f2013-08-15 22:02:4064#include "media/base/user_input_monitor.h"
[email protected]a9875152013-06-22 04:03:0365#include "media/midi/midi_manager.h"
[email protected]b48c9182011-10-26 18:03:3066#include "net/base/network_change_notifier.h"
[email protected]b48c9182011-10-26 18:03:3067#include "net/socket/client_socket_factory.h"
[email protected]536fd0b2013-03-14 17:41:5768#include "net/ssl/ssl_config_service.h"
[email protected]2dd33552012-09-11 16:39:5569#include "ui/base/clipboard/clipboard.h"
[email protected]b48c9182011-10-26 18:03:3070
[email protected]7aef77a2014-04-17 07:38:2071#if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
[email protected]6dc38f72014-01-16 22:19:5872#include "content/browser/compositor/image_transport_factory.h"
[email protected]894e8fc2012-02-24 13:29:5073#endif
74
[email protected]da5f8412014-04-23 17:42:0075#if defined(USE_AURA)
[email protected]fa69f2b62014-05-22 21:47:5876#include "content/public/browser/context_factory.h"
[email protected]da5f8412014-04-23 17:42:0077#include "ui/aura/env.h"
78#endif
79
[email protected]f68c1462014-04-24 18:17:5380#if !defined(OS_IOS)
81#include "content/browser/renderer_host/render_process_host_impl.h"
82#endif
83
[email protected]40bdb122012-11-10 03:02:3884#if defined(OS_ANDROID)
85#include "base/android/jni_android.h"
[email protected]ddb4b202013-08-20 22:55:5486#include "content/browser/android/browser_startup_controller.h"
reveman6f3e3652014-10-10 03:32:0087#include "content/browser/android/browser_surface_texture_manager.h"
[email protected]d6d3c7f2014-04-11 01:28:5488#include "content/browser/android/tracing_controller_android.h"
jonross36980292014-10-08 15:55:1089#include "content/browser/screen_orientation/screen_orientation_delegate_android.h"
90#include "content/public/browser/screen_orientation_provider.h"
[email protected]af7c5d92014-02-03 19:53:1591#include "ui/gl/gl_surface.h"
[email protected]40bdb122012-11-10 03:02:3892#endif
93
tommi354afdd2015-05-27 20:05:3694#if defined(OS_MACOSX)
95#include "media/base/mac/avfoundation_glue.h"
96#endif
97
[email protected]291857a2014-01-23 17:49:1198#if defined(OS_MACOSX) && !defined(OS_IOS)
scottmgdab35482015-05-21 22:13:4499#include "base/memory/memory_pressure_monitor_mac.h"
[email protected]f5bcd0f2014-06-10 14:50:41100#include "content/browser/bootstrap_sandbox_mac.h"
reveman7c45b3082015-06-04 01:27:08101#include "content/browser/browser_io_surface_manager_mac.h"
[email protected]cc405e42014-07-31 11:35:51102#include "content/browser/cocoa/system_hotkey_helper_mac.h"
ccamerona10e9812014-12-08 23:57:01103#include "content/browser/compositor/browser_compositor_view_mac.h"
[email protected]b0988b22013-11-08 08:25:58104#include "content/browser/theme_helper_mac.h"
105#endif
106
[email protected]b48c9182011-10-26 18:03:30107#if defined(OS_WIN)
108#include <windows.h>
109#include <commctrl.h>
[email protected]b48c9182011-10-26 18:03:30110#include <shellapi.h>
111
scottmgdab35482015-05-21 22:13:44112#include "base/memory/memory_pressure_monitor_win.h"
[email protected]cd1cd4c02011-11-15 01:59:49113#include "content/browser/system_message_window_win.h"
[email protected]34f48682013-03-20 00:30:18114#include "content/common/sandbox_win.h"
[email protected]b48c9182011-10-26 18:03:30115#include "net/base/winsock_init.h"
[email protected]536fd0b2013-03-14 17:41:57116#include "ui/base/l10n/l10n_util_win.h"
[email protected]b48c9182011-10-26 18:03:30117#endif
118
skuhne5e3879c2014-12-15 23:38:19119#if defined(OS_CHROMEOS)
scottmgdab35482015-05-21 22:13:44120#include "base/memory/memory_pressure_monitor_chromeos.h"
skuhne5e3879c2014-12-15 23:38:19121#include "chromeos/chromeos_switches.h"
122#endif
123
[email protected]87d985ab2013-11-21 07:11:58124#if defined(USE_GLIB)
[email protected]b48c9182011-10-26 18:03:30125#include <glib-object.h>
126#endif
127
[email protected]49513e02013-11-20 08:36:40128#if defined(OS_LINUX) && defined(USE_UDEV)
129#include "content/browser/device_monitor_udev.h"
[email protected]a34087bd2012-10-11 17:05:30130#elif defined(OS_MACOSX) && !defined(OS_IOS)
[email protected]14625442012-08-15 12:51:42131#include "content/browser/device_monitor_mac.h"
[email protected]97646c92012-07-31 20:30:08132#endif
133
[email protected]b48c9182011-10-26 18:03:30134#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]b48c9182011-10-26 18:03:30135#include "content/browser/renderer_host/render_sandbox_host_linux.h"
[email protected]13d6b3c2012-07-24 01:31:31136#include "content/browser/zygote_host/zygote_host_impl_linux.h"
mdempsky3cc942a2015-02-05 03:29:25137#include "sandbox/linux/suid/client/setuid_sandbox_host.h"
[email protected]b48c9182011-10-26 18:03:30138#endif
139
thestigc4cac8f2014-09-04 21:17:50140#if defined(ENABLE_PLUGINS)
141#include "content/browser/plugin_service_impl.h"
142#endif
143
[email protected]111494e2013-07-24 18:38:29144#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
145#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
146#endif
147
[email protected]462d4a32012-01-19 00:11:04148#if defined(USE_X11)
[email protected]82f884d6ffb2014-04-15 03:34:54149#include "ui/gfx/x/x11_connection.h"
[email protected]d957b102014-04-25 20:17:19150#include "ui/gfx/x/x11_types.h"
[email protected]462d4a32012-01-19 00:11:04151#endif
152
[email protected]64d69de42012-02-06 00:19:54153// One of the linux specific headers defines this as a macro.
154#ifdef DestroyAll
155#undef DestroyAll
156#endif
157
[email protected]130757672012-10-24 00:26:19158namespace content {
[email protected]b48c9182011-10-26 18:03:30159namespace {
160
[email protected]a08029b42012-04-25 03:18:46161#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
[email protected]479278702014-08-11 20:32:09162void SetupSandbox(const base::CommandLine& parsed_command_line) {
[email protected]30610102013-07-04 08:41:38163 TRACE_EVENT0("startup", "SetupSandbox");
[email protected]4741d012013-08-09 20:43:37164 base::FilePath sandbox_binary;
[email protected]be6d0e42014-04-15 05:30:30165
mdempsky3cc942a2015-02-05 03:29:25166 scoped_ptr<sandbox::SetuidSandboxHost> setuid_sandbox_host(
167 sandbox::SetuidSandboxHost::Create());
[email protected]b48c9182011-10-26 18:03:30168
[email protected]9a5bb052014-04-17 16:50:56169 const bool want_setuid_sandbox =
[email protected]b098ef892013-06-13 17:55:18170 !parsed_command_line.HasSwitch(switches::kNoSandbox) &&
[email protected]be6d0e42014-04-15 05:30:30171 !parsed_command_line.HasSwitch(switches::kDisableSetuidSandbox) &&
mdempsky3cc942a2015-02-05 03:29:25172 !setuid_sandbox_host->IsDisabledViaEnvironment();
[email protected]b098ef892013-06-13 17:55:18173
[email protected]be6d0e42014-04-15 05:30:30174 static const char no_suid_error[] =
175 "Running without the SUID sandbox! See "
176 "https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment "
177 "for more information on developing with the sandbox on.";
[email protected]dbf253d42013-06-23 18:53:02178 if (want_setuid_sandbox) {
mdempsky3cc942a2015-02-05 03:29:25179 sandbox_binary = setuid_sandbox_host->GetSandboxBinaryPath();
[email protected]4741d012013-08-09 20:43:37180 if (sandbox_binary.empty()) {
[email protected]be6d0e42014-04-15 05:30:30181 // This needs to be fatal. Talk to [email protected] if you feel
182 // otherwise.
183 LOG(FATAL) << no_suid_error;
[email protected]4741d012013-08-09 20:43:37184 }
[email protected]be6d0e42014-04-15 05:30:30185 } else {
186 LOG(ERROR) << no_suid_error;
[email protected]b098ef892013-06-13 17:55:18187 }
[email protected]b48c9182011-10-26 18:03:30188
189 // Tickle the sandbox host and zygote host so they fork now.
[email protected]58a487b2014-05-10 04:50:11190 RenderSandboxHostLinux::GetInstance()->Init();
[email protected]4741d012013-08-09 20:43:37191 ZygoteHostImpl::GetInstance()->Init(sandbox_binary.value());
[email protected]b48c9182011-10-26 18:03:30192}
193#endif
194
[email protected]87d985ab2013-11-21 07:11:58195#if defined(USE_GLIB)
[email protected]b48c9182011-10-26 18:03:30196static void GLibLogHandler(const gchar* log_domain,
197 GLogLevelFlags log_level,
198 const gchar* message,
199 gpointer userdata) {
200 if (!log_domain)
201 log_domain = "<unknown>";
202 if (!message)
203 message = "<no message>";
204
[email protected]f8aa0c62014-04-15 13:09:45205 if (strstr(message, "Unable to retrieve the file info for")) {
[email protected]8a1ea192011-11-29 22:40:50206 LOG(ERROR) << "GTK File code error: " << message;
[email protected]d133320302013-05-23 16:58:21207 } else if (strstr(message, "Could not find the icon") &&
208 strstr(log_domain, "Gtk")) {
209 LOG(ERROR) << "GTK icon error: " << message;
[email protected]b48c9182011-10-26 18:03:30210 } else if (strstr(message, "Theme file for default has no") ||
211 strstr(message, "Theme directory") ||
[email protected]2bdaecf2011-12-15 02:44:55212 strstr(message, "theme pixmap") ||
213 strstr(message, "locate theme engine")) {
[email protected]b48c9182011-10-26 18:03:30214 LOG(ERROR) << "GTK theme error: " << message;
[email protected]45d8f472012-09-20 19:29:20215 } else if (strstr(message, "Unable to create Ubuntu Menu Proxy") &&
216 strstr(log_domain, "<unknown>")) {
217 LOG(ERROR) << "GTK menu proxy create failed";
[email protected]b48c9182011-10-26 18:03:30218 } else if (strstr(message, "Out of memory") &&
219 strstr(log_domain, "<unknown>")) {
220 LOG(ERROR) << "DBus call timeout or out of memory: "
221 << "http://crosbug.com/15496";
[email protected]0ed43012013-03-05 04:02:29222 } else if (strstr(message, "Could not connect: Connection refused") &&
223 strstr(log_domain, "<unknown>")) {
224 LOG(ERROR) << "DConf settings backend could not connect to session bus: "
225 << "http://crbug.com/179797";
[email protected]238d5c32012-11-20 02:27:40226 } else if (strstr(message, "Attempting to store changes into") ||
227 strstr(message, "Attempting to set the permissions of")) {
228 LOG(ERROR) << message << " (http://bugs.chromium.org/161366)";
[email protected]a8144b72014-01-07 11:08:13229 } else if (strstr(message, "drawable is not a native X11 window")) {
230 LOG(ERROR) << message << " (http://bugs.chromium.org/329991)";
wangxianzhu557296bd2015-05-27 21:54:08231 } else if (strstr(message, "Cannot do system-bus activation with no user")) {
232 LOG(ERROR) << message << " (http://crbug.com/431005)";
[email protected]b48c9182011-10-26 18:03:30233 } else {
234 LOG(DFATAL) << log_domain << ": " << message;
235 }
236}
237
238static void SetUpGLibLogHandler() {
239 // Register GLib-handled assertions to go through our logging system.
240 const char* kLogDomains[] = { NULL, "Gtk", "Gdk", "GLib", "GLib-GObject" };
241 for (size_t i = 0; i < arraysize(kLogDomains); i++) {
242 g_log_set_handler(kLogDomains[i],
243 static_cast<GLogLevelFlags>(G_LOG_FLAG_RECURSION |
244 G_LOG_FLAG_FATAL |
245 G_LOG_LEVEL_ERROR |
246 G_LOG_LEVEL_CRITICAL |
247 G_LOG_LEVEL_WARNING),
248 GLibLogHandler,
249 NULL);
250 }
251}
252#endif
253
[email protected]d6d3c7f2014-04-11 01:28:54254void OnStoppedStartupTracing(const base::FilePath& trace_file) {
[email protected]280a7a72014-04-11 17:17:20255 VLOG(0) << "Completed startup tracing to " << trace_file.value();
[email protected]d6d3c7f2014-04-11 01:28:54256}
257
[email protected]d904aee2014-08-15 21:29:11258// Disable optimizations for this block of functions so the compiler doesn't
259// merge them all together. This makes it possible to tell what thread was
260// unresponsive by inspecting the callstack.
261MSVC_DISABLE_OPTIMIZE()
262MSVC_PUSH_DISABLE_WARNING(4748)
263
264NOINLINE void ResetThread_DB(scoped_ptr<BrowserProcessSubThread> thread) {
rvargas0adfc752014-12-03 19:44:21265 volatile int inhibit_comdat = __LINE__;
266 ALLOW_UNUSED_LOCAL(inhibit_comdat);
[email protected]d904aee2014-08-15 21:29:11267 thread.reset();
268}
269
270NOINLINE void ResetThread_FILE(scoped_ptr<BrowserProcessSubThread> thread) {
rvargas0adfc752014-12-03 19:44:21271 volatile int inhibit_comdat = __LINE__;
272 ALLOW_UNUSED_LOCAL(inhibit_comdat);
[email protected]d904aee2014-08-15 21:29:11273 thread.reset();
274}
275
276NOINLINE void ResetThread_FILE_USER_BLOCKING(
277 scoped_ptr<BrowserProcessSubThread> thread) {
rvargas0adfc752014-12-03 19:44:21278 volatile int inhibit_comdat = __LINE__;
279 ALLOW_UNUSED_LOCAL(inhibit_comdat);
[email protected]d904aee2014-08-15 21:29:11280 thread.reset();
281}
282
283NOINLINE void ResetThread_PROCESS_LAUNCHER(
284 scoped_ptr<BrowserProcessSubThread> thread) {
rvargas0adfc752014-12-03 19:44:21285 volatile int inhibit_comdat = __LINE__;
286 ALLOW_UNUSED_LOCAL(inhibit_comdat);
[email protected]d904aee2014-08-15 21:29:11287 thread.reset();
288}
289
290NOINLINE void ResetThread_CACHE(scoped_ptr<BrowserProcessSubThread> thread) {
rvargas0adfc752014-12-03 19:44:21291 volatile int inhibit_comdat = __LINE__;
292 ALLOW_UNUSED_LOCAL(inhibit_comdat);
[email protected]d904aee2014-08-15 21:29:11293 thread.reset();
294}
295
296NOINLINE void ResetThread_IO(scoped_ptr<BrowserProcessSubThread> thread) {
rvargas0adfc752014-12-03 19:44:21297 volatile int inhibit_comdat = __LINE__;
298 ALLOW_UNUSED_LOCAL(inhibit_comdat);
[email protected]d904aee2014-08-15 21:29:11299 thread.reset();
300}
301
302#if !defined(OS_IOS)
303NOINLINE void ResetThread_IndexedDb(scoped_ptr<base::Thread> thread) {
rvargas0adfc752014-12-03 19:44:21304 volatile int inhibit_comdat = __LINE__;
305 ALLOW_UNUSED_LOCAL(inhibit_comdat);
[email protected]d904aee2014-08-15 21:29:11306 thread.reset();
307}
308#endif
309
310MSVC_POP_WARNING()
311MSVC_ENABLE_OPTIMIZE();
312
chrisha7a11bb82015-05-08 15:39:40313#if defined(OS_WIN)
314// Creates a memory pressure monitor using automatic thresholds, or those
315// specified on the command-line. Ownership is passed to the caller.
316base::win::MemoryPressureMonitor* CreateWinMemoryPressureMonitor(
317 const base::CommandLine& parsed_command_line) {
318 std::vector<std::string> thresholds;
319 base::SplitString(
320 parsed_command_line.GetSwitchValueASCII(
321 switches::kMemoryPressureThresholdsMb),
322 ',',
323 &thresholds);
324
325 int moderate_threshold_mb = 0;
326 int critical_threshold_mb = 0;
327 if (thresholds.size() == 2 &&
328 base::StringToInt(thresholds[0], &moderate_threshold_mb) &&
329 base::StringToInt(thresholds[1], &critical_threshold_mb) &&
330 moderate_threshold_mb >= critical_threshold_mb &&
331 critical_threshold_mb >= 0) {
332 return new base::win::MemoryPressureMonitor(moderate_threshold_mb,
333 critical_threshold_mb);
334 }
335
336 // In absence of valid switches use the automatic defaults.
337 return new base::win::MemoryPressureMonitor();
338}
339#endif // defined(OS_WIN)
340
[email protected]b48c9182011-10-26 18:03:30341} // namespace
342
[email protected]2e5b60a22011-11-28 15:56:41343// The currently-running BrowserMainLoop. There can be one or zero.
[email protected]52e456b92012-02-23 17:13:18344BrowserMainLoop* g_current_browser_main_loop = NULL;
[email protected]2e5b60a22011-11-28 15:56:41345
[email protected]ee57f332013-01-31 18:13:54346// For measuring memory usage after each task. Behind a command line flag.
[email protected]dd32b1272013-05-04 14:17:11347class BrowserMainLoop::MemoryObserver : public base::MessageLoop::TaskObserver {
[email protected]ee57f332013-01-31 18:13:54348 public:
349 MemoryObserver() {}
dchengc2282aa2014-10-21 12:07:58350 ~MemoryObserver() override {}
[email protected]ee57f332013-01-31 18:13:54351
dchengc2282aa2014-10-21 12:07:58352 void WillProcessTask(const base::PendingTask& pending_task) override {}
[email protected]ee57f332013-01-31 18:13:54353
dchengc2282aa2014-10-21 12:07:58354 void DidProcessTask(const base::PendingTask& pending_task) override {
[email protected]66ad3072013-02-25 08:53:34355#if !defined(OS_IOS) // No ProcessMetrics on IOS.
356 scoped_ptr<base::ProcessMetrics> process_metrics(
357 base::ProcessMetrics::CreateProcessMetrics(
358#if defined(OS_MACOSX)
359 base::GetCurrentProcessHandle(), NULL));
360#else
361 base::GetCurrentProcessHandle()));
362#endif
363 size_t private_bytes;
364 process_metrics->GetMemoryBytes(&private_bytes, NULL);
asvitkinec0fb8022014-08-26 04:39:35365 LOCAL_HISTOGRAM_MEMORY_KB("Memory.BrowserUsed", private_bytes >> 10);
[email protected]ee57f332013-01-31 18:13:54366#endif
367 }
368 private:
369 DISALLOW_COPY_AND_ASSIGN(MemoryObserver);
370};
371
372
[email protected]e974ad292012-03-07 07:34:51373// BrowserMainLoop construction / destruction =============================
[email protected]b48c9182011-10-26 18:03:30374
[email protected]aa445462013-06-21 17:12:36375BrowserMainLoop* BrowserMainLoop::GetInstance() {
mostynbfbcdc27a2015-03-13 17:58:52376 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]aa445462013-06-21 17:12:36377 return g_current_browser_main_loop;
378}
379
[email protected]130757672012-10-24 00:26:19380BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
[email protected]b48c9182011-10-26 18:03:30381 : parameters_(parameters),
[email protected]badf5cf2011-10-29 03:44:44382 parsed_command_line_(parameters.command_line),
[email protected]57624ab2013-08-01 16:01:51383 result_code_(RESULT_CODE_NORMAL_EXIT),
[email protected]1eb14612013-11-21 01:04:58384 created_threads_(false),
385 // ContentMainRunner should have enabled tracing of the browser process
386 // when kTraceStartup is in the command line.
[email protected]19ff70d2014-01-31 18:39:26387 is_tracing_startup_(
388 parameters.command_line.HasSwitch(switches::kTraceStartup)) {
[email protected]52e456b92012-02-23 17:13:18389 DCHECK(!g_current_browser_main_loop);
390 g_current_browser_main_loop = this;
[email protected]b48c9182011-10-26 18:03:30391}
392
393BrowserMainLoop::~BrowserMainLoop() {
[email protected]52e456b92012-02-23 17:13:18394 DCHECK_EQ(this, g_current_browser_main_loop);
[email protected]a34087bd2012-10-11 17:05:30395#if !defined(OS_IOS)
[email protected]2dd33552012-09-11 16:39:55396 ui::Clipboard::DestroyClipboardForCurrentThread();
[email protected]a34087bd2012-10-11 17:05:30397#endif // !defined(OS_IOS)
[email protected]52e456b92012-02-23 17:13:18398 g_current_browser_main_loop = NULL;
[email protected]b48c9182011-10-26 18:03:30399}
400
401void BrowserMainLoop::Init() {
[email protected]8b03c072014-04-30 15:49:25402 TRACE_EVENT0("startup", "BrowserMainLoop::Init");
yiyaoliu252f915e2015-04-23 21:56:36403 TRACK_SCOPED_REGION("Startup", "BrowserMainLoop::Init");
404
[email protected]50462bf02011-11-21 19:13:31405 parts_.reset(
406 GetContentClient()->browser()->CreateBrowserMainParts(parameters_));
[email protected]b48c9182011-10-26 18:03:30407}
408
409// BrowserMainLoop stages ==================================================
410
411void BrowserMainLoop::EarlyInitialization() {
[email protected]30610102013-07-04 08:41:38412 TRACE_EVENT0("startup", "BrowserMainLoop::EarlyInitialization");
yiyaoliu252f915e2015-04-23 21:56:36413 TRACK_SCOPED_REGION("Startup", "BrowserMainLoop::EarlyInitialization");
[email protected]f143906c2013-11-22 19:14:20414
415#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
416 // No thread should be created before this call, as SetupSandbox()
417 // will end-up using fork().
418 SetupSandbox(parsed_command_line_);
419#endif
420
[email protected]462d4a32012-01-19 00:11:04421#if defined(USE_X11)
boliu7439d042015-01-27 22:51:11422 if (UsingInProcessGpu()) {
[email protected]82f884d6ffb2014-04-15 03:34:54423 if (!gfx::InitializeThreadedX11()) {
[email protected]462d4a32012-01-19 00:11:04424 LOG(ERROR) << "Failed to put Xlib into threaded mode.";
425 }
426 }
427#endif
428
[email protected]f143906c2013-11-22 19:14:20429 // GLib's spawning of new processes is buggy, so it's important that at this
430 // point GLib does not need to start DBUS. Chrome should always start with
431 // DBUS_SESSION_BUS_ADDRESS properly set. See crbug.com/309093.
[email protected]87d985ab2013-11-21 07:11:58432#if defined(USE_GLIB)
[email protected]d3f854952013-10-23 23:19:34433 // g_type_init will be deprecated in 2.36. 2.35 is the development
434 // version for 2.36, hence do not call g_type_init starting 2.35.
435 // http://developer.gnome.org/gobject/unstable/gobject-Type-Information.html#g-type-init
436#if !GLIB_CHECK_VERSION(2, 35, 0)
437 // GLib type system initialization. Needed at least for gconf,
438 // used in net/proxy/proxy_config_service_linux.cc. Most likely
439 // this is superfluous as gtk_init() ought to do this. It's
440 // definitely harmless, so retained as a reminder of this
441 // requirement for gconf.
442 g_type_init();
443#endif
444
[email protected]d3f854952013-10-23 23:19:34445 SetUpGLibLogHandler();
446#endif
447
[email protected]59383c782013-04-17 16:43:27448 if (parts_)
[email protected]50462bf02011-11-21 19:13:31449 parts_->PreEarlyInitialization();
[email protected]b48c9182011-10-26 18:03:30450
[email protected]b9f44b22014-05-29 23:15:55451#if defined(OS_MACOSX)
452 // We use quite a few file descriptors for our IPC, and the default limit on
453 // the Mac is low (256), so bump it up.
454 base::SetFdLimit(1024);
455#endif
456
[email protected]b48c9182011-10-26 18:03:30457#if defined(OS_WIN)
458 net::EnsureWinsockInit();
459#endif
460
[email protected]1648b292011-11-03 23:57:39461#if !defined(USE_OPENSSL)
[email protected]8cbcabf2013-01-16 03:08:54462 // We want to be sure to init NSPR on the main thread.
463 crypto::EnsureNSPRInit();
[email protected]1648b292011-11-03 23:57:39464#endif // !defined(USE_OPENSSL)
[email protected]b48c9182011-10-26 18:03:30465
[email protected]759a86a2012-09-10 14:42:54466#if !defined(OS_IOS)
[email protected]a6381cb52012-02-13 22:39:34467 if (parsed_command_line_.HasSwitch(switches::kRendererProcessLimit)) {
468 std::string limit_string = parsed_command_line_.GetSwitchValueASCII(
469 switches::kRendererProcessLimit);
470 size_t process_limit;
471 if (base::StringToSizeT(limit_string, &process_limit)) {
[email protected]130757672012-10-24 00:26:19472 RenderProcessHost::SetMaxRendererProcessCount(process_limit);
[email protected]a6381cb52012-02-13 22:39:34473 }
474 }
[email protected]759a86a2012-09-10 14:42:54475#endif // !defined(OS_IOS)
[email protected]a6381cb52012-02-13 22:39:34476
reveman44b807f12014-11-26 02:44:50477 if (parsed_command_line_.HasSwitch(switches::kEnableNativeGpuMemoryBuffers)) {
478 BrowserGpuChannelHostFactory::EnableGpuMemoryBufferFactoryUsage(
479 gfx::GpuMemoryBuffer::MAP);
danakj99669002015-05-26 20:08:38480 BrowserGpuChannelHostFactory::EnableGpuMemoryBufferFactoryUsage(
481 gfx::GpuMemoryBuffer::PERSISTENT_MAP);
reveman44b807f12014-11-26 02:44:50482 }
483
484#if defined(USE_OZONE)
485 BrowserGpuChannelHostFactory::EnableGpuMemoryBufferFactoryUsage(
486 gfx::GpuMemoryBuffer::SCANOUT);
487#endif
488
reveman1af05cb32015-03-17 23:18:16489 base::DiscardableMemoryAllocator::SetInstance(
reveman2799f7f2015-03-16 19:06:21490 HostDiscardableSharedMemoryManager::current());
491
[email protected]59383c782013-04-17 16:43:27492 if (parts_)
[email protected]50462bf02011-11-21 19:13:31493 parts_->PostEarlyInitialization();
[email protected]b48c9182011-10-26 18:03:30494}
495
thestig7e202d1a2015-05-27 21:54:55496void BrowserMainLoop::PreMainMessageLoopStart() {
[email protected]aa328c72013-05-03 10:55:43497 if (parts_) {
498 TRACE_EVENT0("startup",
499 "BrowserMainLoop::MainMessageLoopStart:PreMainMessageLoopStart");
[email protected]50462bf02011-11-21 19:13:31500 parts_->PreMainMessageLoopStart();
[email protected]aa328c72013-05-03 10:55:43501 }
[email protected]b48c9182011-10-26 18:03:30502
503#if defined(OS_WIN)
504 // If we're running tests (ui_task is non-null), then the ResourceBundle
505 // has already been initialized.
[email protected]716476c2011-12-29 00:07:03506 if (!parameters_.ui_task) {
[email protected]b48c9182011-10-26 18:03:30507 // Override the configured locale with the user's preferred UI language.
508 l10n_util::OverrideLocaleWithUILanguageList();
509 }
510#endif
thestig7e202d1a2015-05-27 21:54:55511}
512
513void BrowserMainLoop::MainMessageLoopStart() {
514 // DO NOT add more code here. Use PreMainMessageLoopStart() above or
515 // PostMainMessageLoopStart() below.
516
517 TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart");
518 TRACK_SCOPED_REGION("Startup", "BrowserMainLoop::MainMessageLoopStart");
skuhne3bd1fc02014-12-17 01:49:37519
520 // Create a MessageLoop if one does not already exist for the current thread.
521 if (!base::MessageLoop::current())
522 main_message_loop_.reset(new base::MessageLoopForUI);
523
524 InitializeMainThread();
thestig7e202d1a2015-05-27 21:54:55525}
skuhne3bd1fc02014-12-17 01:49:37526
thestig7e202d1a2015-05-27 21:54:55527void BrowserMainLoop::PostMainMessageLoopStart() {
[email protected]5be58512013-05-31 00:22:24528 {
[email protected]8b03c072014-04-30 15:49:25529 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SystemMonitor");
[email protected]5be58512013-05-31 00:22:24530 system_monitor_.reset(new base::SystemMonitor);
531 }
532 {
[email protected]8b03c072014-04-30 15:49:25533 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor");
[email protected]9dd90152013-08-02 22:09:13534 scoped_ptr<base::PowerMonitorSource> power_monitor_source(
[email protected]ed3bf8a62014-04-05 18:55:57535 new base::PowerMonitorDeviceSource());
536 power_monitor_.reset(new base::PowerMonitor(power_monitor_source.Pass()));
[email protected]5be58512013-05-31 00:22:24537 }
538 {
[email protected]8b03c072014-04-30 15:49:25539 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:HighResTimerManager");
[email protected]89bf27e2013-06-27 18:04:56540 hi_res_timer_manager_.reset(new base::HighResolutionTimerManager);
[email protected]5be58512013-05-31 00:22:24541 }
542 {
[email protected]8b03c072014-04-30 15:49:25543 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:NetworkChangeNotifier");
[email protected]5be58512013-05-31 00:22:24544 network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
545 }
[email protected]8e15369c2013-05-10 00:30:15546
[email protected]f13401b2013-08-28 00:24:32547#if !defined(OS_IOS)
[email protected]5be58512013-05-31 00:22:24548 {
[email protected]8b03c072014-04-30 15:49:25549 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MediaFeatures");
chcunninghambfef6d62015-06-04 19:55:51550 media::InitializeMediaLibrary();
[email protected]5be58512013-05-31 00:22:24551 }
552 {
[email protected]8b03c072014-04-30 15:49:25553 TRACE_EVENT0("startup",
554 "BrowserMainLoop::Subsystem:ContentWebUIController");
[email protected]5be58512013-05-31 00:22:24555 WebUIControllerFactory::RegisterFactory(
556 ContentWebUIControllerFactory::GetInstance());
557 }
[email protected]64ccac32013-01-29 21:40:04558
[email protected]5be58512013-05-31 00:22:24559 {
[email protected]8b03c072014-04-30 15:49:25560 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:OnlineStateObserver");
[email protected]5be58512013-05-31 00:22:24561 online_state_observer_.reset(new BrowserOnlineStateObserver);
562 }
[email protected]e5a631a2013-09-18 07:33:27563
564 {
ssidb2e3ece2015-02-09 16:02:20565 system_stats_monitor_.reset(
566 new base::trace_event::TraceEventSystemStatsMonitor(
567 base::ThreadTaskRunnerHandle::Get()));
[email protected]e5a631a2013-09-18 07:33:27568 }
[email protected]ebd71962012-12-20 02:56:55569#endif // !defined(OS_IOS)
[email protected]b48c9182011-10-26 18:03:30570
[email protected]759a86a2012-09-10 14:42:54571#if defined(OS_WIN)
572 system_message_window_.reset(new SystemMessageWindowWin);
573#endif
[email protected]99907362012-01-11 05:41:40574
[email protected]59383c782013-04-17 16:43:27575 if (parts_)
[email protected]50462bf02011-11-21 19:13:31576 parts_->PostMainMessageLoopStart();
[email protected]40bdb122012-11-10 03:02:38577
[email protected]e8e70cea2014-03-14 11:50:59578#if !defined(OS_IOS)
579 // Start tracing to a file if needed. Only do this after starting the main
580 // message loop to avoid calling MessagePumpForUI::ScheduleWork() before
581 // MessagePumpForUI::Start() as it will crash the browser.
582 if (is_tracing_startup_) {
[email protected]8b03c072014-04-30 15:49:25583 TRACE_EVENT0("startup", "BrowserMainLoop::InitStartupTracing");
[email protected]e8e70cea2014-03-14 11:50:59584 InitStartupTracing(parsed_command_line_);
585 }
586#endif // !defined(OS_IOS)
587
[email protected]40bdb122012-11-10 03:02:38588#if defined(OS_ANDROID)
[email protected]5be58512013-05-31 00:22:24589 {
reveman6f3e3652014-10-10 03:32:00590 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SurfaceTextureManager");
reveman27f02a22015-05-18 20:44:33591 SurfaceTextureManager::SetInstance(new BrowserSurfaceTextureManager);
[email protected]5be58512013-05-31 00:22:24592 }
jonross36980292014-10-08 15:55:10593
mlamouri8ded9762015-03-26 17:06:23594 if (!parsed_command_line_.HasSwitch(
595 switches::kDisableScreenOrientationLock)) {
jonross36980292014-10-08 15:55:10596 TRACE_EVENT0("startup",
597 "BrowserMainLoop::Subsystem:ScreenOrientationProvider");
598 screen_orientation_delegate_.reset(
599 new ScreenOrientationDelegateAndroid());
600 ScreenOrientationProvider::SetDelegate(screen_orientation_delegate_.get());
601 }
[email protected]40bdb122012-11-10 03:02:38602#endif
[email protected]ee57f332013-01-31 18:13:54603
reveman7c45b3082015-06-04 01:27:08604#if defined(OS_MACOSX) && !defined(OS_IOS)
605 {
606 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:IOSurfaceManager");
607 IOSurfaceManager::SetInstance(BrowserIOSurfaceManager::GetInstance());
608 }
609#endif
610
[email protected]ee57f332013-01-31 18:13:54611 if (parsed_command_line_.HasSwitch(switches::kMemoryMetrics)) {
[email protected]8b03c072014-04-30 15:49:25612 TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MemoryObserver");
[email protected]ee57f332013-01-31 18:13:54613 memory_observer_.reset(new MemoryObserver());
[email protected]dd32b1272013-05-04 14:17:11614 base::MessageLoop::current()->AddTaskObserver(memory_observer_.get());
[email protected]ee57f332013-01-31 18:13:54615 }
[email protected]111494e2013-07-24 18:38:29616
cmumforda1f8d832015-05-10 16:44:13617 if (parsed_command_line_.HasSwitch(
618 switches::kEnableAggressiveDOMStorageFlushing)) {
619 TRACE_EVENT0("startup",
620 "BrowserMainLoop::Subsystem:EnableAggressiveCommitDelay");
621 DOMStorageArea::EnableAggressiveCommitDelay();
622 }
623
primiano9f23f382015-04-21 18:35:11624 base::trace_event::MemoryDumpManager::GetInstance()->Initialize();
625
revemancc84bf652015-04-29 07:50:54626 // Enable the dump providers.
627 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
628 HostSharedBitmapManager::current());
629
[email protected]111494e2013-07-24 18:38:29630#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
ssidb2e3ece2015-02-09 16:02:20631 trace_memory_controller_.reset(new base::trace_event::TraceMemoryController(
[email protected]111494e2013-07-24 18:38:29632 base::MessageLoop::current()->message_loop_proxy(),
ssidb2e3ece2015-02-09 16:02:20633 ::HeapProfilerWithPseudoStackStart, ::HeapProfilerStop,
[email protected]111494e2013-07-24 18:38:29634 ::GetHeapProfile));
635#endif
[email protected]b48c9182011-10-26 18:03:30636}
637
[email protected]57624ab2013-08-01 16:01:51638int BrowserMainLoop::PreCreateThreads() {
[email protected]aa328c72013-05-03 10:55:43639 if (parts_) {
640 TRACE_EVENT0("startup",
[email protected]73852e02013-06-21 06:51:53641 "BrowserMainLoop::CreateThreads:PreCreateThreads");
yiyaoliu252f915e2015-04-23 21:56:36642 TRACK_SCOPED_REGION("Startup", "BrowserMainLoop::PreCreateThreads");
643
[email protected]69479b922012-02-02 09:56:20644 result_code_ = parts_->PreCreateThreads();
[email protected]aa328c72013-05-03 10:55:43645 }
[email protected]69479b922012-02-02 09:56:20646
chrishadc837f52015-05-15 03:09:06647 // TODO(chrisha): Abstract away this construction mess to a helper function,
648 // once MemoryPressureMonitor is made a concrete class.
xdaie347db2e2015-02-18 02:37:23649#if defined(OS_CHROMEOS)
650 if (chromeos::switches::MemoryPressureHandlingEnabled()) {
chrishadc837f52015-05-15 03:09:06651 memory_pressure_monitor_.reset(new base::chromeos::MemoryPressureMonitor(
xdaie347db2e2015-02-18 02:37:23652 chromeos::switches::GetMemoryPressureThresholds()));
653 }
shrike45f88e32015-05-01 17:10:23654#elif defined(OS_MACOSX) && !defined(OS_IOS)
chrishadc837f52015-05-15 03:09:06655 memory_pressure_monitor_.reset(new base::mac::MemoryPressureMonitor());
chrisha7a11bb82015-05-08 15:39:40656#elif defined(OS_WIN)
657 memory_pressure_monitor_.reset(CreateWinMemoryPressureMonitor(
658 parsed_command_line_));
xdaie347db2e2015-02-18 02:37:23659#endif
660
[email protected]73852e02013-06-21 06:51:53661#if defined(ENABLE_PLUGINS)
662 // Prior to any processing happening on the io thread, we create the
663 // plugin service as it is predominantly used from the io thread,
664 // but must be created on the main thread. The service ctor is
665 // inexpensive and does not invoke the io_thread() accessor.
666 {
[email protected]8b03c072014-04-30 15:49:25667 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService");
[email protected]73852e02013-06-21 06:51:53668 PluginService::GetInstance()->Init();
669 }
670#endif
671
tommi354afdd2015-05-27 20:05:36672#if defined(OS_MACOSX)
673 {
674 // Initialize AVFoundation if supported, for audio and video.
675 TRACE_EVENT0("startup",
676 "BrowserMainLoop::CreateThreads:InitializeAVFoundation");
677 AVFoundationGlue::InitializeAVFoundation();
678 }
679#endif
680
boliu7439d042015-01-27 22:51:11681 // Need to initialize in-process GpuDataManager before creating threads.
682 // It's unsafe to append the gpu command line switches to the global
683 // CommandLine::ForCurrentProcess object after threads are created.
684 if (UsingInProcessGpu()) {
685 bool initialize_gpu_data_manager = true;
686#if defined(OS_ANDROID)
687 if (!gfx::GLSurface::InitializeOneOff()) {
688 // Single-process Android WebView supports no gpu.
689 LOG(ERROR) << "GLSurface::InitializeOneOff failed";
690 initialize_gpu_data_manager = false;
691 }
692#endif
693
694 // Initialize the GpuDataManager before we set up the MessageLoops because
695 // otherwise we'll trigger the assertion about doing IO on the UI thread.
696 if (initialize_gpu_data_manager)
697 GpuDataManagerImpl::GetInstance()->Initialize();
698 }
699
shouqun12d25202015-03-19 01:02:22700#if !defined(OS_IOS) && (!defined(GOOGLE_CHROME_BUILD) || defined(OS_ANDROID))
701 // Single-process is an unsupported and not fully tested mode, so
702 // don't enable it for official Chrome builds (except on Android).
703 if (parsed_command_line_.HasSwitch(switches::kSingleProcess))
704 RenderProcessHost::SetRunRendererInProcess(true);
705#endif
706
[email protected]57624ab2013-08-01 16:01:51707 return result_code_;
708}
[email protected]dfd53652012-10-25 00:20:02709
[email protected]57624ab2013-08-01 16:01:51710void BrowserMainLoop::CreateStartupTasks() {
[email protected]232e09d2013-08-27 15:29:56711 TRACE_EVENT0("startup", "BrowserMainLoop::CreateStartupTasks");
yiyaoliu252f915e2015-04-23 21:56:36712 TRACK_SCOPED_REGION("Startup", "BrowserMainLoop::CreateStartupTasks");
[email protected]232e09d2013-08-27 15:29:56713
714 // First time through, we really want to create all the tasks
715 if (!startup_task_runner_.get()) {
716#if defined(OS_ANDROID)
717 startup_task_runner_ = make_scoped_ptr(new StartupTaskRunner(
718 base::Bind(&BrowserStartupComplete),
719 base::MessageLoop::current()->message_loop_proxy()));
720#else
721 startup_task_runner_ = make_scoped_ptr(new StartupTaskRunner(
722 base::Callback<void(int)>(),
723 base::MessageLoop::current()->message_loop_proxy()));
724#endif
725 StartupTask pre_create_threads =
726 base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this));
727 startup_task_runner_->AddTask(pre_create_threads);
728
729 StartupTask create_threads =
730 base::Bind(&BrowserMainLoop::CreateThreads, base::Unretained(this));
731 startup_task_runner_->AddTask(create_threads);
732
733 StartupTask browser_thread_started = base::Bind(
734 &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this));
735 startup_task_runner_->AddTask(browser_thread_started);
736
737 StartupTask pre_main_message_loop_run = base::Bind(
738 &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this));
739 startup_task_runner_->AddTask(pre_main_message_loop_run);
[email protected]57624ab2013-08-01 16:01:51740
741#if defined(OS_ANDROID)
[email protected]232e09d2013-08-27 15:29:56742 if (BrowserMayStartAsynchronously()) {
743 startup_task_runner_->StartRunningTasksAsync();
744 }
[email protected]57624ab2013-08-01 16:01:51745#endif
[email protected]232e09d2013-08-27 15:29:56746 }
747#if defined(OS_ANDROID)
748 if (!BrowserMayStartAsynchronously()) {
749 // A second request for asynchronous startup can be ignored, so
750 // StartupRunningTasksAsync is only called first time through. If, however,
751 // this is a request for synchronous startup then it must override any
752 // previous call for async startup, so we call RunAllTasksNow()
753 // unconditionally.
754 startup_task_runner_->RunAllTasksNow();
755 }
756#else
757 startup_task_runner_->RunAllTasksNow();
758#endif
[email protected]57624ab2013-08-01 16:01:51759}
760
761int BrowserMainLoop::CreateThreads() {
762 TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads");
yiyaoliu252f915e2015-04-23 21:56:36763 TRACK_SCOPED_REGION("Startup", "BrowserMainLoop::CreateThreads");
[email protected]2e5b60a22011-11-28 15:56:41764
[email protected]2e5b60a22011-11-28 15:56:41765 base::Thread::Options io_message_loop_options;
[email protected]dd32b1272013-05-04 14:17:11766 io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO;
[email protected]2e5b60a22011-11-28 15:56:41767 base::Thread::Options ui_message_loop_options;
[email protected]dd32b1272013-05-04 14:17:11768 ui_message_loop_options.message_loop_type = base::MessageLoop::TYPE_UI;
[email protected]2e5b60a22011-11-28 15:56:41769
770 // Start threads in the order they occur in the BrowserThread::ID
771 // enumeration, except for BrowserThread::UI which is the main
772 // thread.
773 //
774 // Must be size_t so we can increment it.
775 for (size_t thread_id = BrowserThread::UI + 1;
776 thread_id < BrowserThread::ID_COUNT;
777 ++thread_id) {
778 scoped_ptr<BrowserProcessSubThread>* thread_to_start = NULL;
[email protected]1c8fcb52014-06-26 22:36:32779 base::Thread::Options options;
[email protected]2e5b60a22011-11-28 15:56:41780
781 switch (thread_id) {
782 case BrowserThread::DB:
[email protected]aa328c72013-05-03 10:55:43783 TRACE_EVENT_BEGIN1("startup",
784 "BrowserMainLoop::CreateThreads:start",
785 "Thread", "BrowserThread::DB");
[email protected]2e5b60a22011-11-28 15:56:41786 thread_to_start = &db_thread_;
[email protected]1c8fcb52014-06-26 22:36:32787 options.timer_slack = base::TIMER_SLACK_MAXIMUM;
[email protected]2e5b60a22011-11-28 15:56:41788 break;
[email protected]31dbf9d2011-12-07 01:25:30789 case BrowserThread::FILE_USER_BLOCKING:
[email protected]aa328c72013-05-03 10:55:43790 TRACE_EVENT_BEGIN1("startup",
791 "BrowserMainLoop::CreateThreads:start",
792 "Thread", "BrowserThread::FILE_USER_BLOCKING");
[email protected]31dbf9d2011-12-07 01:25:30793 thread_to_start = &file_user_blocking_thread_;
794 break;
[email protected]2e5b60a22011-11-28 15:56:41795 case BrowserThread::FILE:
[email protected]aa328c72013-05-03 10:55:43796 TRACE_EVENT_BEGIN1("startup",
797 "BrowserMainLoop::CreateThreads:start",
798 "Thread", "BrowserThread::FILE");
[email protected]2e5b60a22011-11-28 15:56:41799 thread_to_start = &file_thread_;
800#if defined(OS_WIN)
801 // On Windows, the FILE thread needs to be have a UI message loop
802 // which pumps messages in such a way that Google Update can
803 // communicate back to us.
[email protected]1c8fcb52014-06-26 22:36:32804 options = ui_message_loop_options;
[email protected]2e5b60a22011-11-28 15:56:41805#else
[email protected]1c8fcb52014-06-26 22:36:32806 options = io_message_loop_options;
[email protected]2e5b60a22011-11-28 15:56:41807#endif
[email protected]1c8fcb52014-06-26 22:36:32808 options.timer_slack = base::TIMER_SLACK_MAXIMUM;
[email protected]2e5b60a22011-11-28 15:56:41809 break;
810 case BrowserThread::PROCESS_LAUNCHER:
[email protected]aa328c72013-05-03 10:55:43811 TRACE_EVENT_BEGIN1("startup",
812 "BrowserMainLoop::CreateThreads:start",
813 "Thread", "BrowserThread::PROCESS_LAUNCHER");
[email protected]2e5b60a22011-11-28 15:56:41814 thread_to_start = &process_launcher_thread_;
[email protected]1c8fcb52014-06-26 22:36:32815 options.timer_slack = base::TIMER_SLACK_MAXIMUM;
[email protected]2e5b60a22011-11-28 15:56:41816 break;
817 case BrowserThread::CACHE:
[email protected]aa328c72013-05-03 10:55:43818 TRACE_EVENT_BEGIN1("startup",
819 "BrowserMainLoop::CreateThreads:start",
820 "Thread", "BrowserThread::CACHE");
[email protected]2e5b60a22011-11-28 15:56:41821 thread_to_start = &cache_thread_;
[email protected]1c8fcb52014-06-26 22:36:32822 options = io_message_loop_options;
823 options.timer_slack = base::TIMER_SLACK_MAXIMUM;
[email protected]2e5b60a22011-11-28 15:56:41824 break;
825 case BrowserThread::IO:
[email protected]aa328c72013-05-03 10:55:43826 TRACE_EVENT_BEGIN1("startup",
827 "BrowserMainLoop::CreateThreads:start",
828 "Thread", "BrowserThread::IO");
[email protected]2e5b60a22011-11-28 15:56:41829 thread_to_start = &io_thread_;
[email protected]1c8fcb52014-06-26 22:36:32830 options = io_message_loop_options;
[email protected]2e5b60a22011-11-28 15:56:41831 break;
[email protected]2e5b60a22011-11-28 15:56:41832 case BrowserThread::UI:
833 case BrowserThread::ID_COUNT:
834 default:
835 NOTREACHED();
836 break;
837 }
838
839 BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id);
840
[email protected]08dda5c2013-07-19 21:55:53841 if (thread_to_start) {
[email protected]2e5b60a22011-11-28 15:56:41842 (*thread_to_start).reset(new BrowserProcessSubThread(id));
jiayl1762c8f2014-09-18 18:23:45843 if (!(*thread_to_start)->StartWithOptions(options)) {
844 LOG(FATAL) << "Failed to start the browser thread: id == " << id;
845 }
[email protected]c2b77b2392011-12-02 13:00:16846 } else {
847 NOTREACHED();
[email protected]2e5b60a22011-11-28 15:56:41848 }
[email protected]aa328c72013-05-03 10:55:43849
850 TRACE_EVENT_END0("startup", "BrowserMainLoop::CreateThreads:start");
[email protected]2e5b60a22011-11-28 15:56:41851 }
[email protected]57624ab2013-08-01 16:01:51852 created_threads_ = true;
853 return result_code_;
854}
[email protected]2e5b60a22011-11-28 15:56:41855
[email protected]57624ab2013-08-01 16:01:51856int BrowserMainLoop::PreMainMessageLoopRun() {
[email protected]aa328c72013-05-03 10:55:43857 if (parts_) {
858 TRACE_EVENT0("startup",
859 "BrowserMainLoop::CreateThreads:PreMainMessageLoopRun");
yiyaoliu252f915e2015-04-23 21:56:36860 TRACK_SCOPED_REGION(
861 "Startup", "BrowserMainLoop::PreMainMessageLoopRun");
862
[email protected]50462bf02011-11-21 19:13:31863 parts_->PreMainMessageLoopRun();
[email protected]aa328c72013-05-03 10:55:43864 }
[email protected]b48c9182011-10-26 18:03:30865
[email protected]b48c9182011-10-26 18:03:30866 // If the UI thread blocks, the whole UI is unresponsive.
867 // Do not allow disk IO from the UI thread.
868 base::ThreadRestrictions::SetIOAllowed(false);
[email protected]3a7b66d2012-04-26 16:34:16869 base::ThreadRestrictions::DisallowWaiting();
[email protected]57624ab2013-08-01 16:01:51870 return result_code_;
[email protected]f573ed6b2012-02-10 15:58:52871}
872
873void BrowserMainLoop::RunMainMessageLoopParts() {
874 TRACE_EVENT_BEGIN_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
[email protected]b48c9182011-10-26 18:03:30875
[email protected]b48c9182011-10-26 18:03:30876 bool ran_main_loop = false;
[email protected]59383c782013-04-17 16:43:27877 if (parts_)
[email protected]50462bf02011-11-21 19:13:31878 ran_main_loop = parts_->MainMessageLoopRun(&result_code_);
879
[email protected]b48c9182011-10-26 18:03:30880 if (!ran_main_loop)
881 MainMessageLoopRun();
882
883 TRACE_EVENT_END_ETW("BrowserMain:MESSAGE_LOOP", 0, "");
[email protected]2e5b60a22011-11-28 15:56:41884}
885
886void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
[email protected]57624ab2013-08-01 16:01:51887 if (!created_threads_) {
888 // Called early, nothing to do
889 return;
890 }
[email protected]8b03c072014-04-30 15:49:25891 TRACE_EVENT0("shutdown", "BrowserMainLoop::ShutdownThreadsAndCleanUp");
[email protected]89af4002013-09-06 07:47:07892
[email protected]2e5b60a22011-11-28 15:56:41893 // Teardown may start in PostMainMessageLoopRun, and during teardown we
894 // need to be able to perform IO.
895 base::ThreadRestrictions::SetIOAllowed(true);
896 BrowserThread::PostTask(
[email protected]8f5a7e492012-01-01 02:14:47897 BrowserThread::IO, FROM_HERE,
[email protected]71cb8aa2011-12-29 19:14:00898 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
899 true));
[email protected]2e5b60a22011-11-28 15:56:41900
rockotb814a582015-06-05 00:30:52901 mojo_shell_context_.reset();
902
[email protected]f68c1462014-04-24 18:17:53903#if !defined(OS_IOS)
[email protected]40bfaf32013-11-19 01:35:43904 if (RenderProcessHost::run_renderer_in_process())
905 RenderProcessHostImpl::ShutDownInProcessRenderer();
[email protected]f68c1462014-04-24 18:17:53906#endif
[email protected]7fff5862013-10-15 20:39:01907
[email protected]89af4002013-09-06 07:47:07908 if (parts_) {
909 TRACE_EVENT0("shutdown",
910 "BrowserMainLoop::Subsystem:PostMainMessageLoopRun");
[email protected]50462bf02011-11-21 19:13:31911 parts_->PostMainMessageLoopRun();
[email protected]89af4002013-09-06 07:47:07912 }
[email protected]2e5b60a22011-11-28 15:56:41913
[email protected]111494e2013-07-24 18:38:29914 trace_memory_controller_.reset();
[email protected]e5a631a2013-09-18 07:33:27915 system_stats_monitor_.reset();
[email protected]111494e2013-07-24 18:38:29916
[email protected]759a86a2012-09-10 14:42:54917#if !defined(OS_IOS)
[email protected]64d69de42012-02-06 00:19:54918 // Destroying the GpuProcessHostUIShims on the UI thread posts a task to
919 // delete related objects on the GPU thread. This must be done before
920 // stopping the GPU thread. The GPU thread will close IPC channels to renderer
921 // processes so this has to happen before stopping the IO thread.
[email protected]89af4002013-09-06 07:47:07922 {
923 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:GPUProcessHostShim");
924 GpuProcessHostUIShim::DestroyAll();
925 }
[email protected]99907362012-01-11 05:41:40926 // Cancel pending requests and prevent new requests.
[email protected]89af4002013-09-06 07:47:07927 if (resource_dispatcher_host_) {
928 TRACE_EVENT0("shutdown",
929 "BrowserMainLoop::Subsystem:ResourceDispatcherHost");
[email protected]99907362012-01-11 05:41:40930 resource_dispatcher_host_.get()->Shutdown();
[email protected]89af4002013-09-06 07:47:07931 }
[email protected]99907362012-01-11 05:41:40932
dmichael6d5c49f02015-04-15 16:07:27933 memory_pressure_monitor_.reset();
skuhne5e3879c2014-12-15 23:38:19934
ccamerona10e9812014-12-08 23:57:01935#if defined(OS_MACOSX)
936 BrowserCompositorMac::DisableRecyclingForShutdown();
937#endif
938
[email protected]4232b2502014-05-13 01:00:35939#if defined(USE_AURA) || defined(OS_MACOSX)
enne6d5c88bb2014-11-15 00:05:14940 {
[email protected]89af4002013-09-06 07:47:07941 TRACE_EVENT0("shutdown",
942 "BrowserMainLoop::Subsystem:ImageTransportFactory");
943 ImageTransportFactory::Terminate();
944 }
[email protected]894e8fc2012-02-24 13:29:50945#endif
[email protected]5b040e592012-02-10 02:56:10946
[email protected]10750832014-01-29 01:36:45947#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
948 ZygoteHostImpl::GetInstance()->TearDownAfterLastChild();
949#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
950
[email protected]14625442012-08-15 12:51:42951 // The device monitors are using |system_monitor_| as dependency, so delete
952 // them before |system_monitor_| goes away.
953 // On Mac and windows, the monitor needs to be destroyed on the same thread
954 // as they were created. On Linux, the monitor will be deleted when IO thread
955 // goes away.
956#if defined(OS_WIN)
957 system_message_window_.reset();
958#elif defined(OS_MACOSX)
959 device_monitor_mac_.reset();
960#endif
[email protected]759a86a2012-09-10 14:42:54961#endif // !defined(OS_IOS)
[email protected]14625442012-08-15 12:51:42962
[email protected]2e5b60a22011-11-28 15:56:41963 // Must be size_t so we can subtract from it.
964 for (size_t thread_id = BrowserThread::ID_COUNT - 1;
965 thread_id >= (BrowserThread::UI + 1);
966 --thread_id) {
967 // Find the thread object we want to stop. Looping over all valid
968 // BrowserThread IDs and DCHECKing on a missing case in the switch
969 // statement helps avoid a mismatch between this code and the
970 // BrowserThread::ID enumeration.
971 //
972 // The destruction order is the reverse order of occurrence in the
973 // BrowserThread::ID list. The rationale for the order is as
974 // follows (need to be filled in a bit):
975 //
[email protected]2e5b60a22011-11-28 15:56:41976 //
977 // - The IO thread is the only user of the CACHE thread.
978 //
979 // - The PROCESS_LAUNCHER thread must be stopped after IO in case
980 // the IO thread posted a task to terminate a process on the
981 // process launcher thread.
982 //
[email protected]2e5b60a22011-11-28 15:56:41983 // - (Not sure why DB stops last.)
[email protected]2e5b60a22011-11-28 15:56:41984 switch (thread_id) {
[email protected]89af4002013-09-06 07:47:07985 case BrowserThread::DB: {
[email protected]d904aee2014-08-15 21:29:11986 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:DBThread");
987 ResetThread_DB(db_thread_.Pass());
[email protected]2e5b60a22011-11-28 15:56:41988 break;
[email protected]d904aee2014-08-15 21:29:11989 }
[email protected]89af4002013-09-06 07:47:07990 case BrowserThread::FILE: {
[email protected]d904aee2014-08-15 21:29:11991 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:FileThread");
[email protected]759a86a2012-09-10 14:42:54992#if !defined(OS_IOS)
[email protected]d904aee2014-08-15 21:29:11993 // Clean up state that lives on or uses the file_thread_ before
994 // it goes away.
995 if (resource_dispatcher_host_)
996 resource_dispatcher_host_.get()->save_file_manager()->Shutdown();
[email protected]759a86a2012-09-10 14:42:54997#endif // !defined(OS_IOS)
[email protected]d904aee2014-08-15 21:29:11998 ResetThread_FILE(file_thread_.Pass());
[email protected]2e5b60a22011-11-28 15:56:41999 break;
[email protected]d904aee2014-08-15 21:29:111000 }
1001 case BrowserThread::FILE_USER_BLOCKING: {
1002 TRACE_EVENT0("shutdown",
1003 "BrowserMainLoop::Subsystem:FileUserBlockingThread");
1004 ResetThread_FILE_USER_BLOCKING(file_user_blocking_thread_.Pass());
1005 break;
1006 }
[email protected]89af4002013-09-06 07:47:071007 case BrowserThread::PROCESS_LAUNCHER: {
[email protected]d904aee2014-08-15 21:29:111008 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:LauncherThread");
1009 ResetThread_PROCESS_LAUNCHER(process_launcher_thread_.Pass());
[email protected]2e5b60a22011-11-28 15:56:411010 break;
[email protected]d904aee2014-08-15 21:29:111011 }
[email protected]89af4002013-09-06 07:47:071012 case BrowserThread::CACHE: {
[email protected]d904aee2014-08-15 21:29:111013 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:CacheThread");
1014 ResetThread_CACHE(cache_thread_.Pass());
[email protected]2e5b60a22011-11-28 15:56:411015 break;
[email protected]d904aee2014-08-15 21:29:111016 }
[email protected]89af4002013-09-06 07:47:071017 case BrowserThread::IO: {
[email protected]d904aee2014-08-15 21:29:111018 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:IOThread");
1019 ResetThread_IO(io_thread_.Pass());
[email protected]2e5b60a22011-11-28 15:56:411020 break;
[email protected]d904aee2014-08-15 21:29:111021 }
[email protected]2e5b60a22011-11-28 15:56:411022 case BrowserThread::UI:
1023 case BrowserThread::ID_COUNT:
1024 default:
1025 NOTREACHED();
1026 break;
1027 }
[email protected]2e5b60a22011-11-28 15:56:411028 }
1029
[email protected]89acda82013-06-25 20:52:501030#if !defined(OS_IOS)
[email protected]89af4002013-09-06 07:47:071031 {
1032 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:IndexedDBThread");
[email protected]d904aee2014-08-15 21:29:111033 ResetThread_IndexedDb(indexed_db_thread_.Pass());
[email protected]89af4002013-09-06 07:47:071034 }
[email protected]89acda82013-06-25 20:52:501035#endif
1036
[email protected]3189013e2012-01-19 04:11:571037 // Close the blocking I/O pool after the other threads. Other threads such
1038 // as the I/O thread may need to schedule work like closing files or flushing
1039 // data during shutdown, so the blocking pool needs to be available. There
1040 // may also be slow operations pending that will blcok shutdown, so closing
1041 // it here (which will block until required operations are complete) gives
1042 // more head start for those operations to finish.
[email protected]89af4002013-09-06 07:47:071043 {
1044 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:ThreadPool");
1045 BrowserThreadImpl::ShutdownThreadPool();
1046 }
[email protected]3189013e2012-01-19 04:11:571047
[email protected]a34087bd2012-10-11 17:05:301048#if !defined(OS_IOS)
[email protected]33fee2e52013-01-12 17:16:241049 // Must happen after the IO thread is shutdown since this may be accessed from
1050 // it.
[email protected]89af4002013-09-06 07:47:071051 {
1052 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:GPUChannelFactory");
[email protected]96ab016c2013-10-23 00:50:291053 if (BrowserGpuChannelHostFactory::instance())
1054 BrowserGpuChannelHostFactory::Terminate();
[email protected]89af4002013-09-06 07:47:071055 }
[email protected]33fee2e52013-01-12 17:16:241056
[email protected]00c0d042012-09-10 07:06:391057 // Must happen after the I/O thread is shutdown since this class lives on the
1058 // I/O thread and isn't threadsafe.
[email protected]89af4002013-09-06 07:47:071059 {
1060 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:GamepadService");
1061 GamepadService::GetInstance()->Terminate();
1062 }
1063 {
1064 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:SensorService");
1065 DeviceInertialSensorService::GetInstance()->Shutdown();
1066 }
1067 {
[email protected]51e2e882014-05-28 20:07:471068 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:BatteryStatusService");
ppi2438a3e2014-10-28 21:55:101069 device::BatteryStatusService::GetInstance()->Shutdown();
[email protected]51e2e882014-05-28 20:07:471070 }
1071 {
[email protected]89af4002013-09-06 07:47:071072 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:DeleteDataSources");
1073 URLDataManager::DeleteDataSources();
1074 }
[email protected]a34087bd2012-10-11 17:05:301075#endif // !defined(OS_IOS)
[email protected]00c0d042012-09-10 07:06:391076
[email protected]89af4002013-09-06 07:47:071077 if (parts_) {
1078 TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:PostDestroyThreads");
[email protected]2e5b60a22011-11-28 15:56:411079 parts_->PostDestroyThreads();
[email protected]89af4002013-09-06 07:47:071080 }
[email protected]b48c9182011-10-26 18:03:301081}
1082
[email protected]cec95632014-07-02 18:01:501083void BrowserMainLoop::StopStartupTracingTimer() {
1084 startup_trace_timer_.Stop();
1085}
1086
[email protected]b48c9182011-10-26 18:03:301087void BrowserMainLoop::InitializeMainThread() {
[email protected]8b03c072014-04-30 15:49:251088 TRACE_EVENT0("startup", "BrowserMainLoop::InitializeMainThread");
thestig7e202d1a2015-05-27 21:54:551089 static const char kThreadName[] = "CrBrowserMain";
[email protected]b48c9182011-10-26 18:03:301090 base::PlatformThread::SetName(kThreadName);
[email protected]59383c782013-04-17 16:43:271091 if (main_message_loop_)
[email protected]de88c5e2012-04-10 23:35:231092 main_message_loop_->set_thread_name(kThreadName);
[email protected]b48c9182011-10-26 18:03:301093
1094 // Register the main thread by instantiating it, but don't call any methods.
[email protected]dd32b1272013-05-04 14:17:111095 main_thread_.reset(
1096 new BrowserThreadImpl(BrowserThread::UI, base::MessageLoop::current()));
[email protected]b48c9182011-10-26 18:03:301097}
1098
[email protected]57624ab2013-08-01 16:01:511099int BrowserMainLoop::BrowserThreadsStarted() {
[email protected]8b03c072014-04-30 15:49:251100 TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted");
[email protected]57624ab2013-08-01 16:01:511101
1102#if !defined(OS_IOS)
1103 indexed_db_thread_.reset(new base::Thread("IndexedDB"));
1104 indexed_db_thread_->Start();
1105#endif
1106
boliu7439d042015-01-27 22:51:111107#if !defined(OS_IOS)
1108 HistogramSynchronizer::GetInstance();
1109
1110
1111 // GpuDataManager for in-process initialized in PreCreateThreads.
1112 bool initialize_gpu_data_manager = !UsingInProcessGpu();
[email protected]e9875de72013-01-24 01:55:061113#if defined(OS_ANDROID)
[email protected]b38864d2013-05-24 14:42:361114 // Up the priority of anything that touches with display tasks
1115 // (this thread is UI thread, and io_thread_ is for IPCs).
gab9a47073b2015-04-01 23:05:021116 io_thread_->SetPriority(base::ThreadPriority::DISPLAY);
1117 base::PlatformThread::SetThreadPriority(base::PlatformThread::CurrentHandle(),
1118 base::ThreadPriority::DISPLAY);
[email protected]e9875de72013-01-24 01:55:061119
boliu7439d042015-01-27 22:51:111120 // On Android, GLSurface::InitializeOneOff() must be called before
1121 // initalizing the GpuDataManagerImpl as it uses the GL bindings.
1122 // TODO(sievers): Shouldn't need to init full bindings to determine GL
1123 // version/vendor strings. crbug.com/326295
1124 if (initialize_gpu_data_manager) {
1125 // Note InitializeOneOff is not safe either for in-process gpu after
1126 // creating threads, since it may race with the gpu thread.
1127 if (!gfx::GLSurface::InitializeOneOff()) {
1128 LOG(FATAL) << "GLSurface::InitializeOneOff failed";
1129 }
[email protected]7b2576b2014-06-25 10:14:421130 }
[email protected]af7c5d92014-02-03 19:53:151131#endif
1132
[email protected]7b2576b2014-06-25 10:14:421133 if (initialize_gpu_data_manager)
1134 GpuDataManagerImpl::GetInstance()->Initialize();
[email protected]96ab016c2013-10-23 00:50:291135
[email protected]17f2f2a2014-04-17 21:35:181136 bool always_uses_gpu = true;
[email protected]96ab016c2013-10-23 00:50:291137 bool established_gpu_channel = false;
thestig7e202d1a2015-05-27 21:54:551138#if defined(OS_ANDROID)
1139 // TODO(crbug.com/439322): This should be set to |true|.
1140 established_gpu_channel = false;
1141 BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
1142#elif defined(USE_AURA) || defined(OS_MACOSX)
enne6d5c88bb2014-11-15 00:05:141143 established_gpu_channel = true;
halliwell1f2c1c42015-03-31 21:12:531144 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor() ||
1145 parsed_command_line_.HasSwitch(switches::kDisableGpuEarlyInit)) {
enne6d5c88bb2014-11-15 00:05:141146 established_gpu_channel = always_uses_gpu = false;
[email protected]96ab016c2013-10-23 00:50:291147 }
enne6d5c88bb2014-11-15 00:05:141148 BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
1149 ImageTransportFactory::Initialize();
1150#if defined(USE_AURA)
1151 if (aura::Env::GetInstance()) {
1152 aura::Env::GetInstance()->set_context_factory(GetContextFactory());
1153 }
thestig7e202d1a2015-05-27 21:54:551154#endif // defined(USE_AURA)
1155#endif // defined(OS_ANDROID)
[email protected]c6ff6a32012-07-17 19:01:011156
reveman84c4caf92015-05-01 20:10:221157 // Enable the GpuMemoryBuffer dump provider with IO thread affinity. Note that
1158 // unregistration happens on the IO thread (See
1159 // BrowserProcessSubThread::IOThreadPreCleanUp).
1160 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
1161 BrowserGpuMemoryBufferManager::current(), io_thread_->task_runner());
1162
dalecurtisfecee042015-03-26 00:37:441163 {
1164 TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:AudioMan");
1165 audio_manager_.reset(media::AudioManager::CreateWithHangTimer(
1166 MediaInternals::GetInstance(), io_thread_->task_runner()));
1167 }
1168
1169 {
1170 TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:MidiManager");
toyoshim78b9d632015-05-08 04:58:311171 midi_manager_.reset(media::midi::MidiManager::Create());
dalecurtisfecee042015-03-26 00:37:441172 }
1173
[email protected]49513e02013-11-20 08:36:401174#if defined(OS_LINUX) && defined(USE_UDEV)
[email protected]97646c92012-07-31 20:30:081175 device_monitor_linux_.reset(new DeviceMonitorLinux());
[email protected]14625442012-08-15 12:51:421176#elif defined(OS_MACOSX)
1177 device_monitor_mac_.reset(new DeviceMonitorMac());
[email protected]97646c92012-07-31 20:30:081178#endif
1179
wfh6575fb42015-01-28 04:05:211180#if defined(OS_WIN)
wfh150b6ef2015-02-02 19:20:421181 UMA_HISTOGRAM_BOOLEAN("Windows.Win32kRendererLockdown",
1182 IsWin32kRendererLockdownEnabled());
wfh6575fb42015-01-28 04:05:211183#endif
[email protected]aa328c72013-05-03 10:55:431184 // RDH needs the IO thread to be created
1185 {
1186 TRACE_EVENT0("startup",
1187 "BrowserMainLoop::BrowserThreadsStarted:InitResourceDispatcherHost");
1188 resource_dispatcher_host_.reset(new ResourceDispatcherHostImpl());
1189 }
[email protected]b14b873b2012-05-03 03:56:091190
[email protected]89c6eaf2012-11-26 18:52:271191 // MediaStreamManager needs the IO thread to be created.
[email protected]aa328c72013-05-03 10:55:431192 {
1193 TRACE_EVENT0("startup",
1194 "BrowserMainLoop::BrowserThreadsStarted:InitMediaStreamManager");
1195 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
1196 }
[email protected]89c6eaf2012-11-26 18:52:271197
[email protected]aa328c72013-05-03 10:55:431198 {
1199 TRACE_EVENT0("startup",
1200 "BrowserMainLoop::BrowserThreadsStarted:InitSpeechRecognition");
[email protected]aa445462013-06-21 17:12:361201 speech_recognition_manager_.reset(new SpeechRecognitionManagerImpl(
1202 audio_manager_.get(), media_stream_manager_.get()));
[email protected]aa328c72013-05-03 10:55:431203 }
[email protected]2dd33552012-09-11 16:39:551204
[email protected]61f697f2013-08-15 22:02:401205 {
1206 TRACE_EVENT0(
1207 "startup",
1208 "BrowserMainLoop::BrowserThreadsStarted::InitUserInputMonitor");
1209 user_input_monitor_ = media::UserInputMonitor::Create(
1210 io_thread_->message_loop_proxy(), main_thread_->message_loop_proxy());
1211 }
1212
[email protected]8b03c072014-04-30 15:49:251213 {
1214 TRACE_EVENT0("startup",
1215 "BrowserMainLoop::BrowserThreadsStarted::TimeZoneMonitor");
1216 time_zone_monitor_ = TimeZoneMonitor::Create();
1217 }
1218
[email protected]2dd33552012-09-11 16:39:551219 // Alert the clipboard class to which threads are allowed to access the
1220 // clipboard:
1221 std::vector<base::PlatformThreadId> allowed_clipboard_threads;
1222 // The current thread is the UI thread.
1223 allowed_clipboard_threads.push_back(base::PlatformThread::CurrentId());
1224#if defined(OS_WIN)
thestig7e202d1a2015-05-27 21:54:551225 // On Windows, clipboards are also used on the FILE or IO threads.
[email protected]2dd33552012-09-11 16:39:551226 allowed_clipboard_threads.push_back(file_thread_->thread_id());
1227 allowed_clipboard_threads.push_back(io_thread_->thread_id());
1228#endif
1229 ui::Clipboard::SetAllowedThreads(allowed_clipboard_threads);
[email protected]3220d1b2012-12-08 04:13:351230
1231 // When running the GPU thread in-process, avoid optimistically starting it
1232 // since creating the GPU thread races against creation of the one-and-only
1233 // ChildProcess instance which is created by the renderer thread.
[email protected]a0401382013-05-07 00:12:551234 if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) &&
[email protected]96ab016c2013-10-23 00:50:291235 !established_gpu_channel &&
[email protected]234edc02013-08-20 12:03:131236 always_uses_gpu &&
boliu7439d042015-01-27 22:51:111237 !UsingInProcessGpu()) {
[email protected]c76faea2013-03-26 07:42:421238 TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
1239 TRACE_EVENT_SCOPE_THREAD);
[email protected]3220d1b2012-12-08 04:13:351240 BrowserThread::PostTask(
thestig7e202d1a2015-05-27 21:54:551241 BrowserThread::IO, FROM_HERE,
1242 base::Bind(base::IgnoreResult(&GpuProcessHost::Get),
1243 GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
1244 CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP));
[email protected]3220d1b2012-12-08 04:13:351245 }
[email protected]b0988b22013-11-08 08:25:581246
1247#if defined(OS_MACOSX)
1248 ThemeHelperMac::GetInstance();
[email protected]cc405e42014-07-31 11:35:511249 SystemHotkeyHelperMac::GetInstance()->DeferredLoadSystemHotkeys();
[email protected]f5bcd0f2014-06-10 14:50:411250 if (ShouldEnableBootstrapSandbox()) {
1251 TRACE_EVENT0("startup",
thestig7e202d1a2015-05-27 21:54:551252 "BrowserMainLoop::BrowserThreadsStarted:BootstrapSandbox");
[email protected]f5bcd0f2014-06-10 14:50:411253 CHECK(GetBootstrapSandbox());
1254 }
1255#endif // defined(OS_MACOSX)
1256
[email protected]291857a2014-01-23 17:49:111257#endif // !defined(OS_IOS)
1258
rockotb814a582015-06-05 00:30:521259 mojo_shell_context_.reset(new MojoShellContext);
1260
[email protected]57624ab2013-08-01 16:01:511261 return result_code_;
[email protected]99907362012-01-11 05:41:401262}
1263
boliu7439d042015-01-27 22:51:111264bool BrowserMainLoop::UsingInProcessGpu() const {
1265 return parsed_command_line_.HasSwitch(switches::kSingleProcess) ||
1266 parsed_command_line_.HasSwitch(switches::kInProcessGPU);
1267}
1268
[email protected]d957b102014-04-25 20:17:191269bool BrowserMainLoop::InitializeToolkit() {
[email protected]8b03c072014-04-30 15:49:251270 TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit");
yiyaoliu252f915e2015-04-23 21:56:361271 TRACK_SCOPED_REGION("Startup", "BrowserMainLoop::InitializeToolkit");
1272
[email protected]b48c9182011-10-26 18:03:301273 // TODO(evan): this function is rather subtle, due to the variety
1274 // of intersecting ifdefs we have. To keep it easy to follow, there
1275 // are no #else branches on any #ifs.
1276 // TODO(stevenjb): Move platform specific code into platform specific Parts
1277 // (Need to add InitializeToolkit stage to BrowserParts).
[email protected]d3f854952013-10-23 23:19:341278 // See also GTK setup in EarlyInitialization, above, and associated comments.
[email protected]b48c9182011-10-26 18:03:301279
[email protected]b48c9182011-10-26 18:03:301280#if defined(OS_WIN)
1281 // Init common control sex.
1282 INITCOMMONCONTROLSEX config;
1283 config.dwSize = sizeof(config);
1284 config.dwICC = ICC_WIN95_CLASSES;
1285 if (!InitCommonControlsEx(&config))
[email protected]ad8cfa92014-05-21 20:06:231286 PLOG(FATAL);
[email protected]b48c9182011-10-26 18:03:301287#endif
1288
[email protected]da5f8412014-04-23 17:42:001289#if defined(USE_AURA)
[email protected]d957b102014-04-25 20:17:191290
1291#if defined(USE_X11)
1292 if (!gfx::GetXDisplay())
1293 return false;
1294#endif
1295
[email protected]da5f8412014-04-23 17:42:001296 // Env creates the compositor. Aura widgets need the compositor to be created
1297 // before they can be initialized by the browser.
[email protected]5b883abb2014-05-05 06:44:101298 aura::Env::CreateInstance(true);
[email protected]d957b102014-04-25 20:17:191299#endif // defined(USE_AURA)
[email protected]da5f8412014-04-23 17:42:001300
[email protected]59383c782013-04-17 16:43:271301 if (parts_)
[email protected]50462bf02011-11-21 19:13:311302 parts_->ToolkitInitialized();
[email protected]d957b102014-04-25 20:17:191303
1304 return true;
[email protected]b48c9182011-10-26 18:03:301305}
1306
1307void BrowserMainLoop::MainMessageLoopRun() {
[email protected]8e937c1e2012-06-28 22:57:301308#if defined(OS_ANDROID)
[email protected]a08029b42012-04-25 03:18:461309 // Android's main message loop is the Java message loop.
1310 NOTREACHED();
[email protected]b48c9182011-10-26 18:03:301311#else
[email protected]9d434e22014-01-20 08:59:521312 DCHECK(base::MessageLoopForUI::IsCurrent());
thestig7e202d1a2015-05-27 21:54:551313 if (parameters_.ui_task) {
[email protected]dd32b1272013-05-04 14:17:111314 base::MessageLoopForUI::current()->PostTask(FROM_HERE,
1315 *parameters_.ui_task);
thestig7e202d1a2015-05-27 21:54:551316 }
[email protected]8e937c1e2012-06-28 22:57:301317
1318 base::RunLoop run_loop;
1319 run_loop.Run();
[email protected]b48c9182011-10-26 18:03:301320#endif
1321}
1322
[email protected]cec95632014-07-02 18:01:501323base::FilePath BrowserMainLoop::GetStartupTraceFileName(
1324 const base::CommandLine& command_line) const {
[email protected]1eb14612013-11-21 01:04:581325 base::FilePath trace_file = command_line.GetSwitchValuePath(
1326 switches::kTraceStartupFile);
1327 // trace_file = "none" means that startup events will show up for the next
1328 // begin/end tracing (via about:tracing or AutomationProxy::BeginTracing/
1329 // EndTracing, for example).
1330 if (trace_file == base::FilePath().AppendASCII("none"))
[email protected]cec95632014-07-02 18:01:501331 return trace_file;
[email protected]1eb14612013-11-21 01:04:581332
1333 if (trace_file.empty()) {
[email protected]d6d3c7f2014-04-11 01:28:541334#if defined(OS_ANDROID)
1335 TracingControllerAndroid::GenerateTracingFilePath(&trace_file);
1336#else
[email protected]1eb14612013-11-21 01:04:581337 // Default to saving the startup trace into the current dir.
1338 trace_file = base::FilePath().AppendASCII("chrometrace.log");
[email protected]d6d3c7f2014-04-11 01:28:541339#endif
[email protected]1eb14612013-11-21 01:04:581340 }
1341
[email protected]cec95632014-07-02 18:01:501342 return trace_file;
1343}
1344
[email protected]479278702014-08-11 20:32:091345void BrowserMainLoop::InitStartupTracing(
1346 const base::CommandLine& command_line) {
[email protected]cec95632014-07-02 18:01:501347 DCHECK(is_tracing_startup_);
1348
1349 startup_trace_file_ = GetStartupTraceFileName(parsed_command_line_);
1350
[email protected]1eb14612013-11-21 01:04:581351 std::string delay_str = command_line.GetSwitchValueASCII(
1352 switches::kTraceStartupDuration);
1353 int delay_secs = 5;
1354 if (!delay_str.empty() && !base::StringToInt(delay_str, &delay_secs)) {
1355 DLOG(WARNING) << "Could not parse --" << switches::kTraceStartupDuration
1356 << "=" << delay_str << " defaulting to 5 (secs)";
1357 delay_secs = 5;
1358 }
1359
[email protected]cec95632014-07-02 18:01:501360 startup_trace_timer_.Start(FROM_HERE,
1361 base::TimeDelta::FromSeconds(delay_secs),
1362 this,
1363 &BrowserMainLoop::EndStartupTracing);
[email protected]1eb14612013-11-21 01:04:581364}
1365
[email protected]cec95632014-07-02 18:01:501366void BrowserMainLoop::EndStartupTracing() {
thestig7e202d1a2015-05-27 21:54:551367 DCHECK(is_tracing_startup_);
1368
[email protected]1eb14612013-11-21 01:04:581369 is_tracing_startup_ = false;
1370 TracingController::GetInstance()->DisableRecording(
caseqb85bb8f2014-09-15 10:50:101371 TracingController::CreateFileSink(
1372 startup_trace_file_,
1373 base::Bind(OnStoppedStartupTracing, startup_trace_file_)));
[email protected]1eb14612013-11-21 01:04:581374}
1375
[email protected]b48c9182011-10-26 18:03:301376} // namespace content