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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 #include "ui/base/ui_base_paths.h" | 55 #include "ui/base/ui_base_paths.h" |
56 #include "ui/base/ui_base_switches.h" | 56 #include "ui/base/ui_base_switches.h" |
57 | 57 |
58 #if defined(OS_POSIX) | 58 #if defined(OS_POSIX) |
59 #include <signal.h> | 59 #include <signal.h> |
60 | 60 |
61 #include "base/threading/thread_task_runner_handle.h" | 61 #include "base/threading/thread_task_runner_handle.h" |
62 #include "chrome/app/shutdown_signal_handlers_posix.h" | 62 #include "chrome/app/shutdown_signal_handlers_posix.h" |
63 #endif // defined(OS_POSIX) | 63 #endif // defined(OS_POSIX) |
64 | 64 |
| 65 #if defined(OS_CHROMEOS) |
| 66 #include "chrome/app/mash/chrome_mus_catalog.h" |
| 67 #endif |
| 68 |
65 using service_manager::mojom::ServiceFactory; | 69 using service_manager::mojom::ServiceFactory; |
66 | 70 |
67 namespace { | 71 namespace { |
68 | 72 |
69 // kProcessType used to identify child processes. | 73 // kProcessType used to identify child processes. |
70 const char* kMashChild = "mash-child"; | 74 const char* kMashChild = "mash-child"; |
71 | 75 |
72 const char kChromeMashServiceName[] = "chrome_mash"; | 76 const char kChromeMashServiceName[] = "chrome_mash"; |
73 | 77 |
| 78 // Name used for --mus. This is only applicable to ChromeOS. it is placed |
| 79 // outside of ifdefs to make code slightly more readable. |
| 80 const char kChromeMusServiceName[] = "chrome_mus"; |
| 81 |
74 bool IsChild() { | 82 bool IsChild() { |
75 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 83 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
76 switches::kProcessType) && | 84 switches::kProcessType) && |
77 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 85 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
78 switches::kProcessType) == kMashChild; | 86 switches::kProcessType) == kMashChild; |
79 } | 87 } |
80 | 88 |
81 void InitializeResources() { | 89 void InitializeResources() { |
82 ui::RegisterPathProvider(); | 90 ui::RegisterPathProvider(); |
83 const std::string locale = | 91 const std::string locale = |
84 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 92 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
85 switches::kLang); | 93 switches::kLang); |
86 // This loads the Chrome's resources (chrome_100_percent.pak etc.) | 94 // This loads the Chrome's resources (chrome_100_percent.pak etc.) |
87 ui::ResourceBundle::InitSharedInstanceWithLocale( | 95 ui::ResourceBundle::InitSharedInstanceWithLocale( |
88 locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES); | 96 locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES); |
89 } | 97 } |
90 | 98 |
91 class ServiceProcessLauncherDelegateImpl | 99 class ServiceProcessLauncherDelegateImpl |
92 : public service_manager::ServiceProcessLauncher::Delegate { | 100 : public service_manager::ServiceProcessLauncher::Delegate { |
93 public: | 101 public: |
94 ServiceProcessLauncherDelegateImpl() {} | 102 ServiceProcessLauncherDelegateImpl() {} |
95 ~ServiceProcessLauncherDelegateImpl() override {} | 103 ~ServiceProcessLauncherDelegateImpl() override {} |
96 | 104 |
97 private: | 105 private: |
98 // service_manager::ServiceProcessLauncher::Delegate: | 106 // service_manager::ServiceProcessLauncher::Delegate: |
99 void AdjustCommandLineArgumentsForTarget( | 107 void AdjustCommandLineArgumentsForTarget( |
100 const service_manager::Identity& target, | 108 const service_manager::Identity& target, |
101 base::CommandLine* command_line) override { | 109 base::CommandLine* command_line) override { |
102 if (target.name() == kChromeMashServiceName || | 110 if (target.name() == kChromeMashServiceName || |
| 111 target.name() == kChromeMusServiceName || |
103 target.name() == content::mojom::kPackagedServicesServiceName) { | 112 target.name() == content::mojom::kPackagedServicesServiceName) { |
104 base::FilePath exe_path; | 113 base::FilePath exe_path; |
105 base::PathService::Get(base::FILE_EXE, &exe_path); | 114 base::PathService::Get(base::FILE_EXE, &exe_path); |
106 command_line->SetProgram(exe_path); | 115 command_line->SetProgram(exe_path); |
107 } | 116 } |
108 if (target.name() != content::mojom::kPackagedServicesServiceName) { | 117 if (target.name() != content::mojom::kPackagedServicesServiceName) { |
109 // If running anything other than the browser process, launch a mash | 118 // If running anything other than the browser process, launch a mash |
110 // child process. The new process will execute MashRunner::RunChild(). | 119 // child process. The new process will execute MashRunner::RunChild(). |
111 command_line->AppendSwitchASCII(switches::kProcessType, kMashChild); | 120 command_line->AppendSwitchASCII(switches::kProcessType, kMashChild); |
112 #if defined(OS_WIN) | 121 #if defined(OS_WIN) |
113 command_line->AppendArg(switches::kPrefetchArgumentOther); | 122 command_line->AppendArg(switches::kPrefetchArgumentOther); |
114 #endif | 123 #endif |
115 return; | 124 return; |
116 } | 125 } |
117 | 126 |
118 // When launching the browser process, ensure that we don't inherit the | 127 // When launching the browser process, ensure that we don't inherit the |
119 // --mash flag so it proceeds with the normal content/browser startup path. | 128 // the mash/mus flag so it proceeds with the normal content/browser startup |
| 129 // path. |
| 130 const bool is_mash = command_line->HasSwitch(switches::kMash); |
120 base::CommandLine::SwitchMap new_switches = command_line->GetSwitches(); | 131 base::CommandLine::SwitchMap new_switches = command_line->GetSwitches(); |
121 new_switches.erase(switches::kMash); | 132 new_switches.erase(switches::kMash); |
| 133 new_switches.erase(switches::kMus); |
122 *command_line = base::CommandLine(command_line->GetProgram()); | 134 *command_line = base::CommandLine(command_line->GetProgram()); |
123 for (const std::pair<std::string, base::CommandLine::StringType>& sw : | 135 for (const std::pair<std::string, base::CommandLine::StringType>& sw : |
124 new_switches) { | 136 new_switches) { |
125 command_line->AppendSwitchNative(sw.first, sw.second); | 137 command_line->AppendSwitchNative(sw.first, sw.second); |
126 } | 138 } |
| 139 // Add kMusConfig so that launched processes know what config they are |
| 140 // running in. |
| 141 command_line->AppendSwitchASCII(switches::kMusConfig, |
| 142 is_mash ? switches::kMash : switches::kMus); |
127 } | 143 } |
128 | 144 |
129 DISALLOW_COPY_AND_ASSIGN(ServiceProcessLauncherDelegateImpl); | 145 DISALLOW_COPY_AND_ASSIGN(ServiceProcessLauncherDelegateImpl); |
130 }; | 146 }; |
131 | 147 |
132 // Quits |run_loop| if the |identity| of the quitting service is critical to the | 148 // Quits |run_loop| if the |identity| of the quitting service is critical to the |
133 // system (e.g. the window manager). Used in the main process. | 149 // system (e.g. the window manager). Used in the main process. |
134 void OnInstanceQuitInMain(base::RunLoop* run_loop, | 150 void OnInstanceQuitInMain(base::RunLoop* run_loop, |
135 int* exit_value, | 151 int* exit_value, |
136 const service_manager::Identity& identity) { | 152 const service_manager::Identity& identity) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 ipc_thread.Stop(); | 199 ipc_thread.Stop(); |
184 base::TaskScheduler::GetInstance()->Shutdown(); | 200 base::TaskScheduler::GetInstance()->Shutdown(); |
185 return exit_value; | 201 return exit_value; |
186 } | 202 } |
187 | 203 |
188 int MashRunner::RunServiceManagerInMain() { | 204 int MashRunner::RunServiceManagerInMain() { |
189 // TODO(sky): refactor BackgroundServiceManager so can supply own context, we | 205 // TODO(sky): refactor BackgroundServiceManager so can supply own context, we |
190 // 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 |
191 // in chrome. | 207 // in chrome. |
192 ServiceProcessLauncherDelegateImpl service_process_launcher_delegate; | 208 ServiceProcessLauncherDelegateImpl service_process_launcher_delegate; |
| 209 const bool is_mash = |
| 210 base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kMash); |
| 211 #if defined(OS_CHROMEOS) |
| 212 service_manager::BackgroundServiceManager background_service_manager( |
| 213 &service_process_launcher_delegate, |
| 214 is_mash ? CreateChromeMashCatalog() : CreateChromeMusCatalog()); |
| 215 #else |
193 service_manager::BackgroundServiceManager background_service_manager( | 216 service_manager::BackgroundServiceManager background_service_manager( |
194 &service_process_launcher_delegate, CreateChromeMashCatalog()); | 217 &service_process_launcher_delegate, CreateChromeMashCatalog()); |
| 218 #endif |
195 service_manager::mojom::ServicePtr service; | 219 service_manager::mojom::ServicePtr service; |
196 service_manager::ServiceContext context( | 220 service_manager::ServiceContext context( |
197 base::MakeUnique<mash::MashPackagedService>(), | 221 base::MakeUnique<mash::MashPackagedService>(), |
198 service_manager::mojom::ServiceRequest(&service)); | 222 service_manager::mojom::ServiceRequest(&service)); |
199 background_service_manager.RegisterService( | 223 background_service_manager.RegisterService( |
200 service_manager::Identity( | 224 service_manager::Identity( |
201 kChromeMashServiceName, service_manager::mojom::kRootUserID), | 225 is_mash ? kChromeMashServiceName : kChromeMusServiceName, |
| 226 service_manager::mojom::kRootUserID), |
202 std::move(service), nullptr); | 227 std::move(service), nullptr); |
203 | 228 |
204 // Quit the main process if an important child (e.g. window manager) dies. | 229 // Quit the main process if an important child (e.g. window manager) dies. |
205 // On Chrome OS the OS-level session_manager will restart the main process. | 230 // On Chrome OS the OS-level session_manager will restart the main process. |
206 base::RunLoop run_loop; | 231 base::RunLoop run_loop; |
207 int exit_value = 0; | 232 int exit_value = 0; |
208 background_service_manager.SetInstanceQuitCallback( | 233 background_service_manager.SetInstanceQuitCallback( |
209 base::Bind(&OnInstanceQuitInMain, &run_loop, &exit_value)); | 234 base::Bind(&OnInstanceQuitInMain, &run_loop, &exit_value)); |
210 | 235 |
211 #if defined(OS_POSIX) | 236 #if defined(OS_POSIX) |
212 // Quit the main process in response to shutdown signals (like SIGTERM). | 237 // Quit the main process in response to shutdown signals (like SIGTERM). |
213 // These signals are used by Linux distributions to request clean shutdown. | 238 // These signals are used by Linux distributions to request clean shutdown. |
214 // On Chrome OS the SIGTERM signal is sent by session_manager. | 239 // On Chrome OS the SIGTERM signal is sent by session_manager. |
215 InstallShutdownSignalHandlers(run_loop.QuitClosure(), | 240 InstallShutdownSignalHandlers(run_loop.QuitClosure(), |
216 base::ThreadTaskRunnerHandle::Get()); | 241 base::ThreadTaskRunnerHandle::Get()); |
217 #endif | 242 #endif |
218 | 243 |
219 // Ping services that we know we want to launch on startup (UI service, | 244 // Ping services that we know we want to launch on startup (UI service, |
220 // window manager, quick launch app). | 245 // window manager, quick launch app). |
221 context.connector()->Connect(ui::mojom::kServiceName); | 246 context.connector()->Connect(ui::mojom::kServiceName); |
222 context.connector()->Connect(mash::common::GetWindowManagerServiceName()); | |
223 context.connector()->Connect(mash::quick_launch::mojom::kServiceName); | |
224 context.connector()->Connect(content::mojom::kPackagedServicesServiceName); | 247 context.connector()->Connect(content::mojom::kPackagedServicesServiceName); |
| 248 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kMash)) { |
| 249 context.connector()->Connect(mash::common::GetWindowManagerServiceName()); |
| 250 context.connector()->Connect(mash::quick_launch::mojom::kServiceName); |
| 251 } |
225 | 252 |
226 run_loop.Run(); | 253 run_loop.Run(); |
227 | 254 |
228 // |context| must be destroyed before the message loop. | 255 // |context| must be destroyed before the message loop. |
229 return exit_value; | 256 return exit_value; |
230 } | 257 } |
231 | 258 |
232 int MashRunner::RunChild() { | 259 int MashRunner::RunChild() { |
233 service_manager::WaitForDebuggerIfNecessary(); | 260 service_manager::WaitForDebuggerIfNecessary(); |
234 | 261 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 command_line->GetSwitchValueASCII(switches::kWaitForDebugger)) { | 337 command_line->GetSwitchValueASCII(switches::kWaitForDebugger)) { |
311 return; | 338 return; |
312 } | 339 } |
313 | 340 |
314 // Include the pid as logging may not have been initialized yet (the pid | 341 // Include the pid as logging may not have been initialized yet (the pid |
315 // printed out by logging is wrong). | 342 // printed out by logging is wrong). |
316 LOG(WARNING) << "waiting for debugger to attach for service " << service_name | 343 LOG(WARNING) << "waiting for debugger to attach for service " << service_name |
317 << " pid=" << base::Process::Current().Pid(); | 344 << " pid=" << base::Process::Current().Pid(); |
318 base::debug::WaitForDebugger(120, true); | 345 base::debug::WaitForDebugger(120, true); |
319 } | 346 } |
OLD | NEW |