| 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 |