blob: 4fb375a15fb593f4a259efdfaaca4f2427e3fc71 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2012 The Chromium Authors
[email protected]f573ed6b2012-02-10 15:58:522// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Xi Han6740d622018-05-22 19:21:075#include "content/browser/browser_main_runner_impl.h"
[email protected]f573ed6b2012-02-10 15:58:526
Peter Boströmdd7e40ec2021-04-05 20:40:107#include <memory>
8
Kalvin Lee8529bdde2024-10-25 14:10:429#include "base/allocator/partition_alloc_support.h"
[email protected]f573ed6b2012-02-10 15:58:5210#include "base/base_switches.h"
Hans Wennborg0917de892020-04-28 20:21:1511#include "base/check.h"
[email protected]f573ed6b2012-02-10 15:58:5212#include "base/command_line.h"
anantaf2651872016-06-16 22:21:0213#include "base/debug/debugger.h"
[email protected]1cefd4b2013-11-20 21:55:4014#include "base/debug/leak_annotations.h"
asvitkine8d51e9d2016-09-02 23:55:4315#include "base/metrics/histogram_macros.h"
Lei Zhang81f85692022-10-06 21:03:2216#include "base/no_destructor.h"
gab7af9dc02017-05-05 13:38:5417#include "base/run_loop.h"
Gabriel Charette8eb4dff2018-03-27 14:22:5418#include "base/synchronization/atomic_flag.h"
robliao7fac1d82015-09-23 23:07:4019#include "base/time/time.h"
ssidb3fabc662016-04-01 04:39:2520#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
ssid3e765612015-01-28 04:03:4221#include "base/trace_event/trace_event.h"
avib7348942015-12-25 20:57:1022#include "build/build_config.h"
primianoccb26c62016-06-01 21:50:0223#include "components/tracing/common/tracing_switches.h"
[email protected]f573ed6b2012-02-10 15:58:5224#include "content/browser/browser_main_loop.h"
Alexander Timinfc9756782020-12-23 22:05:5225#include "content/browser/tracing/startup_tracing_controller.h"
John Abd-El-Malek884291c2017-08-09 06:43:4826#include "content/common/content_switches_internal.h"
[email protected]f573ed6b2012-02-10 15:58:5227#include "content/public/common/content_switches.h"
28#include "content/public/common/main_function_params.h"
Etienne Pierre-dorayf3fd9e82024-06-12 16:40:3529#include "services/tracing/public/cpp/trace_startup_config.h"
boliu9847d572015-09-10 20:29:1830#include "third_party/skia/include/core/SkGraphics.h"
Michael Spang539c6f32019-04-03 19:08:5231#include "ui/base/ime/init/input_method_initializer.h"
Etienne Bergeron0acd0fcc2019-09-25 22:45:2632#include "ui/gfx/font_util.h"
[email protected]f573ed6b2012-02-10 15:58:5233
Xiaohan Wang1ecfd002022-01-19 22:33:1034#if BUILDFLAG(IS_ANDROID)
zhenwc074d28f2015-08-31 17:28:1735#include "content/browser/android/tracing_controller_android.h"
36#endif
37
Xiaohan Wang1ecfd002022-01-19 22:33:1038#if BUILDFLAG(IS_WIN)
Bill Carrba4cbb972022-10-10 18:24:1139#include "base/win/win_util.h"
[email protected]b68b51e2012-11-15 01:10:4540#include "base/win/windows_version.h"
[email protected]10208ea2013-06-06 20:08:0341#include "ui/base/win/scoped_ole_initializer.h"
[email protected]f573ed6b2012-02-10 15:58:5242#endif
43
[email protected]46488322012-10-30 03:22:2044namespace content {
rsleevi25e2bc0a2014-09-24 03:12:5545namespace {
46
Lei Zhang81f85692022-10-06 21:03:2247base::AtomicFlag& GetExitedMainMessageLoopFlag() {
48 static base::NoDestructor<base::AtomicFlag> flag;
49 return *flag;
50}
thestig5a551c4c2015-08-29 02:45:3551
rsleevi25e2bc0a2014-09-24 03:12:5552} // namespace
53
Xi Han6740d622018-05-22 19:21:0754// static
Ayu Ishii4e19b5f2019-01-16 23:22:0055std::unique_ptr<BrowserMainRunnerImpl> BrowserMainRunnerImpl::Create() {
56 return std::make_unique<BrowserMainRunnerImpl>();
Xi Han6740d622018-05-22 19:21:0757}
[email protected]f573ed6b2012-02-10 15:58:5258
Xi Han6740d622018-05-22 19:21:0759BrowserMainRunnerImpl::BrowserMainRunnerImpl()
Xi Han8012e462018-10-05 19:52:3060 : initialization_started_(false),
61 is_shutdown_(false),
62 scoped_execution_fence_(
Gabriel Charette43fd3702019-05-29 16:36:5163 std::make_unique<base::ThreadPoolInstance::ScopedExecutionFence>()) {}
[email protected]f573ed6b2012-02-10 15:58:5264
Xi Han6740d622018-05-22 19:21:0765BrowserMainRunnerImpl::~BrowserMainRunnerImpl() {
Sina Firoozabadi9ff575ac2023-02-22 22:42:4666 if (initialization_started_ && !is_shutdown_) {
Xi Han6740d622018-05-22 19:21:0767 Shutdown();
Sina Firoozabadi9ff575ac2023-02-22 22:42:4668 }
Xi Han6740d622018-05-22 19:21:0769}
yiyaoliu9e6a5ab32015-03-18 18:04:3770
Gabriel Charettefbeeb1c2021-11-10 20:50:0671int BrowserMainRunnerImpl::Initialize(MainFunctionParams parameters) {
Xi Han6740d622018-05-22 19:21:0772 SCOPED_UMA_HISTOGRAM_LONG_TIMER(
73 "Startup.BrowserMainRunnerImplInitializeLongTime");
74 TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize");
robliao7fac1d82015-09-23 23:07:4075
Xi Han6740d622018-05-22 19:21:0776 // On Android we normally initialize the browser in a series of UI thread
77 // tasks. While this is happening a second request can come from the OS or
78 // another application to start the browser. If this happens then we must
79 // not run these parts of initialization twice.
80 if (!initialization_started_) {
81 initialization_started_ = true;
Alexei Filippov6cd45c92018-02-10 03:29:1582
Xi Han6740d622018-05-22 19:21:0783 SkGraphics::Init();
John Abd-El-Malek884291c2017-08-09 06:43:4884
Sina Firoozabadi9ff575ac2023-02-22 22:42:4685 if (parameters.command_line->HasSwitch(switches::kWaitForDebugger)) {
Xi Han6740d622018-05-22 19:21:0786 base::debug::WaitForDebugger(60, true);
Sina Firoozabadi9ff575ac2023-02-22 22:42:4687 }
Xi Han6740d622018-05-22 19:21:0788
Sina Firoozabadi9ff575ac2023-02-22 22:42:4689 if (parameters.command_line->HasSwitch(switches::kBrowserStartupDialog)) {
Xi Han6740d622018-05-22 19:21:0790 WaitForDebugger("Browser");
Sina Firoozabadi9ff575ac2023-02-22 22:42:4691 }
Xi Han6740d622018-05-22 19:21:0792
Xiaohan Wang1ecfd002022-01-19 22:33:1093#if BUILDFLAG(IS_WIN)
Bill Carrba4cbb972022-10-10 18:24:1194 base::win::EnableHighDPISupport();
Xi Han6740d622018-05-22 19:21:0795 // Ole must be initialized before starting message pump, so that TSF
96 // (Text Services Framework) module can interact with the message pump
97 // on Windows 8 Metro mode.
Peter Boström560859d2021-05-01 01:31:2598 ole_initializer_ = std::make_unique<ui::ScopedOleInitializer>();
Xiaohan Wang1ecfd002022-01-19 22:33:1099#endif // BUILDFLAG(IS_WIN)
[email protected]962a8482013-01-15 03:42:56100
Etienne Bergeron0acd0fcc2019-09-25 22:45:26101 gfx::InitializeFonts();
102
Gabriel Charettefbeeb1c2021-11-10 20:50:06103 auto created_main_parts_closure =
104 std::move(parameters.created_main_parts_closure);
105
Peter Boströmdd7e40ec2021-04-05 20:40:10106 main_loop_ = std::make_unique<BrowserMainLoop>(
Gabriel Charettefbeeb1c2021-11-10 20:50:06107 std::move(parameters), std::move(scoped_execution_fence_));
[email protected]f573ed6b2012-02-10 15:58:52108
Xi Han4090dcc2018-07-11 03:15:20109 main_loop_->Init();
[email protected]f573ed6b2012-02-10 15:58:52110
Gabriel Charettefbeeb1c2021-11-10 20:50:06111 if (created_main_parts_closure) {
112 std::move(created_main_parts_closure).Run(main_loop_->parts());
[email protected]232e09d2013-08-27 15:29:56113 }
[email protected]f573ed6b2012-02-10 15:58:52114
Xi Han6740d622018-05-22 19:21:07115 const int early_init_error_code = main_loop_->EarlyInitialization();
Will Harrisba4e1a52022-04-20 23:05:33116 if (early_init_error_code > 0) {
117 main_loop_->CreateMessageLoopForEarlyShutdown();
Xi Han6740d622018-05-22 19:21:07118 return early_init_error_code;
Will Harrisba4e1a52022-04-20 23:05:33119 }
robliao7fac1d82015-09-23 23:07:40120
Xi Han6740d622018-05-22 19:21:07121 // Must happen before we try to use a message loop or display any UI.
Alexander Dunaev05210172022-01-19 19:43:09122 if (!main_loop_->InitializeToolkit()) {
123 main_loop_->CreateMessageLoopForEarlyShutdown();
Xi Han6740d622018-05-22 19:21:07124 return 1;
Alexander Dunaev05210172022-01-19 19:43:09125 }
Xi Han6740d622018-05-22 19:21:07126
Gabriel Charette09c6a96e2021-05-17 14:52:59127 main_loop_->PreCreateMainMessageLoop();
128 main_loop_->CreateMainMessageLoop();
129 main_loop_->PostCreateMainMessageLoop();
Xi Han6740d622018-05-22 19:21:07130
131 // WARNING: If we get a WM_ENDSESSION, objects created on the stack here
132 // are NOT deleted. If you need something to run during WM_ENDSESSION add it
133 // to browser_shutdown::Shutdown or BrowserProcess::EndSession.
134
135 ui::InitializeInputMethod();
[email protected]f573ed6b2012-02-10 15:58:52136 }
Xi Han6740d622018-05-22 19:21:07137 main_loop_->CreateStartupTasks();
138 int result_code = main_loop_->GetResultCode();
Sina Firoozabadi9ff575ac2023-02-22 22:42:46139 if (result_code > 0) {
Xi Han6740d622018-05-22 19:21:07140 return result_code;
Sina Firoozabadi9ff575ac2023-02-22 22:42:46141 }
Xi Han6740d622018-05-22 19:21:07142
143 // Return -1 to indicate no early termination.
144 return -1;
145}
[email protected]f573ed6b2012-02-10 15:58:52146
Xiaohan Wang1ecfd002022-01-19 22:33:10147#if BUILDFLAG(IS_ANDROID)
Xi Han6740d622018-05-22 19:21:07148void BrowserMainRunnerImpl::SynchronouslyFlushStartupTasks() {
149 main_loop_->SynchronouslyFlushStartupTasks();
150}
John Budoricka7971502017-08-14 20:03:03151#endif
152
Xi Han6740d622018-05-22 19:21:07153int BrowserMainRunnerImpl::Run() {
154 DCHECK(initialization_started_);
155 DCHECK(!is_shutdown_);
Gabriel Charettec716bcf32021-03-16 16:25:35156 main_loop_->RunMainMessageLoop();
Xi Han6740d622018-05-22 19:21:07157 return main_loop_->GetResultCode();
158}
[email protected]f573ed6b2012-02-10 15:58:52159
Xi Han6740d622018-05-22 19:21:07160void BrowserMainRunnerImpl::Shutdown() {
161 DCHECK(initialization_started_);
162 DCHECK(!is_shutdown_);
bcwhiteda097d32017-01-12 23:55:03163
Kalvin Lee8529bdde2024-10-25 14:10:42164#if BUILDFLAG(IS_CHROMEOS)
165 // Reduces shutdown hangs on CrOS.
166 // Googlers: see go/cros-no-op-free-2024 for the experiment write-up.
167 base::allocator::MakeFreeNoOp();
168#endif
Kalvin Leeafefbfe2024-05-23 18:37:16169
Xi Han6740d622018-05-22 19:21:07170 main_loop_->PreShutdown();
bcwhiteda097d32017-01-12 23:55:03171
Eric Seckler7d928e2d2019-04-05 19:05:35172 // Finalize the startup tracing session if it is still active.
ssid6bedaa92021-06-16 10:25:24173 StartupTracingController::GetInstance().ShutdownAndWaitForStopIfNeeded();
Chris Pickel5d76e332018-05-15 12:18:57174
Xi Han6740d622018-05-22 19:21:07175 {
176 // The trace event has to stay between profiler creation and destruction.
177 TRACE_EVENT0("shutdown", "BrowserMainRunner");
Lei Zhang81f85692022-10-06 21:03:22178 GetExitedMainMessageLoopFlag().Set();
Chris Pickel5d76e332018-05-15 12:18:57179
Xi Han6740d622018-05-22 19:21:07180 main_loop_->ShutdownThreadsAndCleanUp();
181
182 ui::ShutdownInputMethod();
Xiaohan Wang1ecfd002022-01-19 22:33:10183#if BUILDFLAG(IS_WIN)
Xi Han6740d622018-05-22 19:21:07184 ole_initializer_.reset(NULL);
Chris Pickel5d76e332018-05-15 12:18:57185#endif
Xi Han6740d622018-05-22 19:21:07186 main_loop_.reset(nullptr);
Chris Pickel5d76e332018-05-15 12:18:57187
Xi Han6740d622018-05-22 19:21:07188 is_shutdown_ = true;
189 }
190}
[email protected]f573ed6b2012-02-10 15:58:52191
[email protected]f573ed6b2012-02-10 15:58:52192// static
Ayu Ishii4e19b5f2019-01-16 23:22:00193std::unique_ptr<BrowserMainRunner> BrowserMainRunner::Create() {
Xi Han6740d622018-05-22 19:21:07194 return BrowserMainRunnerImpl::Create();
[email protected]f573ed6b2012-02-10 15:58:52195}
196
thestig5a551c4c2015-08-29 02:45:35197// static
198bool BrowserMainRunner::ExitedMainMessageLoop() {
Lei Zhang81f85692022-10-06 21:03:22199 return GetExitedMainMessageLoopFlag().IsSet();
thestig5a551c4c2015-08-29 02:45:35200}
201
[email protected]f573ed6b2012-02-10 15:58:52202} // namespace content