1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/browser/browser_main_loop.h"
6 
7 #include <stddef.h>
8 
9 #include <algorithm>
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "base/base_switches.h"
16 #include "base/bind.h"
17 #include "base/command_line.h"
18 #include "base/debug/alias.h"
19 #include "base/deferred_sequenced_task_runner.h"
20 #include "base/feature_list.h"
21 #include "base/location.h"
22 #include "base/logging.h"
23 #include "base/memory/memory_pressure_monitor.h"
24 #include "base/memory/ptr_util.h"
25 #include "base/message_loop/message_loop_current.h"
26 #include "base/metrics/field_trial.h"
27 #include "base/metrics/histogram_macros.h"
28 #include "base/metrics/user_metrics.h"
29 #include "base/no_destructor.h"
30 #include "base/path_service.h"
31 #include "base/pending_task.h"
32 #include "base/power_monitor/power_monitor.h"
33 #include "base/power_monitor/power_monitor_device_source.h"
34 #include "base/process/process_metrics.h"
35 #include "base/run_loop.h"
36 #include "base/scoped_observer.h"
37 #include "base/single_thread_task_runner.h"
38 #include "base/stl_util.h"
39 #include "base/strings/string_number_conversions.h"
40 #include "base/strings/string_split.h"
41 #include "base/synchronization/waitable_event.h"
42 #include "base/system/system_monitor.h"
43 #include "base/task/post_task.h"
44 #include "base/task/thread_pool/initialization_util.h"
45 #include "base/threading/thread.h"
46 #include "base/threading/thread_restrictions.h"
47 #include "base/threading/thread_task_runner_handle.h"
48 #include "base/time/time.h"
49 #include "base/timer/hi_res_timer_manager.h"
50 #include "base/trace_event/memory_dump_manager.h"
51 #include "base/trace_event/trace_event.h"
52 #include "base/util/memory_pressure/multi_source_memory_pressure_monitor.h"
53 #include "build/branding_buildflags.h"
54 #include "build/build_config.h"
55 #include "cc/base/histograms.h"
56 #include "components/discardable_memory/service/discardable_shared_memory_manager.h"
57 #include "components/services/storage/dom_storage/storage_area_impl.h"
58 #include "components/tracing/common/trace_startup_config.h"
59 #include "components/tracing/common/trace_to_console.h"
60 #include "components/tracing/common/tracing_switches.h"
61 #include "components/viz/host/compositing_mode_reporter_impl.h"
62 #include "components/viz/host/gpu_host_impl.h"
63 #include "components/viz/host/host_frame_sink_manager.h"
64 #include "content/browser/browser_thread_impl.h"
65 #include "content/browser/child_process_security_policy_impl.h"
66 #include "content/browser/compositor/viz_process_transport_factory.h"
67 #include "content/browser/download/save_file_manager.h"
68 #include "content/browser/field_trial_synchronizer.h"
69 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
70 #include "content/browser/gpu/browser_gpu_client_delegate.h"
71 #include "content/browser/gpu/compositor_util.h"
72 #include "content/browser/gpu/gpu_data_manager_impl.h"
73 #include "content/browser/gpu/gpu_process_host.h"
74 #include "content/browser/gpu/shader_cache_factory.h"
75 #include "content/browser/histogram_synchronizer.h"
76 #include "content/browser/media/capture/audio_mirroring_manager.h"
77 #include "content/browser/media/media_internals.h"
78 #include "content/browser/media/media_keys_listener_manager_impl.h"
79 #include "content/browser/net/browser_online_state_observer.h"
80 #include "content/browser/network_service_instance_impl.h"
81 #include "content/browser/renderer_host/media/media_stream_manager.h"
82 #include "content/browser/renderer_host/render_process_host_impl.h"
83 #include "content/browser/scheduler/browser_task_executor.h"
84 #include "content/browser/scheduler/responsiveness/watcher.h"
85 #include "content/browser/screenlock_monitor/screenlock_monitor.h"
86 #include "content/browser/screenlock_monitor/screenlock_monitor_device_source.h"
87 #if BUILDFLAG(ENABLE_WEB_SPEECH)
88 #include "content/browser/speech/speech_recognition_manager_impl.h"
89 #endif
90 #include "content/browser/startup_data_impl.h"
91 #include "content/browser/startup_task_runner.h"
92 #include "content/browser/tracing/background_tracing_manager_impl.h"
93 #include "content/browser/tracing/tracing_controller_impl.h"
94 #include "content/browser/utility_process_host.h"
95 #include "content/browser/webui/content_web_ui_controller_factory.h"
96 #include "content/browser/webui/url_data_manager.h"
97 #include "content/common/content_switches_internal.h"
98 #include "content/common/thread_pool_util.h"
99 #include "content/public/browser/audio_service.h"
100 #include "content/public/browser/browser_main_parts.h"
101 #include "content/public/browser/browser_task_traits.h"
102 #include "content/public/browser/browser_thread.h"
103 #include "content/public/browser/content_browser_client.h"
104 #include "content/public/browser/device_service.h"
105 #include "content/public/browser/gpu_data_manager_observer.h"
106 #include "content/public/browser/network_service_instance.h"
107 #include "content/public/browser/render_process_host.h"
108 #include "content/public/browser/service_process_host.h"
109 #include "content/public/browser/site_isolation_policy.h"
110 #include "content/public/common/content_client.h"
111 #include "content/public/common/content_features.h"
112 #include "content/public/common/content_switches.h"
113 #include "content/public/common/main_function_params.h"
114 #include "content/public/common/result_codes.h"
115 #include "content/public/common/service_names.mojom.h"
116 #include "device/fido/hid/fido_hid_discovery.h"
117 #include "device/gamepad/gamepad_service.h"
118 #include "media/audio/audio_manager.h"
119 #include "media/audio/audio_system.h"
120 #include "media/audio/audio_thread_impl.h"
121 #include "media/base/media.h"
122 #include "media/base/user_input_monitor.h"
123 #include "media/media_buildflags.h"
124 #include "media/midi/midi_service.h"
125 #include "media/mojo/buildflags.h"
126 #include "mojo/core/embedder/embedder.h"
127 #include "mojo/core/embedder/scoped_ipc_support.h"
128 #include "mojo/public/cpp/bindings/mojo_buildflags.h"
129 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
130 #include "net/base/network_change_notifier.h"
131 #include "net/socket/client_socket_factory.h"
132 #include "net/ssl/ssl_config_service.h"
133 #include "ppapi/buildflags/buildflags.h"
134 #include "services/audio/service.h"
135 #include "services/content/public/cpp/navigable_contents_view.h"
136 #include "services/data_decoder/public/cpp/service_provider.h"
137 #include "services/network/transitional_url_loader_factory_owner.h"
138 #include "services/service_manager/zygote/common/zygote_buildflags.h"
139 #include "skia/ext/event_tracer_impl.h"
140 #include "skia/ext/skia_memory_dump_provider.h"
141 #include "sql/sql_memory_dump_provider.h"
142 #include "ui/base/clipboard/clipboard.h"
143 #include "ui/display/display_features.h"
144 #include "ui/gfx/font_render_params.h"
145 #include "ui/gfx/switches.h"
146 
147 #if defined(USE_AURA) || defined(OS_MACOSX)
148 #include "content/browser/compositor/image_transport_factory.h"
149 #endif
150 
151 #if defined(USE_AURA)
152 #include "content/public/browser/context_factory.h"
153 #include "ui/aura/env.h"
154 #endif
155 
156 #if defined(OS_ANDROID)
157 #include "base/android/jni_android.h"
158 #include "base/trace_event/cpufreq_monitor_android.h"
159 #include "components/tracing/common/graphics_memory_dump_provider_android.h"
160 #include "content/browser/android/browser_startup_controller.h"
161 #include "content/browser/android/launcher_thread.h"
162 #include "content/browser/android/scoped_surface_request_manager.h"
163 #include "content/browser/android/tracing_controller_android.h"
164 #include "content/browser/font_unique_name_lookup/font_unique_name_lookup.h"
165 #include "content/browser/screen_orientation/screen_orientation_delegate_android.h"
166 #include "media/base/android/media_drm_bridge_client.h"
167 #include "ui/android/screen_android.h"
168 #include "ui/display/screen.h"
169 #include "ui/gl/gl_surface.h"
170 #endif
171 
172 #if defined(OS_MACOSX)
173 #include "content/browser/renderer_host/browser_compositor_view_mac.h"
174 #include "content/browser/theme_helper_mac.h"
175 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
176 #endif
177 
178 #if defined(OS_WIN)
179 #include <commctrl.h>
180 #include <shellapi.h>
181 #include <windows.h>
182 
183 #include "content/browser/renderer_host/dwrite_font_lookup_table_builder_win.h"
184 #include "net/base/winsock_init.h"
185 #include "services/service_manager/sandbox/win/sandbox_win.h"
186 #include "ui/display/win/screen_win.h"
187 #endif
188 
189 #if defined(OS_CHROMEOS)
190 #include "chromeos/constants/chromeos_switches.h"
191 #include "device/bluetooth/bluetooth_adapter_factory.h"
192 #include "services/data_decoder/public/cpp/data_decoder.h"
193 #endif
194 
195 #if defined(USE_GLIB)
196 #include <glib-object.h>
197 #endif
198 
199 #if defined(OS_WIN)
200 #include "media/device_monitors/system_message_window_win.h"
201 #include "sandbox/win/src/process_mitigations.h"
202 #elif defined(OS_LINUX) && defined(USE_UDEV)
203 #include "media/device_monitors/device_monitor_udev.h"
204 #elif defined(OS_MACOSX)
205 #include "media/device_monitors/device_monitor_mac.h"
206 #endif
207 
208 #if defined(OS_FUCHSIA)
209 #include <lib/zx/job.h>
210 
211 #include "base/fuchsia/default_job.h"
212 #include "base/fuchsia/fuchsia_logging.h"
213 #endif  // defined(OS_FUCHSIA)
214 
215 #if defined(OS_POSIX) && !defined(OS_MACOSX)
216 #include "content/browser/sandbox_host_linux.h"
217 #endif
218 
219 #if BUILDFLAG(ENABLE_PLUGINS)
220 #include "content/browser/plugin_service_impl.h"
221 #endif
222 
223 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
224 #include "content/browser/media/cdm_registry_impl.h"
225 #endif
226 
227 #if BUILDFLAG(ENABLE_WEBRTC)
228 #include "content/browser/webrtc/webrtc_internals.h"
229 #endif
230 
231 #if defined(USE_X11)
232 #include "gpu/config/gpu_driver_bug_workaround_type.h"
233 #include "ui/base/x/x11_util_internal.h"  // nogncheck
234 #include "ui/gfx/x/x11_connection.h"      // nogncheck
235 #include "ui/gfx/x/x11_types.h"           // nogncheck
236 #endif
237 
238 #if defined(USE_NSS_CERTS)
239 #include "crypto/nss_util.h"
240 #endif
241 
242 #if defined(ENABLE_IPC_FUZZER) && defined(OS_MACOSX)
243 #include "base/mac/foundation_util.h"
244 #endif
245 
246 #if BUILDFLAG(MOJO_RANDOM_DELAYS_ENABLED)
247 #include "mojo/public/cpp/bindings/lib/test_random_mojo_delays.h"
248 #endif
249 
250 #if defined(OS_BSD)
251 #include "content/browser/sandbox_host_linux.h"
252 #include "services/service_manager/zygote/common/common_sandbox_support_linux.h"
253 #include "content/public/common/common_sandbox_support_linux.h"
254 #include "services/service_manager/sandbox/sandbox.h"
255 #endif
256 
257 // One of the linux specific headers defines this as a macro.
258 #ifdef DestroyAll
259 #undef DestroyAll
260 #endif
261 
262 namespace content {
263 namespace {
264 
265 #if defined(USE_GLIB)
GLibLogHandler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer userdata)266 static void GLibLogHandler(const gchar* log_domain,
267                            GLogLevelFlags log_level,
268                            const gchar* message,
269                            gpointer userdata) {
270   if (!log_domain)
271     log_domain = "<unknown>";
272   if (!message)
273     message = "<no message>";
274 
275   GLogLevelFlags always_fatal_flags = g_log_set_always_fatal(G_LOG_LEVEL_MASK);
276   g_log_set_always_fatal(always_fatal_flags);
277   GLogLevelFlags fatal_flags =
278       g_log_set_fatal_mask(log_domain, G_LOG_LEVEL_MASK);
279   g_log_set_fatal_mask(log_domain, fatal_flags);
280   if ((always_fatal_flags | fatal_flags) & log_level) {
281     LOG(DFATAL) << log_domain << ": " << message;
282   } else if (log_level & (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL)) {
283     LOG(ERROR) << log_domain << ": " << message;
284   } else if (log_level & (G_LOG_LEVEL_WARNING)) {
285     LOG(WARNING) << log_domain << ": " << message;
286   } else if (log_level &
287              (G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG)) {
288     LOG(INFO) << log_domain << ": " << message;
289   } else {
290     NOTREACHED();
291     LOG(DFATAL) << log_domain << ": " << message;
292   }
293 }
294 
SetUpGLibLogHandler()295 static void SetUpGLibLogHandler() {
296   // Register GLib-handled assertions to go through our logging system.
297   const char* const kLogDomains[] = {nullptr, "Gtk", "Gdk", "GLib",
298                                      "GLib-GObject"};
299   for (size_t i = 0; i < base::size(kLogDomains); i++) {
300     g_log_set_handler(
301         kLogDomains[i],
302         static_cast<GLogLevelFlags>(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL |
303                                     G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL |
304                                     G_LOG_LEVEL_WARNING),
305         GLibLogHandler, nullptr);
306   }
307 }
308 #endif  // defined(USE_GLIB)
309 
310 // Tell compiler not to inline this function so it's possible to tell what
311 // thread was unresponsive by inspecting the callstack.
ResetThread_IO(std::unique_ptr<BrowserProcessSubThread> io_thread)312 NOINLINE void ResetThread_IO(
313     std::unique_ptr<BrowserProcessSubThread> io_thread) {
314   const int line_number = __LINE__;
315   io_thread.reset();
316   base::debug::Alias(&line_number);
317 }
318 
319 enum WorkerPoolType : size_t {
320   BACKGROUND = 0,
321   BACKGROUND_BLOCKING,
322   FOREGROUND,
323   FOREGROUND_BLOCKING,
324   WORKER_POOL_COUNT  // Always last.
325 };
326 
327 #if defined(OS_FUCHSIA)
328 // Create and register the job which will contain all child processes
329 // of the browser process as well as their descendents.
InitDefaultJob()330 void InitDefaultJob() {
331   zx::job job;
332   zx_status_t result = zx::job::create(*zx::job::default_job(), 0, &job);
333   ZX_CHECK(ZX_OK == result, result) << "zx_job_create";
334   base::SetDefaultJob(std::move(job));
335 }
336 #endif  // defined(OS_FUCHSIA)
337 
338 #if defined(ENABLE_IPC_FUZZER)
GetBuildDirectory(base::FilePath * result)339 bool GetBuildDirectory(base::FilePath* result) {
340   if (!base::PathService::Get(base::DIR_EXE, result))
341     return false;
342 
343 #if defined(OS_MACOSX)
344   if (base::mac::AmIBundled()) {
345     // The bundled app executables (Chromium, TestShell, etc) live three
346     // levels down from the build directory, eg:
347     // Chromium.app/Contents/MacOS/Chromium
348     *result = result->DirName().DirName().DirName();
349   }
350 #endif
351   return true;
352 }
353 
SetFileUrlPathAliasForIpcFuzzer()354 void SetFileUrlPathAliasForIpcFuzzer() {
355   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
356           switches::kFileUrlPathAlias))
357     return;
358 
359   base::FilePath build_directory;
360   if (!GetBuildDirectory(&build_directory)) {
361     LOG(ERROR) << "Failed to get build directory for /gen path alias.";
362     return;
363   }
364 
365   const base::CommandLine::StringType alias_switch =
366       FILE_PATH_LITERAL("/gen=") + build_directory.AppendASCII("gen").value();
367   base::CommandLine::ForCurrentProcess()->AppendSwitchNative(
368       switches::kFileUrlPathAlias, alias_switch);
369 }
370 #endif
371 
CreateMemoryPressureMonitor(const base::CommandLine & command_line)372 std::unique_ptr<base::MemoryPressureMonitor> CreateMemoryPressureMonitor(
373     const base::CommandLine& command_line) {
374   // Behavior of browser tests should not depend on things outside of their
375   // control (like the amount of memory on the system running the tests).
376   if (command_line.HasSwitch(switches::kBrowserTest))
377     return nullptr;
378 
379   std::unique_ptr<util::MultiSourceMemoryPressureMonitor> monitor;
380 
381 #if defined(OS_CHROMEOS)
382   if (chromeos::switches::MemoryPressureHandlingEnabled())
383     monitor = std::make_unique<util::MultiSourceMemoryPressureMonitor>();
384 #elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_FUCHSIA)
385   monitor = std::make_unique<util::MultiSourceMemoryPressureMonitor>();
386 #endif
387   // No memory monitor on other platforms...
388 
389   if (monitor)
390     monitor->Start();
391 
392   return monitor;
393 }
394 
395 #if defined(OS_CHROMEOS)
GetBleScanParser()396 mojo::PendingRemote<data_decoder::mojom::BleScanParser> GetBleScanParser() {
397   static base::NoDestructor<data_decoder::DataDecoder> decoder;
398   mojo::PendingRemote<data_decoder::mojom::BleScanParser> ble_scan_parser;
399   decoder->GetService()->BindBleScanParser(
400       ble_scan_parser.InitWithNewPipeAndPassReceiver());
401   return ble_scan_parser;
402 }
403 #endif  // defined(OS_CHROMEOS)
404 
405 #if defined(OS_WIN)
406 // Disable dynamic code using ACG. Prevents the browser process from generating
407 // dynamic code or modifying executable code. See comments in
408 // sandbox/win/src/security_level.h. Only available on Windows 10 RS1 (1607,
409 // Build 14393) onwards.
410 const base::Feature kBrowserDynamicCodeDisabled{
411     "BrowserDynamicCodeDisabled", base::FEATURE_DISABLED_BY_DEFAULT};
412 #endif  // defined(OS_WIN)
413 
414 class OopDataDecoder : public data_decoder::ServiceProvider {
415  public:
OopDataDecoder()416   OopDataDecoder() { data_decoder::ServiceProvider::Set(this); }
~OopDataDecoder()417   ~OopDataDecoder() override { data_decoder::ServiceProvider::Set(nullptr); }
418 
419   // data_decoder::ServiceProvider implementation:
BindDataDecoderService(mojo::PendingReceiver<data_decoder::mojom::DataDecoderService> receiver)420   void BindDataDecoderService(
421       mojo::PendingReceiver<data_decoder::mojom::DataDecoderService> receiver)
422       override {
423     ServiceProcessHost::Launch(
424         std::move(receiver),
425         ServiceProcessHost::Options()
426             .WithSandboxType(service_manager::SandboxType::kUtility)
427             .WithDisplayName("Data Decoder Service")
428             .Pass());
429   }
430 
431  private:
432   DISALLOW_COPY_AND_ASSIGN(OopDataDecoder);
433 };
434 
BindHidManager(mojo::PendingReceiver<device::mojom::HidManager> receiver)435 void BindHidManager(mojo::PendingReceiver<device::mojom::HidManager> receiver) {
436 #if !defined(OS_ANDROID)
437   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
438     base::PostTask(FROM_HERE, {BrowserThread::UI},
439                    base::BindOnce(&BindHidManager, std::move(receiver)));
440     return;
441   }
442 
443   GetDeviceService().BindHidManager(std::move(receiver));
444 #endif
445 }
446 
447 }  // namespace
448 
449 #if defined(USE_X11)
450 namespace internal {
451 
452 // Forwards GPUInfo updates to ui::XVisualManager
453 class GpuDataManagerVisualProxy : public GpuDataManagerObserver {
454  public:
GpuDataManagerVisualProxy(GpuDataManagerImpl * gpu_data_manager)455   explicit GpuDataManagerVisualProxy(GpuDataManagerImpl* gpu_data_manager)
456       : gpu_data_manager_(gpu_data_manager) {
457     if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless))
458       scoped_observer_.Add(gpu_data_manager_);
459   }
460 
461   ~GpuDataManagerVisualProxy() override = default;
462 
OnGpuInfoUpdate()463   void OnGpuInfoUpdate() override { OnUpdate(); }
OnGpuExtraInfoUpdate()464   void OnGpuExtraInfoUpdate() override { OnUpdate(); }
465 
466  private:
OnUpdate()467   void OnUpdate() {
468     if (!gfx::GetXDisplay())
469       return;
470     gpu::GPUInfo gpu_info = gpu_data_manager_->GetGPUInfo();
471     gpu::GpuExtraInfo gpu_extra_info = gpu_data_manager_->GetGpuExtraInfo();
472     if (!ui::XVisualManager::GetInstance()->OnGPUInfoChanged(
473             gpu_info.software_rendering ||
474                 !gpu_data_manager_->GpuAccessAllowed(nullptr),
475             gpu_extra_info.system_visual, gpu_extra_info.rgba_visual)) {
476       // The GPU process sent back bad visuals, which should never happen.
477       auto* gpu_process_host =
478           GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED, false);
479       if (gpu_process_host)
480         gpu_process_host->ForceShutdown();
481     }
482   }
483 
484   GpuDataManagerImpl* gpu_data_manager_;
485 
486   ScopedObserver<GpuDataManagerImpl, GpuDataManagerObserver> scoped_observer_{
487       this};
488 
489   DISALLOW_COPY_AND_ASSIGN(GpuDataManagerVisualProxy);
490 };
491 
492 }  // namespace internal
493 #endif
494 
495 #if defined(OS_WIN)
496 namespace {
497 
498 // Provides a bridge whereby display::win::ScreenWin can ask the GPU process
499 // about the HDR status of the system.
500 class HDRProxy {
501  public:
Initialize()502   static void Initialize() {
503     display::win::ScreenWin::SetRequestHDRStatusCallback(
504         base::BindRepeating(&HDRProxy::RequestHDRStatus));
505   }
506 
RequestHDRStatus()507   static void RequestHDRStatus() {
508     // The request must be sent to the GPU process from the IO thread.
509     base::PostTask(FROM_HERE, {BrowserThread::IO},
510                    base::BindOnce(&HDRProxy::RequestOnIOThread));
511   }
512 
513  private:
RequestOnIOThread()514   static void RequestOnIOThread() {
515     auto* gpu_process_host =
516         GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED, false);
517     if (gpu_process_host) {
518       auto* gpu_service = gpu_process_host->gpu_host()->gpu_service();
519       gpu_service->RequestHDRStatus(
520           base::BindOnce(&HDRProxy::GotResultOnIOThread));
521     } else {
522       bool hdr_enabled = false;
523       GotResultOnIOThread(hdr_enabled);
524     }
525   }
GotResultOnIOThread(bool hdr_enabled)526   static void GotResultOnIOThread(bool hdr_enabled) {
527     base::PostTask(FROM_HERE, {BrowserThread::UI},
528                    base::BindOnce(&HDRProxy::GotResult, hdr_enabled));
529   }
GotResult(bool hdr_enabled)530   static void GotResult(bool hdr_enabled) {
531     display::win::ScreenWin::SetHDREnabled(hdr_enabled);
532   }
533 };
534 
535 }  // namespace
536 #endif
537 
538 // The currently-running BrowserMainLoop.  There can be one or zero.
539 BrowserMainLoop* g_current_browser_main_loop = nullptr;
540 
541 #if defined(OS_ANDROID)
542 
543 namespace {
544 // Whether or not BrowserMainLoop::CreateStartupTasks() posts any tasks.
545 bool g_post_startup_tasks = true;
546 }  // namespace
547 
548 // static
EnableStartupTasks(bool enabled)549 void BrowserMainLoop::EnableStartupTasks(bool enabled) {
550   g_post_startup_tasks = enabled;
551 }
552 
553 #endif
554 
555 // BrowserMainLoop construction / destruction =============================
556 
GetInstance()557 BrowserMainLoop* BrowserMainLoop::GetInstance() {
558   DCHECK_CURRENTLY_ON(BrowserThread::UI);
559   return g_current_browser_main_loop;
560 }
561 
562 // static
GetAudioManager()563 media::AudioManager* BrowserMainLoop::GetAudioManager() {
564   return g_current_browser_main_loop->audio_manager();
565 }
566 
BrowserMainLoop(const MainFunctionParams & parameters,std::unique_ptr<base::ThreadPoolInstance::ScopedExecutionFence> scoped_execution_fence)567 BrowserMainLoop::BrowserMainLoop(
568     const MainFunctionParams& parameters,
569     std::unique_ptr<base::ThreadPoolInstance::ScopedExecutionFence>
570         scoped_execution_fence)
571     : parameters_(parameters),
572       parsed_command_line_(parameters.command_line),
573       result_code_(service_manager::RESULT_CODE_NORMAL_EXIT),
574       created_threads_(false),
575       scoped_execution_fence_(std::move(scoped_execution_fence))
576 #if !defined(OS_ANDROID)
577       ,
578       // TODO(fdoray): Create the fence on Android too. Not enabled yet because
579       // tests timeout. https://crbug.com/887407
580       scoped_best_effort_execution_fence_(base::in_place_t())
581 #endif
582 {
583   DCHECK(!g_current_browser_main_loop);
584   DCHECK(scoped_execution_fence_)
585       << "ThreadPool must be halted before kicking off content.";
586   g_current_browser_main_loop = this;
587 
588   if (GetContentClient()->browser()->ShouldCreateThreadPool()) {
589     DCHECK(base::ThreadPoolInstance::Get());
590   }
591 }
592 
~BrowserMainLoop()593 BrowserMainLoop::~BrowserMainLoop() {
594   DCHECK_EQ(this, g_current_browser_main_loop);
595   ui::Clipboard::DestroyClipboardForCurrentThread();
596   g_current_browser_main_loop = nullptr;
597 }
598 
Init()599 void BrowserMainLoop::Init() {
600   TRACE_EVENT0("startup", "BrowserMainLoop::Init");
601 
602   // |startup_data| is optional. If set, the thread owned by the data
603   // will be registered as BrowserThread::IO in CreateThreads() instead of
604   // creating a brand new thread.
605   if (parameters_.startup_data) {
606     StartupDataImpl* startup_data =
607         static_cast<StartupDataImpl*>(parameters_.startup_data);
608     // This is always invoked before |io_thread_| is initialized (i.e. never
609     // resets it).
610     io_thread_ = std::move(startup_data->ipc_thread);
611     mojo_ipc_support_ = std::move(startup_data->mojo_ipc_support);
612     service_manager_shutdown_closure_ =
613         std::move(startup_data->service_manager_shutdown_closure);
614   }
615 
616   parts_ = GetContentClient()->browser()->CreateBrowserMainParts(parameters_);
617 }
618 
619 // BrowserMainLoop stages ==================================================
620 
EarlyInitialization()621 int BrowserMainLoop::EarlyInitialization() {
622   TRACE_EVENT0("startup", "BrowserMainLoop::EarlyInitialization");
623 
624 #if BUILDFLAG(USE_ZYGOTE_HANDLE)
625   // The initialization of the sandbox host ends up with forking the Zygote
626   // process and requires no thread been forked. The initialization has happened
627   // by now since a thread to start the ServiceManager has been created
628   // before the browser main loop starts.
629   DCHECK(SandboxHostLinux::GetInstance()->IsInitialized());
630 #endif
631 
632 #if defined(USE_X11) && !defined(TOOLKIT_QT)
633   if (UsingInProcessGpu()) {
634     if (!gfx::InitializeThreadedX11()) {
635       LOG(ERROR) << "Failed to put Xlib into threaded mode.";
636     }
637   }
638 #endif
639 
640   // GLib's spawning of new processes is buggy, so it's important that at this
641   // point GLib does not need to start DBUS. Chrome should always start with
642   // DBUS_SESSION_BUS_ADDRESS properly set. See crbug.com/309093.
643 #if defined(USE_GLIB)
644   // g_type_init will be deprecated in 2.36. 2.35 is the development
645   // version for 2.36, hence do not call g_type_init starting 2.35.
646   // http://developer.gnome.org/gobject/unstable/gobject-Type-Information.html#g-type-init
647 #if !GLIB_CHECK_VERSION(2, 35, 0)
648   // GLib type system initialization. It's unclear if it's still required for
649   // any remaining code. Most likely this is superfluous as gtk_init() ought
650   // to do this. It's definitely harmless, so it's retained here.
651   g_type_init();
652 #endif  // !GLIB_CHECK_VERSION(2, 35, 0)
653 
654   SetUpGLibLogHandler();
655 #endif  // defined(USE_GLIB)
656 
657   if (parts_) {
658     const int pre_early_init_error_code = parts_->PreEarlyInitialization();
659     if (pre_early_init_error_code != service_manager::RESULT_CODE_NORMAL_EXIT)
660       return pre_early_init_error_code;
661   }
662 
663   // Up the priority of the UI thread unless it was already high (since Mac
664   // and recent versions of Android (O+) do this automatically).
665 #if !defined(OS_MACOSX)
666   if (base::FeatureList::IsEnabled(
667           features::kBrowserUseDisplayThreadPriority) &&
668       base::PlatformThread::GetCurrentThreadPriority() <
669           base::ThreadPriority::DISPLAY) {
670     base::PlatformThread::SetCurrentThreadPriority(
671         base::ThreadPriority::DISPLAY);
672   }
673 #endif  // !defined(OS_MACOSX)
674 
675 #if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) || \
676     defined(OS_ANDROID)
677   // We use quite a few file descriptors for our IPC as well as disk the disk
678   // cache,and the default limit on the Mac is low (256), so bump it up.
679 
680   // Same for Linux. The default various per distro, but it is 1024 on Fedora.
681   // Low soft limits combined with liberal use of file descriptors means power
682   // users can easily hit this limit with many open tabs. Bump up the limit to
683   // an arbitrarily high number. See https://crbug.com/539567
684   base::IncreaseFdLimitTo(8192);
685 #endif  // defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) ||
686         // defined(OS_ANDROID)
687 
688 #if defined(OS_WIN)
689   net::EnsureWinsockInit();
690 #endif
691 
692 #if defined(USE_NSS_CERTS)
693   // We want to be sure to init NSPR on the main thread.
694   crypto::EnsureNSPRInit();
695 #endif
696 
697 #if defined(OS_FUCHSIA)
698   InitDefaultJob();
699 #endif
700 
701 #if defined(OS_WIN)
702   if (!parsed_command_line_.HasSwitch(switches::kSingleProcess)) {
703     if (base::FeatureList::IsEnabled(kBrowserDynamicCodeDisabled)) {
704       sandbox::ApplyProcessMitigationsToCurrentProcess(
705           sandbox::MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT);
706     }
707   }
708 #endif
709 
710   if (parsed_command_line_.HasSwitch(switches::kRendererProcessLimit)) {
711     std::string limit_string = parsed_command_line_.GetSwitchValueASCII(
712         switches::kRendererProcessLimit);
713     size_t process_limit;
714     if (base::StringToSizeT(limit_string, &process_limit)) {
715       RenderProcessHost::SetMaxRendererProcessCount(process_limit);
716     }
717   }
718 
719   if (parts_)
720     parts_->PostEarlyInitialization();
721 
722   return service_manager::RESULT_CODE_NORMAL_EXIT;
723 }
724 
PreMainMessageLoopStart()725 void BrowserMainLoop::PreMainMessageLoopStart() {
726   TRACE_EVENT0("startup",
727                "BrowserMainLoop::MainMessageLoopStart:PreMainMessageLoopStart");
728   if (parts_) {
729     parts_->PreMainMessageLoopStart();
730   }
731 }
732 
MainMessageLoopStart()733 void BrowserMainLoop::MainMessageLoopStart() {
734   // DO NOT add more code here. Use PreMainMessageLoopStart() above or
735   // PostMainMessageLoopStart() below.
736 
737   TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart");
738   DCHECK(base::MessageLoopCurrentForUI::IsSet());
739   InitializeMainThread();
740 }
741 
PostMainMessageLoopStart()742 void BrowserMainLoop::PostMainMessageLoopStart() {
743   {
744     TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SystemMonitor");
745     system_monitor_.reset(new base::SystemMonitor);
746   }
747   {
748     TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor");
749     if (!base::PowerMonitor::IsInitialized()) {
750       base::PowerMonitor::Initialize(
751           std::make_unique<base::PowerMonitorDeviceSource>());
752     }
753   }
754   {
755     TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:HighResTimerManager");
756     hi_res_timer_manager_.reset(new base::HighResolutionTimerManager);
757   }
758   {
759     TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:NetworkChangeNotifier");
760     // On Android if reduced mode started network service this would already be
761     //  created.
762     network_change_notifier_ = net::NetworkChangeNotifier::CreateIfNeeded();
763   }
764   {
765     TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:ScreenlockMonitor");
766     std::unique_ptr<ScreenlockMonitorSource> screenlock_monitor_source =
767         std::make_unique<ScreenlockMonitorDeviceSource>();
768     screenlock_monitor_ = std::make_unique<ScreenlockMonitor>(
769         std::move(screenlock_monitor_source));
770   }
771   {
772     TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MediaFeatures");
773     media::InitializeMediaLibrary();
774   }
775   {
776     TRACE_EVENT0("startup",
777                  "BrowserMainLoop::Subsystem:ContentWebUIController");
778     WebUIControllerFactory::RegisterFactory(
779         ContentWebUIControllerFactory::GetInstance());
780   }
781 
782   {
783     TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:OnlineStateObserver");
784     online_state_observer_.reset(new BrowserOnlineStateObserver);
785   }
786 
787   {
788     base::SetRecordActionTaskRunner(
789         base::CreateSingleThreadTaskRunner({BrowserThread::UI}));
790   }
791 
792   // TODO(boliu): kSingleProcess check is a temporary workaround for
793   // in-process Android WebView. crbug.com/503724 tracks proper fix.
794   if (!parsed_command_line_.HasSwitch(switches::kSingleProcess)) {
795     base::DiscardableMemoryAllocator::SetInstance(
796         discardable_memory::DiscardableSharedMemoryManager::Get());
797   }
798 
799   if (parts_)
800     parts_->PostMainMessageLoopStart();
801 
802 #if defined(OS_ANDROID)
803   {
804     TRACE_EVENT0("startup",
805                  "BrowserMainLoop::Subsystem:ScopedSurfaceRequestManager");
806     if (UsingInProcessGpu()) {
807       gpu::ScopedSurfaceRequestConduit::SetInstance(
808           ScopedSurfaceRequestManager::GetInstance());
809     }
810   }
811 
812   if (!parsed_command_line_.HasSwitch(
813           switches::kDisableScreenOrientationLock)) {
814     TRACE_EVENT0("startup",
815                  "BrowserMainLoop::Subsystem:ScreenOrientationProvider");
816     screen_orientation_delegate_.reset(new ScreenOrientationDelegateAndroid());
817   }
818 
819   base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(
820       base::trace_event::CPUFreqMonitor::GetInstance());
821 #endif
822 
823   // Enable memory-infra dump providers.
824   InitSkiaEventTracer();
825   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
826       skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
827   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
828       sql::SqlMemoryDumpProvider::GetInstance(), "Sql", nullptr);
829 #if defined(OS_CHROMEOS)
830   device::BluetoothAdapterFactory::SetBleScanParserCallback(
831       base::BindRepeating(&GetBleScanParser));
832 #else
833   // Chrome Remote Desktop needs TransitionalURLLoaderFactoryOwner on ChromeOS.
834   network::TransitionalURLLoaderFactoryOwner::DisallowUsageInProcess();
835 #endif
836 }
837 
PreCreateThreads()838 int BrowserMainLoop::PreCreateThreads() {
839   // Make sure no accidental call to initialize GpuDataManager earlier.
840   DCHECK(!GpuDataManagerImpl::Initialized());
841   if (parts_) {
842     TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PreCreateThreads");
843 
844     result_code_ = parts_->PreCreateThreads();
845   }
846 
847   InitializeMemoryManagementComponent();
848 
849 #if BUILDFLAG(ENABLE_PLUGINS)
850   // Prior to any processing happening on the IO thread, we create the
851   // plugin service as it is predominantly used from the IO thread,
852   // but must be created on the main thread. The service ctor is
853   // inexpensive and does not invoke the io_thread() accessor.
854   {
855     TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService");
856     PluginService::GetInstance()->Init();
857   }
858 #endif
859 
860 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
861   // Prior to any processing happening on the IO thread, we create the
862   // CDM service as it is predominantly used from the IO thread. This must
863   // be called on the main thread since it involves file path checks.
864   CdmRegistry::GetInstance()->Init();
865 #endif
866 
867 #if defined(OS_MACOSX)
868   // The WindowResizeHelper allows the UI thread to wait on specific renderer
869   // and GPU messages from the IO thread. Initializing it before the IO thread
870   // starts ensures the affected IO thread messages always have somewhere to go.
871   ui::WindowResizeHelperMac::Get()->Init(base::ThreadTaskRunnerHandle::Get());
872 #endif
873 
874   // GpuDataManager should be initialized in parts_->PreCreateThreads through
875   // ChromeBrowserMainExtraPartsGpu. However, if |parts_| is not set,
876   // initialize it here.
877   // Need to initialize in-process GpuDataManager before creating threads.
878   // It's unsafe to append the gpu command line switches to the global
879   // CommandLine::ForCurrentProcess object after threads are created.
880   GpuDataManagerImpl::GetInstance();
881   DCHECK(GpuDataManagerImpl::Initialized());
882 
883 #if defined(USE_X11)
884   gpu_data_manager_visual_proxy_.reset(new internal::GpuDataManagerVisualProxy(
885       GpuDataManagerImpl::GetInstance()));
886 #endif
887 
888 #if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || defined(OS_ANDROID)
889   // Single-process is an unsupported and not fully tested mode, so
890   // don't enable it for official Chrome builds (except on Android).
891   if (parsed_command_line_.HasSwitch(switches::kSingleProcess))
892     RenderProcessHost::SetRunRendererInProcess(true);
893 #endif
894 
895   // Initialize origins that require process isolation.  Must be done
896   // after base::FeatureList is initialized, but before any navigations can
897   // happen.
898   SiteIsolationPolicy::ApplyGlobalIsolatedOrigins();
899 
900   return result_code_;
901 }
902 
PreShutdown()903 void BrowserMainLoop::PreShutdown() {
904   ui::Clipboard::OnPreShutdownForCurrentThread();
905 }
906 
CreateStartupTasks()907 void BrowserMainLoop::CreateStartupTasks() {
908   TRACE_EVENT0("startup", "BrowserMainLoop::CreateStartupTasks");
909 
910   DCHECK(!startup_task_runner_);
911 #if defined(OS_ANDROID)
912   // Some java scheduler tests need to test migration to C++, but the browser
913   // environment isn't set up fully and if these tasks run they may crash.
914   if (!g_post_startup_tasks)
915     return;
916 
917   startup_task_runner_ = std::make_unique<StartupTaskRunner>(
918       base::BindOnce(&BrowserStartupComplete),
919       base::CreateSingleThreadTaskRunner(
920           {BrowserThread::UI, BrowserTaskType::kBootstrap}));
921 #else
922   startup_task_runner_ = std::make_unique<StartupTaskRunner>(
923       base::OnceCallback<void(int)>(), base::ThreadTaskRunnerHandle::Get());
924 #endif
925   StartupTask pre_create_threads = base::BindOnce(
926       &BrowserMainLoop::PreCreateThreads, base::Unretained(this));
927   startup_task_runner_->AddTask(std::move(pre_create_threads));
928 
929   StartupTask create_threads =
930       base::BindOnce(&BrowserMainLoop::CreateThreads, base::Unretained(this));
931   startup_task_runner_->AddTask(std::move(create_threads));
932 
933   StartupTask post_create_threads = base::BindOnce(
934       &BrowserMainLoop::PostCreateThreads, base::Unretained(this));
935   startup_task_runner_->AddTask(std::move(post_create_threads));
936 
937   StartupTask browser_thread_started = base::BindOnce(
938       &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this));
939   startup_task_runner_->AddTask(std::move(browser_thread_started));
940 
941   StartupTask pre_main_message_loop_run = base::BindOnce(
942       &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this));
943   startup_task_runner_->AddTask(std::move(pre_main_message_loop_run));
944 
945 #if defined(OS_ANDROID)
946   startup_task_runner_->StartRunningTasksAsync();
947 #else
948   startup_task_runner_->RunAllTasksNow();
949 #endif
950 }
951 
952 scoped_refptr<base::SingleThreadTaskRunner>
GetResizeTaskRunner()953 BrowserMainLoop::GetResizeTaskRunner() {
954 #if defined(OS_MACOSX)
955   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
956       ui::WindowResizeHelperMac::Get()->task_runner();
957   // In tests, WindowResizeHelperMac task runner might not be initialized.
958   return task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get();
959 #else
960   return base::ThreadTaskRunnerHandle::Get();
961 #endif
962 }
963 
964 gpu::GpuChannelEstablishFactory*
gpu_channel_establish_factory() const965 BrowserMainLoop::gpu_channel_establish_factory() const {
966   return BrowserGpuChannelHostFactory::instance();
967 }
968 
969 #if defined(OS_ANDROID)
SynchronouslyFlushStartupTasks()970 void BrowserMainLoop::SynchronouslyFlushStartupTasks() {
971   startup_task_runner_->RunAllTasksNow();
972 }
973 #endif  // OS_ANDROID
974 
CreateThreads()975 int BrowserMainLoop::CreateThreads() {
976   TRACE_EVENT0("startup,rail", "BrowserMainLoop::CreateThreads");
977 
978   // Release the ThreadPool's threads.
979   scoped_execution_fence_.reset();
980 
981   // The |io_thread| can have optionally been injected into Init(), but if not,
982   // create it here. Thre thread is only tagged as BrowserThread::IO here in
983   // order to prevent any code from statically posting to it before
984   // CreateThreads() (as such maintaining the invariant that PreCreateThreads()
985   // et al. "happen-before" BrowserThread::IO is "brought up").
986   if (!io_thread_) {
987     io_thread_ = BrowserTaskExecutor::CreateIOThread();
988   }
989   io_thread_->RegisterAsBrowserThread();
990   BrowserTaskExecutor::InitializeIOThread();
991 
992   // TODO(https://crbug.com/863341): Replace with a better API
993   GetContentClient()->browser()->PostAfterStartupTask(
994       FROM_HERE, base::SequencedTaskRunnerHandle::Get(),
995       base::BindOnce(
996           [](BrowserMainLoop* browser_main_loop) {
997             // Enable main thread and thread pool best effort queues. Non-best
998             // effort queues will already have been enabled. This will enable
999             // all queues on all browser threads, so we need to do this after
1000             // the threads have been created, i.e. here.
1001             content::BrowserTaskExecutor::EnableAllQueues();
1002             browser_main_loop->scoped_best_effort_execution_fence_.reset();
1003           },
1004           // Main thread tasks can't run after BrowserMainLoop destruction.
1005           // Accessing an Unretained pointer to BrowserMainLoop from a main
1006           // thread task is therefore safe.
1007           base::Unretained(this)));
1008 
1009   created_threads_ = true;
1010   return result_code_;
1011 }
1012 
PostCreateThreads()1013 int BrowserMainLoop::PostCreateThreads() {
1014   tracing_controller_ = std::make_unique<content::TracingControllerImpl>();
1015   content::BackgroundTracingManagerImpl::GetInstance()
1016       ->AddMetadataGeneratorFunction();
1017 
1018   if (parts_) {
1019     TRACE_EVENT0("startup", "BrowserMainLoop::PostCreateThreads");
1020     parts_->PostCreateThreads();
1021   }
1022 
1023   return result_code_;
1024 }
1025 
PreMainMessageLoopRun()1026 int BrowserMainLoop::PreMainMessageLoopRun() {
1027 #if defined(OS_ANDROID)
1028   bool use_display_wide_color_gamut =
1029       GetContentClient()->browser()->GetWideColorGamutHeuristic() ==
1030       ContentBrowserClient::WideColorGamutHeuristic::kUseDisplay;
1031   // Let screen instance be overridable by parts.
1032   ui::SetScreenAndroid(use_display_wide_color_gamut);
1033 #endif
1034 
1035   if (parts_) {
1036     TRACE_EVENT0("startup",
1037                  "BrowserMainLoop::CreateThreads:PreMainMessageLoopRun");
1038 
1039     parts_->PreMainMessageLoopRun();
1040   }
1041 
1042 #if defined(OS_WIN)
1043   // ShellBrowserMainParts initializes a ShellBrowserContext with a profile
1044   // directory only in PreMainMessageLoopRun(). DWriteFontLookupTableBuilder
1045   // needs to access this directory, hence triggering after this stage has run.
1046   if (base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)) {
1047     content::DWriteFontLookupTableBuilder::GetInstance()
1048         ->SchedulePrepareFontUniqueNameTableIfNeeded();
1049   }
1050 #endif
1051 
1052   // If the UI thread blocks, the whole UI is unresponsive. Do not allow
1053   // unresponsive tasks from the UI thread and instantiate a
1054   // responsiveness::Watcher to catch jank induced by any blocking tasks not
1055   // instrumented with ScopedBlockingCall's assert.
1056   base::DisallowUnresponsiveTasks();
1057 #if !defined(TOOLKIT_QT)
1058   responsiveness_watcher_ = new responsiveness::Watcher;
1059   responsiveness_watcher_->SetUp();
1060 #endif
1061   return result_code_;
1062 }
1063 
RunMainMessageLoopParts()1064 void BrowserMainLoop::RunMainMessageLoopParts() {
1065   // Don't use the TRACE_EVENT0 macro because the tracing infrastructure doesn't
1066   // expect synchronous events around the main loop of a thread.
1067   TRACE_EVENT_ASYNC_BEGIN0("toplevel", "BrowserMain:MESSAGE_LOOP", this);
1068 
1069   bool ran_main_loop = false;
1070   if (parts_)
1071     ran_main_loop = parts_->MainMessageLoopRun(&result_code_);
1072 
1073   if (!ran_main_loop)
1074     MainMessageLoopRun();
1075 
1076   TRACE_EVENT_ASYNC_END0("toplevel", "BrowserMain:MESSAGE_LOOP", this);
1077 }
1078 
ShutdownThreadsAndCleanUp()1079 void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
1080   if (!created_threads_) {
1081     // Called early, nothing to do
1082     return;
1083   }
1084   TRACE_EVENT0("shutdown", "BrowserMainLoop::ShutdownThreadsAndCleanUp");
1085 
1086   // Teardown may start in PostMainMessageLoopRun, and during teardown we
1087   // need to be able to perform IO.
1088   base::ThreadRestrictions::SetIOAllowed(true);
1089   base::PostTask(
1090       FROM_HERE, {BrowserThread::IO},
1091       base::BindOnce(
1092           base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), true));
1093 
1094   // Also allow waiting to join threads.
1095   // TODO(https://crbug.com/800808): Ideally this (and the above SetIOAllowed()
1096   // would be scoped allowances). That would be one of the first step to ensure
1097   // no persistent work is being done after ThreadPoolInstance::Shutdown() in
1098   // order to move towards atomic shutdown.
1099   base::ThreadRestrictions::SetWaitAllowed(true);
1100   base::PostTask(
1101       FROM_HERE, {BrowserThread::IO},
1102       base::BindOnce(
1103           base::IgnoreResult(&base::ThreadRestrictions::SetWaitAllowed), true));
1104 
1105   if (RenderProcessHost::run_renderer_in_process())
1106     RenderProcessHostImpl::ShutDownInProcessRenderer();
1107 
1108   if (parts_) {
1109     TRACE_EVENT0("shutdown",
1110                  "BrowserMainLoop::Subsystem:PostMainMessageLoopRun");
1111     parts_->PostMainMessageLoopRun();
1112   }
1113 
1114   // Request shutdown to clean up allocated resources on the IO thread.
1115   if (midi_service_) {
1116     TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:MidiService");
1117     midi_service_->Shutdown();
1118   }
1119 
1120 #if BUILDFLAG(ENABLE_WEB_SPEECH)
1121   TRACE_EVENT0("shutdown",
1122                "BrowserMainLoop::Subsystem:SpeechRecognitionManager");
1123   io_thread_->task_runner()->DeleteSoon(FROM_HERE,
1124                                         speech_recognition_manager_.release());
1125 #endif
1126 
1127   memory_pressure_monitor_.reset();
1128 
1129   ShutDownNetworkService();
1130 
1131 #if defined(OS_MACOSX)
1132   BrowserCompositorMac::DisableRecyclingForShutdown();
1133 #endif
1134 
1135 #if defined(USE_AURA) || defined(OS_MACOSX)
1136   {
1137     TRACE_EVENT0("shutdown",
1138                  "BrowserMainLoop::Subsystem:ImageTransportFactory");
1139     ImageTransportFactory::Terminate();
1140   }
1141 #endif
1142 
1143 #if !defined(OS_ANDROID)
1144   host_frame_sink_manager_.reset();
1145   compositing_mode_reporter_impl_.reset();
1146 #endif
1147 
1148 // The device monitors are using |system_monitor_| as dependency, so delete
1149 // them before |system_monitor_| goes away.
1150 // On Mac and windows, the monitor needs to be destroyed on the same thread
1151 // as they were created. On Linux, the monitor will be deleted when IO thread
1152 // goes away.
1153 #if defined(OS_WIN)
1154   system_message_window_.reset();
1155 #elif defined(OS_MACOSX)
1156   device_monitor_mac_.reset();
1157 #endif
1158 
1159   if (BrowserGpuChannelHostFactory::instance())
1160     BrowserGpuChannelHostFactory::instance()->CloseChannel();
1161 
1162   // Shutdown the Service Manager and IPC.
1163   if (service_manager_shutdown_closure_)
1164     std::move(service_manager_shutdown_closure_).Run();
1165   mojo_ipc_support_.reset();
1166 
1167   if (save_file_manager_)
1168     save_file_manager_->Shutdown();
1169 
1170   {
1171     TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:IOThread");
1172     ResetThread_IO(std::move(io_thread_));
1173   }
1174 
1175   {
1176     TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:ThreadPool");
1177     base::ThreadPoolInstance::Get()->Shutdown();
1178   }
1179 
1180   // Must happen after the IO thread is shutdown since this may be accessed from
1181   // it.
1182   {
1183     TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:GPUChannelFactory");
1184     if (BrowserGpuChannelHostFactory::instance()) {
1185       BrowserGpuChannelHostFactory::Terminate();
1186     }
1187   }
1188 
1189   // Must happen after the I/O thread is shutdown since this class lives on the
1190   // I/O thread and isn't threadsafe.
1191   {
1192     TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:GamepadService");
1193     device::GamepadService::GetInstance()->Terminate();
1194   }
1195   {
1196     TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:DeleteDataSources");
1197     URLDataManager::DeleteDataSources();
1198   }
1199   {
1200     TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:AudioMan");
1201     if (audio_manager_ && !audio_manager_->Shutdown()) {
1202       // Intentionally leak AudioManager if shutdown failed.
1203       // We might run into various CHECK(s) in AudioManager destructor.
1204       ignore_result(audio_manager_.release());
1205       // |user_input_monitor_| may be in use by stray streams in case
1206       // AudioManager shutdown failed.
1207       ignore_result(user_input_monitor_.release());
1208     }
1209 
1210     // Leaking AudioSystem: we cannot correctly destroy it since Audio service
1211     // connection in there is bound to IO thread.
1212     ignore_result(audio_system_.release());
1213   }
1214 
1215   if (parts_) {
1216     TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:PostDestroyThreads");
1217     parts_->PostDestroyThreads();
1218   }
1219 }
1220 
audio_manager() const1221 media::AudioManager* BrowserMainLoop::audio_manager() const {
1222   DCHECK(audio_manager_) << "AudioManager is not instantiated - running the "
1223                             "audio service out of process?";
1224   return audio_manager_.get();
1225 }
1226 
GetCompositingModeReporter(mojo::PendingReceiver<viz::mojom::CompositingModeReporter> receiver)1227 void BrowserMainLoop::GetCompositingModeReporter(
1228     mojo::PendingReceiver<viz::mojom::CompositingModeReporter> receiver) {
1229 #if defined(OS_ANDROID)
1230   // Android doesn't support non-gpu compositing modes, and doesn't make a
1231   // CompositingModeReporter.
1232   return;
1233 #else
1234   compositing_mode_reporter_impl_->BindReceiver(std::move(receiver));
1235 #endif
1236 }
1237 
InitializeMainThread()1238 void BrowserMainLoop::InitializeMainThread() {
1239   TRACE_EVENT0("startup", "BrowserMainLoop::InitializeMainThread");
1240   base::PlatformThread::SetName("CrBrowserMain");
1241 
1242   // Register the main thread. The main thread's task runner should already have
1243   // been initialized in MainMessageLoopStart() (or before if
1244   // MessageLoopCurrent::Get() was externally provided).
1245   DCHECK(base::ThreadTaskRunnerHandle::IsSet());
1246   main_thread_.reset(new BrowserThreadImpl(
1247       BrowserThread::UI, base::ThreadTaskRunnerHandle::Get()));
1248 }
1249 
BrowserThreadsStarted()1250 int BrowserMainLoop::BrowserThreadsStarted() {
1251   TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted");
1252 
1253   // Bring up Mojo IPC and the embedded Service Manager as early as possible.
1254   // Initializaing mojo requires the IO thread to have been initialized first,
1255   // so this cannot happen any earlier than now.
1256   InitializeMojo();
1257 
1258   data_decoder_service_provider_ = std::make_unique<OopDataDecoder>();
1259 
1260   HistogramSynchronizer::GetInstance();
1261 
1262 #ifndef TOOLKIT_QT
1263   field_trial_synchronizer_ = base::MakeRefCounted<FieldTrialSynchronizer>();
1264 #endif
1265 
1266   // cc assumes a single client name for metrics in a process, which is
1267   // is inconsistent with single process mode where both the renderer and
1268   // browser compositor run in the same process. In this case, avoid
1269   // initializing with a browser metric name to ensure we record metrics for the
1270   // renderer compositor.
1271   // Note that since single process mode is only used by webview in practice,
1272   // which doesn't have a browser compositor, this is not required anyway.
1273   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
1274           switches::kSingleProcess)) {
1275     cc::SetClientNameForMetrics("Browser");
1276   }
1277 
1278   // Initialize the GPU shader cache. This needs to be initialized before
1279   // BrowserGpuChannelHostFactory below, since that depends on an initialized
1280   // ShaderCacheFactory.
1281   InitShaderCacheFactorySingleton(
1282       base::CreateSingleThreadTaskRunner({BrowserThread::IO}));
1283 
1284   // Initialize the FontRenderParams on IO thread. This needs to be initialized
1285   // before gpu process initialization below.
1286   base::PostTask(FROM_HERE, {BrowserThread::IO},
1287                  base::BindOnce(&viz::GpuHostImpl::InitFontRenderParams,
1288                                 gfx::GetFontRenderParams(
1289                                     gfx::FontRenderParamsQuery(), nullptr)));
1290 
1291   bool always_uses_gpu = true;
1292   bool established_gpu_channel = false;
1293 #if defined(OS_ANDROID)
1294   // TODO(crbug.com/439322): This should be set to |true|.
1295   established_gpu_channel = false;
1296   always_uses_gpu = ShouldStartGpuProcessOnBrowserStartup();
1297   BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
1298 #else
1299   established_gpu_channel = true;
1300   if (parsed_command_line_.HasSwitch(switches::kDisableGpu) ||
1301       parsed_command_line_.HasSwitch(switches::kDisableGpuCompositing) ||
1302       parsed_command_line_.HasSwitch(switches::kDisableGpuEarlyInit)) {
1303     established_gpu_channel = always_uses_gpu = false;
1304   }
1305 
1306   host_frame_sink_manager_ = std::make_unique<viz::HostFrameSinkManager>();
1307   BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
1308   compositing_mode_reporter_impl_ =
1309       std::make_unique<viz::CompositingModeReporterImpl>();
1310 
1311   auto transport_factory = std::make_unique<VizProcessTransportFactory>(
1312       BrowserGpuChannelHostFactory::instance(), GetResizeTaskRunner(),
1313       compositing_mode_reporter_impl_.get());
1314   transport_factory->ConnectHostFrameSinkManager();
1315   ImageTransportFactory::SetFactory(std::move(transport_factory));
1316 
1317 #if defined(USE_AURA)
1318   env_->set_context_factory(GetContextFactory());
1319 #endif  // defined(USE_AURA)
1320 #endif  // !defined(OS_ANDROID)
1321 
1322 #if defined(OS_ANDROID)
1323   base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
1324       tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
1325       nullptr);
1326 #endif
1327 
1328   {
1329     TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:AudioMan");
1330     InitializeAudio();
1331   }
1332 
1333   {
1334     TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:MidiService");
1335     midi_service_.reset(new midi::MidiService);
1336   }
1337 
1338   {
1339     TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:Devices");
1340     device::GamepadService::GetInstance()->StartUp(
1341         base::BindRepeating(&BindHidManager));
1342 #if BUILDFLAG(ENABLE_WEB_AUTH)
1343     device::FidoHidDiscovery::SetHidManagerBinder(
1344         base::BindRepeating(&BindHidManager));
1345 #endif
1346   }
1347 
1348 #if defined(OS_WIN)
1349   HDRProxy::Initialize();
1350   system_message_window_.reset(new media::SystemMessageWindowWin);
1351 #elif defined(OS_LINUX) && defined(USE_UDEV)
1352   device_monitor_linux_ = std::make_unique<media::DeviceMonitorLinux>();
1353 #elif defined(OS_MACOSX)
1354   // On Mac, the audio task runner must belong to the main thread.
1355   // See audio_thread_impl.cc and https://crbug.com/158170.
1356   DCHECK(!audio_manager_ ||
1357          audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
1358   device_monitor_mac_.reset(
1359       new media::DeviceMonitorMac(base::ThreadTaskRunnerHandle::Get()));
1360 #endif
1361 
1362 #if BUILDFLAG(ENABLE_WEBRTC)
1363   // Instantiated once using CreateSingletonInstance(), and accessed only using
1364   // GetInstance(), which is not allowed to create the object. This allows us
1365   // to ensure that it cannot be used before objects it relies on have been
1366   // created; namely, WebRtcEventLogManager.
1367   // Allowed to leak when the browser exits.
1368   WebRTCInternals::CreateSingletonInstance();
1369 #endif
1370 
1371   // MediaStreamManager needs the IO thread to be created.
1372   {
1373     TRACE_EVENT0(
1374         "startup",
1375         "BrowserMainLoop::BrowserThreadsStarted:InitMediaStreamManager");
1376 
1377     scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner =
1378         audio_manager_ ? audio_manager_->GetTaskRunner() : nullptr;
1379 
1380 #if defined(OS_MACOSX)
1381     // On Mac, the audio task runner must belong to the main thread.
1382     // See audio_thread_impl.cc and https://crbug.com/158170.
1383     if (audio_task_runner) {
1384       DCHECK(audio_task_runner->BelongsToCurrentThread());
1385     } else {
1386       audio_task_runner = base::ThreadTaskRunnerHandle::Get();
1387     }
1388 #endif
1389 
1390     media_stream_manager_ = std::make_unique<MediaStreamManager>(
1391         audio_system_.get(), std::move(audio_task_runner));
1392   }
1393 #if BUILDFLAG(ENABLE_WEB_SPEECH)
1394   {
1395     TRACE_EVENT0(
1396         "startup",
1397         "BrowserMainLoop::BrowserThreadsStarted:InitSpeechRecognition");
1398     speech_recognition_manager_.reset(new SpeechRecognitionManagerImpl(
1399         audio_system_.get(), media_stream_manager_.get()));
1400   }
1401 #endif
1402 
1403   {
1404     TRACE_EVENT0(
1405         "startup",
1406         "BrowserMainLoop::BrowserThreadsStarted::InitUserInputMonitor");
1407     user_input_monitor_ = media::UserInputMonitor::Create(
1408         io_thread_->task_runner(), base::ThreadTaskRunnerHandle::Get());
1409   }
1410 
1411   {
1412     TRACE_EVENT0("startup",
1413                  "BrowserMainLoop::BrowserThreadsStarted::SaveFileManager");
1414     save_file_manager_ = new SaveFileManager();
1415   }
1416 
1417   // Alert the clipboard class to which threads are allowed to access the
1418   // clipboard:
1419   std::vector<base::PlatformThreadId> allowed_clipboard_threads;
1420   // The current thread is the UI thread.
1421   allowed_clipboard_threads.push_back(base::PlatformThread::CurrentId());
1422 #if defined(OS_WIN)
1423   // On Windows, clipboard is also used on the IO thread.
1424   allowed_clipboard_threads.push_back(io_thread_->GetThreadId());
1425 #endif
1426   ui::Clipboard::SetAllowedThreads(allowed_clipboard_threads);
1427 
1428   if (GpuDataManagerImpl::GetInstance()->GpuProcessStartAllowed() &&
1429       !established_gpu_channel && always_uses_gpu) {
1430     TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
1431                          TRACE_EVENT_SCOPE_THREAD);
1432     base::PostTask(
1433         FROM_HERE, {BrowserThread::IO},
1434         base::BindOnce(base::IgnoreResult(&GpuProcessHost::Get),
1435                        GPU_PROCESS_KIND_SANDBOXED, true /* force_create */));
1436   }
1437 
1438 #if defined(OS_WIN)
1439   GpuDataManagerImpl::GetInstance()->OnBrowserThreadsStarted();
1440 #endif
1441 
1442   if (MediaKeysListenerManager::IsMediaKeysListenerManagerEnabled()) {
1443     media_keys_listener_manager_ =
1444         std::make_unique<MediaKeysListenerManagerImpl>();
1445   }
1446 
1447 #if defined(OS_MACOSX)
1448   ThemeHelperMac::GetInstance();
1449 #endif  // defined(OS_MACOSX)
1450 
1451 #if defined(OS_ANDROID)
1452   media::SetMediaDrmBridgeClient(GetContentClient()->GetMediaDrmBridgeClient());
1453   if (base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)) {
1454     FontUniqueNameLookup::GetInstance();
1455   }
1456 #endif
1457 
1458 #if defined(ENABLE_IPC_FUZZER)
1459   SetFileUrlPathAliasForIpcFuzzer();
1460 #endif
1461   return result_code_;
1462 }
1463 
UsingInProcessGpu() const1464 bool BrowserMainLoop::UsingInProcessGpu() const {
1465   return parsed_command_line_.HasSwitch(switches::kSingleProcess) ||
1466          parsed_command_line_.HasSwitch(switches::kInProcessGPU);
1467 }
1468 
InitializeMemoryManagementComponent()1469 void BrowserMainLoop::InitializeMemoryManagementComponent() {
1470   memory_pressure_monitor_ = CreateMemoryPressureMonitor(parsed_command_line_);
1471 }
1472 
InitializeToolkit()1473 bool BrowserMainLoop::InitializeToolkit() {
1474   TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit");
1475 
1476   // TODO(evan): this function is rather subtle, due to the variety
1477   // of intersecting ifdefs we have.  To keep it easy to follow, there
1478   // are no #else branches on any #ifs.
1479   // TODO(stevenjb): Move platform specific code into platform specific Parts
1480   // (Need to add InitializeToolkit stage to BrowserParts).
1481   // See also GTK setup in EarlyInitialization, above, and associated comments.
1482 
1483 #if defined(OS_WIN)
1484   INITCOMMONCONTROLSEX config;
1485   config.dwSize = sizeof(config);
1486   config.dwICC = ICC_WIN95_CLASSES;
1487   if (!InitCommonControlsEx(&config))
1488     PLOG(FATAL);
1489 #endif
1490 
1491 #if defined(USE_AURA)
1492 
1493 #if defined(USE_X11) && !defined(TOOLKIT_QT)
1494   if (!parsed_command_line_.HasSwitch(switches::kHeadless) &&
1495       !gfx::GetXDisplay()) {
1496     LOG(ERROR) << "Unable to open X display.";
1497     return false;
1498   }
1499 #endif
1500 
1501   // Env creates the compositor. Aura widgets need the compositor to be created
1502   // before they can be initialized by the browser.
1503   env_ = aura::Env::CreateInstance();
1504 #endif  // defined(USE_AURA)
1505 
1506   if (parts_)
1507     parts_->ToolkitInitialized();
1508 
1509   return true;
1510 }
1511 
MainMessageLoopRun()1512 void BrowserMainLoop::MainMessageLoopRun() {
1513 #if defined(OS_ANDROID)
1514   // Android's main message loop is the Java message loop.
1515   NOTREACHED();
1516 #else
1517   base::RunLoop run_loop;
1518   parts_->PreDefaultMainMessageLoopRun(run_loop.QuitClosure());
1519   run_loop.Run();
1520 #endif
1521 }
1522 
InitializeMojo()1523 void BrowserMainLoop::InitializeMojo() {
1524   if (!parsed_command_line_.HasSwitch(switches::kSingleProcess)) {
1525     // Disallow mojo sync calls in the browser process. Note that we allow sync
1526     // calls in single-process mode since renderer IPCs are made from a browser
1527     // thread.
1528     mojo::SyncCallRestrictions::DisallowSyncCall();
1529   }
1530 
1531   // Ensure that any NavigableContentsViews constructed in the browser process
1532   // know they're running in the same process as the service.
1533   content::NavigableContentsView::SetClientRunningInServiceProcess();
1534 
1535   // Start startup tracing through TracingController's interface. TraceLog has
1536   // been enabled in content_main_runner where threads are not available. Now We
1537   // need to start tracing for all other tracing agents, which require threads.
1538   // We can only do this after starting the main message loop to avoid calling
1539   // MessagePumpForUI::ScheduleWork() before MessagePumpForUI::Start().
1540   TracingControllerImpl::GetInstance()->StartStartupTracingIfNeeded();
1541 
1542 #if BUILDFLAG(MOJO_RANDOM_DELAYS_ENABLED)
1543   mojo::BeginRandomMojoDelays();
1544 #endif
1545 }
1546 
InitializeAudio()1547 void BrowserMainLoop::InitializeAudio() {
1548   DCHECK(!audio_manager_);
1549 
1550   audio_manager_ = GetContentClient()->browser()->CreateAudioManager(
1551       MediaInternals::GetInstance());
1552   DCHECK_EQ(!!audio_manager_,
1553             GetContentClient()->browser()->OverridesAudioManager());
1554 
1555   // Do not initialize |audio_manager_| if running out of process.
1556   if (!audio_manager_ &&
1557       (base::CommandLine::ForCurrentProcess()->HasSwitch(
1558            switches::kSingleProcess) ||
1559        !base::FeatureList::IsEnabled(features::kAudioServiceOutOfProcess))) {
1560     audio_manager_ =
1561         media::AudioManager::Create(std::make_unique<media::AudioThreadImpl>(),
1562                                     MediaInternals::GetInstance());
1563     CHECK(audio_manager_);
1564   }
1565 
1566   // Iff |audio_manager_| is instantiated, the audio service will run
1567   // in-process. Complete the setup for that:
1568   if (audio_manager_) {
1569     AudioMirroringManager* const mirroring_manager =
1570         AudioMirroringManager::GetInstance();
1571     audio_manager_->SetDiverterCallbacks(
1572         mirroring_manager->GetAddDiverterCallback(),
1573         mirroring_manager->GetRemoveDiverterCallback());
1574 
1575     TRACE_EVENT_INSTANT0("startup", "Starting Audio service task runner",
1576                          TRACE_EVENT_SCOPE_THREAD);
1577     audio::Service::GetInProcessTaskRunner()->StartWithTaskRunner(
1578         audio_manager_->GetTaskRunner());
1579   }
1580 
1581   if (base::FeatureList::IsEnabled(features::kAudioServiceLaunchOnStartup)) {
1582     // Schedule the audio service startup on the main thread.
1583     base::PostTask(
1584         FROM_HERE,
1585         {content::BrowserThread::UI, base::TaskPriority::BEST_EFFORT},
1586         base::BindOnce([]() {
1587           TRACE_EVENT0("audio", "Starting audio service");
1588           GetAudioService();
1589         }));
1590   }
1591 
1592   audio_system_ = CreateAudioSystemForAudioService();
1593   CHECK(audio_system_);
1594 }
1595 
AudioServiceOutOfProcess() const1596 bool BrowserMainLoop::AudioServiceOutOfProcess() const {
1597   // Returns true iff kAudioServiceOutOfProcess feature is enabled and if the
1598   // embedder does not provide its own in-process AudioManager.
1599   return base::FeatureList::IsEnabled(features::kAudioServiceOutOfProcess) &&
1600          !GetContentClient()->browser()->OverridesAudioManager();
1601 }
1602 
1603 }  // namespace content
1604