OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/app/mash/mash_runner.h" | 5 #include "chrome/app/mash/mash_runner.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
10 #include "base/base_paths.h" | 10 #include "base/base_paths.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "base/sys_info.h" | 25 #include "base/sys_info.h" |
26 #include "base/task_scheduler/task_scheduler.h" | 26 #include "base/task_scheduler/task_scheduler.h" |
27 #include "base/threading/sequenced_worker_pool.h" | 27 #include "base/threading/sequenced_worker_pool.h" |
28 #include "base/threading/thread.h" | 28 #include "base/threading/thread.h" |
29 #include "base/trace_event/trace_event.h" | 29 #include "base/trace_event/trace_event.h" |
30 #include "chrome/app/mash/chrome_mash_catalog.h" | 30 #include "chrome/app/mash/chrome_mash_catalog.h" |
31 #include "components/tracing/common/trace_to_console.h" | 31 #include "components/tracing/common/trace_to_console.h" |
32 #include "components/tracing/common/tracing_switches.h" | 32 #include "components/tracing/common/tracing_switches.h" |
33 #include "content/public/common/content_switches.h" | 33 #include "content/public/common/content_switches.h" |
34 #include "content/public/common/service_names.mojom.h" | 34 #include "content/public/common/service_names.mojom.h" |
| 35 #include "mash/common/config.h" |
35 #include "mash/package/mash_packaged_service.h" | 36 #include "mash/package/mash_packaged_service.h" |
36 #include "mash/session/public/interfaces/constants.mojom.h" | 37 #include "mash/quick_launch/public/interfaces/constants.mojom.h" |
37 #include "mojo/edk/embedder/embedder.h" | 38 #include "mojo/edk/embedder/embedder.h" |
38 #include "mojo/edk/embedder/scoped_ipc_support.h" | 39 #include "mojo/edk/embedder/scoped_ipc_support.h" |
39 #include "mojo/public/cpp/bindings/binding_set.h" | 40 #include "mojo/public/cpp/bindings/binding_set.h" |
40 #include "services/catalog/public/interfaces/catalog.mojom.h" | 41 #include "services/catalog/public/interfaces/catalog.mojom.h" |
41 #include "services/catalog/public/interfaces/constants.mojom.h" | 42 #include "services/catalog/public/interfaces/constants.mojom.h" |
42 #include "services/service_manager/background/background_service_manager.h" | 43 #include "services/service_manager/background/background_service_manager.h" |
43 #include "services/service_manager/public/cpp/connector.h" | 44 #include "services/service_manager/public/cpp/connector.h" |
44 #include "services/service_manager/public/cpp/identity.h" | 45 #include "services/service_manager/public/cpp/identity.h" |
45 #include "services/service_manager/public/cpp/service.h" | 46 #include "services/service_manager/public/cpp/service.h" |
46 #include "services/service_manager/public/cpp/service_context.h" | 47 #include "services/service_manager/public/cpp/service_context.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 140 |
140 // For now all standalone services act like the browser process and write | 141 // For now all standalone services act like the browser process and write |
141 // their own in-process crash dumps. When ash and the window server are | 142 // their own in-process crash dumps. When ash and the window server are |
142 // sandboxed we will need to hook up the crash signal file descriptor, make | 143 // sandboxed we will need to hook up the crash signal file descriptor, make |
143 // the root process handle dumping, and pass a process type here. | 144 // the root process handle dumping, and pass a process type here. |
144 const std::string process_type_unused; | 145 const std::string process_type_unused; |
145 breakpad::InitCrashReporter(process_type_unused); | 146 breakpad::InitCrashReporter(process_type_unused); |
146 } | 147 } |
147 #endif // defined(OS_CHROMEOS) | 148 #endif // defined(OS_CHROMEOS) |
148 | 149 |
| 150 // Quits |run_loop| if the |identity| of the quitting service is critical to the |
| 151 // system (e.g. the window manager). Used in the main process. |
| 152 void OnInstanceQuitInMain(base::RunLoop* run_loop, |
| 153 int* exit_value, |
| 154 const service_manager::Identity& identity) { |
| 155 DCHECK(exit_value); |
| 156 DCHECK(run_loop); |
| 157 |
| 158 // TODO(jamescook): Also shut down if the window server dies. |
| 159 if (identity.name() != mash::common::GetWindowManagerServiceName()) |
| 160 return; |
| 161 |
| 162 if (!run_loop->running()) |
| 163 return; |
| 164 |
| 165 *exit_value = 1; |
| 166 run_loop->Quit(); |
| 167 } |
| 168 |
149 } // namespace | 169 } // namespace |
150 | 170 |
151 MashRunner::MashRunner() {} | 171 MashRunner::MashRunner() {} |
152 | 172 |
153 MashRunner::~MashRunner() {} | 173 MashRunner::~MashRunner() {} |
154 | 174 |
155 int MashRunner::Run() { | 175 int MashRunner::Run() { |
156 base::TaskScheduler::CreateAndSetSimpleTaskScheduler( | 176 base::TaskScheduler::CreateAndSetSimpleTaskScheduler( |
157 base::SysInfo::NumberOfProcessors()); | 177 base::SysInfo::NumberOfProcessors()); |
158 | 178 |
159 if (IsChild()) | 179 if (IsChild()) |
160 return RunChild(); | 180 return RunChild(); |
161 RunMain(); | 181 |
162 return 0; | 182 return RunMain(); |
163 } | 183 } |
164 | 184 |
165 void MashRunner::RunMain() { | 185 int MashRunner::RunMain() { |
166 base::SequencedWorkerPool::EnableWithRedirectionToTaskSchedulerForProcess(); | 186 base::SequencedWorkerPool::EnableWithRedirectionToTaskSchedulerForProcess(); |
167 | 187 |
168 mojo::edk::Init(); | 188 mojo::edk::Init(); |
169 | 189 |
170 base::Thread ipc_thread("IPC thread"); | 190 base::Thread ipc_thread("IPC thread"); |
171 ipc_thread.StartWithOptions( | 191 ipc_thread.StartWithOptions( |
172 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 192 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
173 mojo::edk::ScopedIPCSupport ipc_support( | 193 mojo::edk::ScopedIPCSupport ipc_support( |
174 ipc_thread.task_runner(), | 194 ipc_thread.task_runner(), |
175 mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST); | 195 mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST); |
176 | 196 |
| 197 int exit_value = RunServiceManagerInMain(); |
| 198 |
| 199 ipc_thread.Stop(); |
| 200 base::TaskScheduler::GetInstance()->Shutdown(); |
| 201 return exit_value; |
| 202 } |
| 203 |
| 204 int MashRunner::RunServiceManagerInMain() { |
177 // TODO(sky): refactor BackgroundServiceManager so can supply own context, we | 205 // TODO(sky): refactor BackgroundServiceManager so can supply own context, we |
178 // shouldn't we using context as it has a lot of stuff we don't really want | 206 // shouldn't we using context as it has a lot of stuff we don't really want |
179 // in chrome. | 207 // in chrome. |
180 ServiceProcessLauncherDelegateImpl service_process_launcher_delegate; | 208 ServiceProcessLauncherDelegateImpl service_process_launcher_delegate; |
181 service_manager::BackgroundServiceManager background_service_manager( | 209 service_manager::BackgroundServiceManager background_service_manager( |
182 &service_process_launcher_delegate, CreateChromeMashCatalog()); | 210 &service_process_launcher_delegate, CreateChromeMashCatalog()); |
183 service_manager::mojom::ServicePtr service; | 211 service_manager::mojom::ServicePtr service; |
184 context_.reset(new service_manager::ServiceContext( | 212 context_.reset(new service_manager::ServiceContext( |
185 base::MakeUnique<mash::MashPackagedService>(), | 213 base::MakeUnique<mash::MashPackagedService>(), |
186 service_manager::mojom::ServiceRequest(&service))); | 214 service_manager::mojom::ServiceRequest(&service))); |
187 background_service_manager.RegisterService( | 215 background_service_manager.RegisterService( |
188 service_manager::Identity( | 216 service_manager::Identity( |
189 kChromeMashServiceName, service_manager::mojom::kRootUserID), | 217 kChromeMashServiceName, service_manager::mojom::kRootUserID), |
190 std::move(service), nullptr); | 218 std::move(service), nullptr); |
191 | 219 |
192 // Ping mash_session to ensure an instance is brought up | 220 // Quit the main process if an important child (e.g. window manager) dies. |
193 context_->connector()->Connect(mash::session::mojom::kServiceName); | 221 // On Chrome OS the OS-level session_manager will restart the main process. |
194 base::RunLoop().Run(); | 222 base::RunLoop run_loop; |
| 223 int exit_value = 0; |
| 224 background_service_manager.SetInstanceQuitCallback( |
| 225 base::Bind(&OnInstanceQuitInMain, &run_loop, &exit_value)); |
195 | 226 |
196 base::TaskScheduler::GetInstance()->Shutdown(); | 227 // Ping services that we know we want to launch on startup. |
| 228 // TODO(jamescook): Start the window server / ui service explicitly. |
| 229 context_->connector()->Connect(mash::common::GetWindowManagerServiceName()); |
| 230 context_->connector()->Connect(mash::quick_launch::mojom::kServiceName); |
| 231 |
| 232 run_loop.Run(); |
| 233 |
| 234 context_.reset(); |
| 235 return exit_value; |
197 } | 236 } |
198 | 237 |
199 int MashRunner::RunChild() { | 238 int MashRunner::RunChild() { |
200 service_manager::WaitForDebuggerIfNecessary(); | 239 service_manager::WaitForDebuggerIfNecessary(); |
201 | 240 |
202 base::i18n::InitializeICU(); | 241 base::i18n::InitializeICU(); |
203 InitializeResources(); | 242 InitializeResources(); |
204 service_manager::RunStandaloneService( | 243 service_manager::RunStandaloneService( |
205 base::Bind(&MashRunner::StartChildApp, base::Unretained(this))); | 244 base::Bind(&MashRunner::StartChildApp, base::Unretained(this))); |
206 return 0; | 245 return 0; |
207 } | 246 } |
208 | 247 |
209 void MashRunner::StartChildApp( | 248 void MashRunner::StartChildApp( |
210 service_manager::mojom::ServiceRequest service_request) { | 249 service_manager::mojom::ServiceRequest service_request) { |
211 // TODO(sad): Normally, this would be a TYPE_DEFAULT message loop. However, | 250 // TODO(sad): Normally, this would be a TYPE_DEFAULT message loop. However, |
212 // TYPE_UI is needed for mojo:ui. But it is not known whether the child app is | 251 // TYPE_UI is needed for mojo:ui. But it is not known whether the child app is |
213 // going to be mojo:ui at this point. So always create a TYPE_UI message loop | 252 // going to be mojo:ui at this point. So always create a TYPE_UI message loop |
214 // for now. | 253 // for now. |
215 base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); | 254 base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); |
| 255 base::RunLoop run_loop; |
216 context_.reset(new service_manager::ServiceContext( | 256 context_.reset(new service_manager::ServiceContext( |
217 base::MakeUnique<mash::MashPackagedService>(), | 257 base::MakeUnique<mash::MashPackagedService>(), |
218 std::move(service_request))); | 258 std::move(service_request))); |
219 base::RunLoop().Run(); | 259 // Quit the child process if it loses its connection to service manager. |
| 260 context_->SetConnectionLostClosure(run_loop.QuitClosure()); |
| 261 run_loop.Run(); |
220 } | 262 } |
221 | 263 |
222 int MashMain() { | 264 int MashMain() { |
223 #if !defined(OFFICIAL_BUILD) && defined(OS_WIN) | 265 #if !defined(OFFICIAL_BUILD) && defined(OS_WIN) |
224 base::RouteStdioToConsole(false); | 266 base::RouteStdioToConsole(false); |
225 #endif | 267 #endif |
226 // TODO(sky): wire this up correctly. | 268 // TODO(sky): wire this up correctly. |
227 service_manager::InitializeLogging(); | 269 service_manager::InitializeLogging(); |
228 | 270 |
229 #if defined(OS_LINUX) | 271 #if defined(OS_LINUX) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 command_line->GetSwitchValueASCII(switches::kWaitForDebugger)) { | 313 command_line->GetSwitchValueASCII(switches::kWaitForDebugger)) { |
272 return; | 314 return; |
273 } | 315 } |
274 | 316 |
275 // Include the pid as logging may not have been initialized yet (the pid | 317 // Include the pid as logging may not have been initialized yet (the pid |
276 // printed out by logging is wrong). | 318 // printed out by logging is wrong). |
277 LOG(WARNING) << "waiting for debugger to attach for service " << service_name | 319 LOG(WARNING) << "waiting for debugger to attach for service " << service_name |
278 << " pid=" << base::Process::Current().Pid(); | 320 << " pid=" << base::Process::Current().Pid(); |
279 base::debug::WaitForDebugger(120, true); | 321 base::debug::WaitForDebugger(120, true); |
280 } | 322 } |
OLD | NEW |