Commit a1105c68 authored by Xi Han's avatar Xi Han Committed by Commit Bot

Split ContentMain start and ServiceManager Start.

With "allow-start-service-manager-only" flag, we can start the service
manager without starting the remaining parts of the browser,
particularly the browser main loop. Later, we could start the full
browser with the service manager running. Currently, both code path go
through service_manager::main(). Therefore, we need to avoid calling the
initialization in service_manager::main() multiple times.

In this CL:
1. service_manager::main() checks its static bool flag to decide
   whether initialization should be called.
2. Plumbs the start-service-manager-only flag to the ContentMainRunner
   who starts the browser main loop.

This CL impacts Android only for now. It follows up CL:
 https://crrev.com/c/1093303.

BUG=854209, 846846

Change-Id: I7fcfb804ce7f3065da7df12947674344fe2f56d6
Reviewed-on: https://chromium-review.googlesource.com/1114077
Commit-Queue: Xi Han <hanxi@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574169}
parent 57988b5c
......@@ -42,10 +42,12 @@ static jint JNI_ContentMain_Start(JNIEnv* env,
g_service_manager_main_delegate.Get() =
std::make_unique<ContentServiceManagerMainDelegate>(
ContentMainParams(g_content_main_delegate.Get().get()));
} else {
return 0;
}
static_cast<ContentServiceManagerMainDelegate*>(
g_service_manager_main_delegate.Get().get())
->SetStartServiceManagerOnly(start_service_manager_only);
service_manager::MainParams main_params(
g_service_manager_main_delegate.Get().get());
return service_manager::Main(main_params);
......
......@@ -893,7 +893,7 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
return -1;
}
int ContentMainRunnerImpl::Run() {
int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
DCHECK(is_initialized_);
DCHECK(!is_shutdown_);
const base::CommandLine& command_line =
......
......@@ -41,7 +41,7 @@ class ContentMainRunnerImpl : public ContentMainRunner {
// ContentMainRunner:
int Initialize(const ContentMainParams& params) override;
int Run() override;
int Run(bool start_service_manager_only) override;
void Shutdown() override;
private:
......
......@@ -50,7 +50,7 @@ bool ContentServiceManagerMainDelegate::IsEmbedderSubprocess() {
}
int ContentServiceManagerMainDelegate::RunEmbedderProcess() {
return content_main_runner_->Run();
return content_main_runner_->Run(start_service_manager_only_);
}
void ContentServiceManagerMainDelegate::ShutDownEmbedderProcess() {
......@@ -126,4 +126,9 @@ ContentServiceManagerMainDelegate::CreateEmbeddedService(
return nullptr;
}
void ContentServiceManagerMainDelegate::SetStartServiceManagerOnly(
bool start_service_manager_only) {
start_service_manager_only_ = start_service_manager_only;
}
} // namespace content
......@@ -42,6 +42,10 @@ class ContentServiceManagerMainDelegate : public service_manager::MainDelegate {
std::unique_ptr<service_manager::Service> CreateEmbeddedService(
const std::string& service_name) override;
// Sets the flag whether to start the Service Manager without starting the
// full browser.
void SetStartServiceManagerOnly(bool start_service_manager_only);
private:
ContentMainParams content_main_params_;
std::unique_ptr<ContentMainRunnerImpl> content_main_runner_;
......@@ -50,6 +54,10 @@ class ContentServiceManagerMainDelegate : public service_manager::MainDelegate {
bool initialized_ = false;
#endif
// Indicates whether to start the Service Manager without starting the full
// browser.
bool start_service_manager_only_ = false;
DISALLOW_COPY_AND_ASSIGN(ContentServiceManagerMainDelegate);
};
......
......@@ -23,7 +23,7 @@ class CONTENT_EXPORT ContentMainRunner {
virtual int Initialize(const ContentMainParams& params) = 0;
// Perform the default run logic.
virtual int Run() = 0;
virtual int Run(bool start_service_manager_only) = 0;
// Shut down the content state.
virtual void Shutdown() = 0;
......
......@@ -310,87 +310,141 @@ int Main(const MainParams& params) {
MainDelegate* delegate = params.delegate;
DCHECK(delegate);
int exit_code = -1;
base::debug::GlobalActivityTracker* tracker = nullptr;
ProcessType process_type = delegate->OverrideProcessType();
#if defined(OS_MACOSX)
std::unique_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool;
#endif
// A flag to indicate whether Main() has been called before. On Android, we
// may re-run Main() without restarting the browser process. This flag
// prevents initializing things more than once.
static bool is_initialized = false;
#if !defined(OS_ANDROID)
DCHECK(!is_initialized);
#endif
if (!is_initialized) {
is_initialized = true;
#if defined(OS_MACOSX) && BUILDFLAG(USE_ALLOCATOR_SHIM)
base::allocator::InitializeAllocatorShim();
base::allocator::InitializeAllocatorShim();
#endif
base::EnableTerminationOnOutOfMemory();
base::EnableTerminationOnOutOfMemory();
#if defined(OS_LINUX)
// The various desktop environments set this environment variable that allows
// the dbus client library to connect directly to the bus. When this variable
// is not set (test environments like xvfb-run), the dbus client library will
// fall back to auto-launch mode. Auto-launch is dangerous as it can cause
// hangs (crbug.com/715658) . This one line disables the dbus auto-launch,
// by clobbering the DBUS_SESSION_BUS_ADDRESS env variable if not already set.
// The old auto-launch behavior, if needed, can be restored by setting
// DBUS_SESSION_BUS_ADDRESS="autolaunch:" before launching chrome.
const int kNoOverrideIfAlreadySet = 0;
setenv("DBUS_SESSION_BUS_ADDRESS", "disabled:", kNoOverrideIfAlreadySet);
// The various desktop environments set this environment variable that
// allows the dbus client library to connect directly to the bus. When this
// variable is not set (test environments like xvfb-run), the dbus client
// library will fall back to auto-launch mode. Auto-launch is dangerous as
// it can cause hangs (crbug.com/715658) . This one line disables the dbus
// auto-launch, by clobbering the DBUS_SESSION_BUS_ADDRESS env variable if
// not already set. The old auto-launch behavior, if needed, can be restored
// by setting DBUS_SESSION_BUS_ADDRESS="autolaunch:" before launching
// chrome.
const int kNoOverrideIfAlreadySet = 0;
setenv("DBUS_SESSION_BUS_ADDRESS", "disabled:", kNoOverrideIfAlreadySet);
#endif
#if defined(OS_WIN)
base::win::RegisterInvalidParamHandler();
ui::win::CreateATLModuleIfNeeded();
base::win::RegisterInvalidParamHandler();
ui::win::CreateATLModuleIfNeeded();
#endif // defined(OS_WIN)
#if !defined(OS_ANDROID)
// On Android, the command line is initialized when library is loaded.
int argc = 0;
const char** argv = nullptr;
// On Android, the command line is initialized when library is loaded.
int argc = 0;
const char** argv = nullptr;
#if !defined(OS_WIN)
// argc/argv are ignored on Windows; see command_line.h for details.
argc = params.argc;
argv = params.argv;
// argc/argv are ignored on Windows; see command_line.h for details.
argc = params.argc;
argv = params.argv;
#endif
base::CommandLine::Init(argc, argv);
base::CommandLine::Init(argc, argv);
#if defined(OS_POSIX)
PopulateFDsFromCommandLine();
PopulateFDsFromCommandLine();
#endif
base::EnableTerminationOnHeapCorruption();
base::EnableTerminationOnHeapCorruption();
SetProcessTitleFromCommandLine(argv);
SetProcessTitleFromCommandLine(argv);
#endif // !defined(OS_ANDROID)
// On Android setlocale() is not supported, and we don't override the signal
// handlers so we can get a stack trace when crashing.
#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
// Set C library locale to make sure CommandLine can parse argument values in
// the correct encoding.
setlocale(LC_ALL, "");
// Set C library locale to make sure CommandLine can parse argument values
// in the correct encoding.
setlocale(LC_ALL, "");
SetupSignalHandlers();
SetupSignalHandlers();
#endif
const auto& command_line = *base::CommandLine::ForCurrentProcess();
const auto& command_line = *base::CommandLine::ForCurrentProcess();
#if defined(OS_WIN)
base::win::SetupCRT(command_line);
base::win::SetupCRT(command_line);
#endif
MainDelegate::InitializeParams init_params;
MainDelegate::InitializeParams init_params;
#if defined(OS_MACOSX)
// We need this pool for all the objects created before we get to the event
// loop, but we don't want to leave them hanging around until the app quits.
// Each "main" needs to flush this pool right before it goes into its main
// event loop to get rid of the cruft.
std::unique_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool =
std::make_unique<base::mac::ScopedNSAutoreleasePool>();
init_params.autorelease_pool = autorelease_pool.get();
InitializeMac();
// We need this pool for all the objects created before we get to the event
// loop, but we don't want to leave them hanging around until the app quits.
// Each "main" needs to flush this pool right before it goes into its main
// event loop to get rid of the cruft.
autorelease_pool = std::make_unique<base::mac::ScopedNSAutoreleasePool>();
init_params.autorelease_pool = autorelease_pool.get();
InitializeMac();
#endif
mojo::core::Configuration mojo_config;
ProcessType process_type = delegate->OverrideProcessType();
mojo::core::Configuration mojo_config;
if (process_type == ProcessType::kDefault &&
command_line.GetSwitchValueASCII(switches::kProcessType) ==
switches::kProcessTypeServiceManager) {
mojo_config.is_broker_process = true;
}
mojo_config.max_message_num_bytes = kMaximumMojoMessageSize;
delegate->OverrideMojoConfiguration(&mojo_config);
mojo::core::Init(mojo_config);
ui::RegisterPathProvider();
tracker = base::debug::GlobalActivityTracker::Get();
exit_code = delegate->Initialize(init_params);
if (exit_code >= 0) {
if (tracker) {
tracker->SetProcessPhase(
base::debug::GlobalActivityTracker::PROCESS_LAUNCH_FAILED);
tracker->process_data().SetInt("exit-code", exit_code);
}
return exit_code;
}
#if defined(OS_WIN)
// Route stdio to parent console (if any) or create one.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableLogging)) {
base::RouteStdioToConsole(true);
}
#endif
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kTraceToConsole)) {
base::trace_event::TraceConfig trace_config =
tracing::GetConfigForTraceToConsole();
base::trace_event::TraceLog::GetInstance()->SetEnabled(
trace_config, base::trace_event::TraceLog::RECORDING_MODE);
}
}
const auto& command_line = *base::CommandLine::ForCurrentProcess();
if (process_type == ProcessType::kDefault) {
std::string type_switch =
command_line.GetSwitchValueASCII(switches::kProcessType);
if (type_switch == switches::kProcessTypeServiceManager) {
mojo_config.is_broker_process = true;
process_type = ProcessType::kServiceManager;
} else if (type_switch == switches::kProcessTypeService) {
process_type = ProcessType::kService;
......@@ -398,40 +452,6 @@ int Main(const MainParams& params) {
process_type = ProcessType::kEmbedder;
}
}
mojo_config.max_message_num_bytes = kMaximumMojoMessageSize;
delegate->OverrideMojoConfiguration(&mojo_config);
mojo::core::Init(mojo_config);
ui::RegisterPathProvider();
base::debug::GlobalActivityTracker* tracker =
base::debug::GlobalActivityTracker::Get();
int exit_code = delegate->Initialize(init_params);
if (exit_code >= 0) {
if (tracker) {
tracker->SetProcessPhase(
base::debug::GlobalActivityTracker::PROCESS_LAUNCH_FAILED);
tracker->process_data().SetInt("exit-code", exit_code);
}
return exit_code;
}
#if defined(OS_WIN)
// Route stdio to parent console (if any) or create one.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableLogging)) {
base::RouteStdioToConsole(true);
}
#endif
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kTraceToConsole)) {
base::trace_event::TraceConfig trace_config =
tracing::GetConfigForTraceToConsole();
base::trace_event::TraceLog::GetInstance()->SetEnabled(
trace_config, base::trace_event::TraceLog::RECORDING_MODE);
}
switch (process_type) {
case ProcessType::kDefault:
NOTREACHED();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment