Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: services/service_manager/standalone/context.cc

Issue 2645973006: [Service Manager] Get rid of dynamic service discovery (Closed)
Patch Set: . Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « services/service_manager/standalone/context.h ('k') | services/service_manager/tests/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "services/service_manager/standalone/context.h" 5 #include "services/service_manager/standalone/context.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/json/json_file_value_serializer.h" 16 #include "base/json/json_file_value_serializer.h"
17 #include "base/lazy_instance.h"
18 #include "base/location.h"
19 #include "base/macros.h" 17 #include "base/macros.h"
20 #include "base/memory/ptr_util.h" 18 #include "base/memory/ptr_util.h"
21 #include "base/path_service.h" 19 #include "base/path_service.h"
22 #include "base/process/process_info.h" 20 #include "base/process/process_info.h"
23 #include "base/run_loop.h"
24 #include "base/single_thread_task_runner.h"
25 #include "base/strings/string_number_conversions.h" 21 #include "base/strings/string_number_conversions.h"
26 #include "base/strings/string_split.h" 22 #include "base/strings/string_split.h"
27 #include "base/strings/string_util.h" 23 #include "base/strings/string_util.h"
28 #include "base/strings/utf_string_conversions.h" 24 #include "base/strings/utf_string_conversions.h"
29 #include "base/threading/sequenced_worker_pool.h" 25 #include "base/threading/sequenced_worker_pool.h"
30 #include "base/threading/thread_task_runner_handle.h"
31 #include "base/trace_event/trace_event.h" 26 #include "base/trace_event/trace_event.h"
32 #include "build/build_config.h" 27 #include "build/build_config.h"
33 #include "components/tracing/common/tracing_switches.h" 28 #include "components/tracing/common/tracing_switches.h"
34 #include "mojo/edk/embedder/embedder.h"
35 #include "mojo/public/cpp/bindings/strong_binding.h"
36 #include "services/catalog/catalog.h" 29 #include "services/catalog/catalog.h"
37 #include "services/catalog/store.h"
38 #include "services/service_manager/connect_params.h" 30 #include "services/service_manager/connect_params.h"
39 #include "services/service_manager/connect_util.h" 31 #include "services/service_manager/connect_util.h"
40 #include "services/service_manager/runner/common/switches.h" 32 #include "services/service_manager/runner/common/switches.h"
41 #include "services/service_manager/runner/host/service_process_launcher.h" 33 #include "services/service_manager/runner/host/service_process_launcher.h"
34 #include "services/service_manager/service_manager.h"
42 #include "services/service_manager/standalone/tracer.h" 35 #include "services/service_manager/standalone/tracer.h"
43 #include "services/service_manager/switches.h" 36 #include "services/service_manager/switches.h"
44 #include "services/tracing/public/cpp/provider.h" 37 #include "services/tracing/public/cpp/provider.h"
45 #include "services/tracing/public/cpp/switches.h" 38 #include "services/tracing/public/cpp/switches.h"
46 #include "services/tracing/public/interfaces/constants.mojom.h" 39 #include "services/tracing/public/interfaces/constants.mojom.h"
47 #include "services/tracing/public/interfaces/tracing.mojom.h" 40 #include "services/tracing/public/interfaces/tracing.mojom.h"
48 41
49 #if defined(OS_MACOSX) 42 #if defined(OS_MACOSX)
50 #include "services/service_manager/public/cpp/standalone_service/mach_broker.h" 43 #include "services/service_manager/public/cpp/standalone_service/mach_broker.h"
51 #endif 44 #endif
52 45
46 namespace base {
47 class TaskRunner;
48 }
49
53 namespace service_manager { 50 namespace service_manager {
54 namespace { 51 namespace {
55 52
56 base::FilePath::StringType GetPathFromCommandLineSwitch(
57 const base::StringPiece& value) {
58 #if defined(OS_POSIX)
59 return value.as_string();
60 #elif defined(OS_WIN)
61 return base::UTF8ToUTF16(value);
62 #endif // OS_POSIX
63 }
64
65 // Used to ensure we only init once. 53 // Used to ensure we only init once.
66 class Setup {
67 public:
68 Setup() { mojo::edk::Init(); }
69
70 ~Setup() {}
71
72 private:
73 DISALLOW_COPY_AND_ASSIGN(Setup);
74 };
75
76 class ServiceProcessLauncherFactoryImpl : public ServiceProcessLauncherFactory { 54 class ServiceProcessLauncherFactoryImpl : public ServiceProcessLauncherFactory {
77 public: 55 public:
78 ServiceProcessLauncherFactoryImpl(base::TaskRunner* launch_process_runner, 56 ServiceProcessLauncherFactoryImpl(base::TaskRunner* launch_process_runner,
79 ServiceProcessLauncher::Delegate* delegate) 57 ServiceProcessLauncher::Delegate* delegate)
80 : launch_process_runner_(launch_process_runner), 58 : launch_process_runner_(launch_process_runner),
81 delegate_(delegate) { 59 delegate_(delegate) {
82 } 60 }
83 61
84 private: 62 private:
85 std::unique_ptr<ServiceProcessLauncher> Create( 63 std::unique_ptr<ServiceProcessLauncher> Create(
86 const base::FilePath& service_path) override { 64 const base::FilePath& service_path) override {
87 return base::MakeUnique<ServiceProcessLauncher>( 65 return base::MakeUnique<ServiceProcessLauncher>(
88 launch_process_runner_, delegate_, service_path); 66 launch_process_runner_, delegate_, service_path);
89 } 67 }
90 68
91 base::TaskRunner* launch_process_runner_; 69 base::TaskRunner* launch_process_runner_;
92 ServiceProcessLauncher::Delegate* delegate_; 70 ServiceProcessLauncher::Delegate* delegate_;
93 }; 71 };
94 72
95 std::unique_ptr<base::Thread> CreateIOThread(const char* name) {
96 std::unique_ptr<base::Thread> thread(new base::Thread(name));
97 base::Thread::Options options;
98 options.message_loop_type = base::MessageLoop::TYPE_IO;
99 thread->StartWithOptions(options);
100 return thread;
101 }
102
103 void OnInstanceQuit(const std::string& name, const Identity& identity) { 73 void OnInstanceQuit(const std::string& name, const Identity& identity) {
104 if (name == identity.name()) 74 if (name == identity.name())
105 base::MessageLoop::current()->QuitWhenIdle(); 75 base::MessageLoop::current()->QuitWhenIdle();
106 } 76 }
107 77
108 const char kService[] = "service"; 78 const char kService[] = "service";
109 79
110 } // namespace 80 } // namespace
111 81
112 Context::InitParams::InitParams() {} 82 Context::Context(
113 Context::InitParams::~InitParams() {} 83 ServiceProcessLauncher::Delegate* service_process_launcher_delegate,
114 84 std::unique_ptr<base::Value> catalog_contents)
115 Context::Context() 85 : main_entry_time_(base::Time::Now()) {
116 : io_thread_(CreateIOThread("io_thread")), 86 TRACE_EVENT0("service_manager", "Context::Context");
117 main_entry_time_(base::Time::Now()) {}
118
119 Context::~Context() {
120 DCHECK(!base::MessageLoop::current());
121 blocking_pool_->Shutdown();
122 }
123
124 // static
125 void Context::EnsureEmbedderIsInitialized() {
126 static base::LazyInstance<Setup>::Leaky setup = LAZY_INSTANCE_INITIALIZER;
127 setup.Get();
128 }
129
130 void Context::Init(std::unique_ptr<InitParams> init_params) {
131 TRACE_EVENT0("service_manager", "Context::Init");
132 const base::CommandLine& command_line = 87 const base::CommandLine& command_line =
133 *base::CommandLine::ForCurrentProcess(); 88 *base::CommandLine::ForCurrentProcess();
134 89
135 bool trace_startup = command_line.HasSwitch(::switches::kTraceStartup); 90 bool trace_startup = command_line.HasSwitch(::switches::kTraceStartup);
136 if (trace_startup) { 91 if (trace_startup) {
137 tracer_.Start( 92 tracer_.Start(
138 command_line.GetSwitchValueASCII(::switches::kTraceStartup), 93 command_line.GetSwitchValueASCII(::switches::kTraceStartup),
139 command_line.GetSwitchValueASCII(::switches::kTraceStartupDuration), 94 command_line.GetSwitchValueASCII(::switches::kTraceStartupDuration),
140 "mojo_runner.trace"); 95 "mojo_runner.trace");
141 } 96 }
142 97
143 if (!init_params || init_params->init_edk)
144 EnsureEmbedderIsInitialized();
145
146 service_manager_runner_ = base::ThreadTaskRunnerHandle::Get();
147 blocking_pool_ = new base::SequencedWorkerPool( 98 blocking_pool_ = new base::SequencedWorkerPool(
148 kThreadPoolMaxThreads, "blocking_pool", base::TaskPriority::USER_VISIBLE); 99 kThreadPoolMaxThreads, "blocking_pool", base::TaskPriority::USER_VISIBLE);
149 100
150 init_edk_ = !init_params || init_params->init_edk;
151 if (init_edk_) {
152 mojo::edk::InitIPCSupport(io_thread_->task_runner().get());
153 #if defined(OS_MACOSX)
154 mojo::edk::SetMachPortProvider(MachBroker::GetInstance()->port_provider());
155 #endif
156 }
157
158 std::unique_ptr<ServiceProcessLauncherFactory> 101 std::unique_ptr<ServiceProcessLauncherFactory>
159 service_process_launcher_factory = 102 service_process_launcher_factory =
160 base::MakeUnique<ServiceProcessLauncherFactoryImpl>( 103 base::MakeUnique<ServiceProcessLauncherFactoryImpl>(
161 blocking_pool_.get(), 104 blocking_pool_.get(),
162 init_params ? init_params->service_process_launcher_delegate 105 service_process_launcher_delegate);
163 : nullptr); 106 catalog_.reset(new catalog::Catalog(std::move(catalog_contents)));
164 if (init_params && init_params->static_catalog) {
165 catalog_.reset(
166 new catalog::Catalog(std::move(init_params->static_catalog)));
167 } else {
168 catalog_.reset(
169 new catalog::Catalog(blocking_pool_.get(), nullptr));
170 }
171 service_manager_.reset( 107 service_manager_.reset(
172 new ServiceManager(std::move(service_process_launcher_factory), 108 new ServiceManager(std::move(service_process_launcher_factory),
173 catalog_->TakeService())); 109 catalog_->TakeService()));
174 110
175 if (command_line.HasSwitch(::switches::kServiceOverrides)) {
176 base::FilePath overrides_file(GetPathFromCommandLineSwitch(
177 command_line.GetSwitchValueASCII(::switches::kServiceOverrides)));
178 JSONFileValueDeserializer deserializer(overrides_file);
179 int error = 0;
180 std::string message;
181 std::unique_ptr<base::Value> contents =
182 deserializer.Deserialize(&error, &message);
183 if (!contents) {
184 LOG(ERROR) << "Failed to parse service overrides file: " << message;
185 } else {
186 std::unique_ptr<ServiceOverrides> service_overrides =
187 base::MakeUnique<ServiceOverrides>(std::move(contents));
188 for (const auto& iter : service_overrides->entries()) {
189 if (!iter.second.package_name.empty())
190 catalog_->OverridePackageName(iter.first, iter.second.package_name);
191 }
192 service_manager_->SetServiceOverrides(std::move(service_overrides));
193 }
194 }
195
196 bool enable_stats_collection_bindings = 111 bool enable_stats_collection_bindings =
197 command_line.HasSwitch(tracing::kEnableStatsCollectionBindings); 112 command_line.HasSwitch(tracing::kEnableStatsCollectionBindings);
198 113
199 if (enable_stats_collection_bindings || 114 if (enable_stats_collection_bindings ||
200 command_line.HasSwitch(switches::kEnableTracing)) { 115 command_line.HasSwitch(switches::kEnableTracing)) {
201 Identity source_identity = CreateServiceManagerIdentity(); 116 Identity source_identity = CreateServiceManagerIdentity();
202 Identity tracing_identity(tracing::mojom::kServiceName, mojom::kRootUserID); 117 Identity tracing_identity(tracing::mojom::kServiceName, mojom::kRootUserID);
203 tracing::mojom::FactoryPtr factory; 118 tracing::mojom::FactoryPtr factory;
204 BindInterface(service_manager(), source_identity, tracing_identity, 119 BindInterface(service_manager(), source_identity, tracing_identity,
205 &factory); 120 &factory);
(...skipping 16 matching lines...) Expand all
222 const base::Time creation_time = base::CurrentProcessInfo::CreationTime(); 137 const base::Time creation_time = base::CurrentProcessInfo::CreationTime();
223 collector->SetServiceManagerProcessCreationTime( 138 collector->SetServiceManagerProcessCreationTime(
224 creation_time.ToInternalValue()); 139 creation_time.ToInternalValue());
225 #endif 140 #endif
226 collector->SetServiceManagerMainEntryPointTime( 141 collector->SetServiceManagerMainEntryPointTime(
227 main_entry_time_.ToInternalValue()); 142 main_entry_time_.ToInternalValue());
228 } 143 }
229 } 144 }
230 } 145 }
231 146
232 void Context::Shutdown() { 147 Context::~Context() { blocking_pool_->Shutdown(); }
233 // Actions triggered by Service Manager's destructor may require a current
234 // message loop,
235 // so we should destruct it explicitly now as ~Context() occurs post message
236 // loop shutdown.
237 service_manager_.reset();
238
239 DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(), service_manager_runner_);
240
241 // If we didn't initialize the edk we should not shut it down.
242 if (!init_edk_)
243 return;
244
245 TRACE_EVENT0("service_manager", "Context::Shutdown");
246 mojo::edk::ShutdownIPCSupport(
247 base::Bind(IgnoreResult(&base::TaskRunner::PostTask),
248 base::ThreadTaskRunnerHandle::Get(), FROM_HERE,
249 base::Bind(&Context::OnShutdownComplete,
250 base::Unretained(this))));
251 // We'll quit when we get OnShutdownComplete().
252 base::RunLoop().Run();
253 }
254
255 void Context::OnShutdownComplete() {
256 DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(), service_manager_runner_);
257 base::MessageLoop::current()->QuitWhenIdle();
258 }
259 148
260 void Context::RunCommandLineApplication() { 149 void Context::RunCommandLineApplication() {
261 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 150 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
262 if (command_line->HasSwitch(kService)) 151 if (command_line->HasSwitch(kService))
263 Run(command_line->GetSwitchValueASCII(kService)); 152 Run(command_line->GetSwitchValueASCII(kService));
264 } 153 }
265 154
266 void Context::Run(const std::string& name) { 155 void Context::Run(const std::string& name) {
267 service_manager_->SetInstanceQuitCallback(base::Bind(&OnInstanceQuit, name)); 156 service_manager_->SetInstanceQuitCallback(base::Bind(&OnInstanceQuit, name));
268 157
269 mojom::InterfaceProviderPtr remote_interfaces; 158 mojom::InterfaceProviderPtr remote_interfaces;
270 mojom::InterfaceProviderPtr local_interfaces; 159 mojom::InterfaceProviderPtr local_interfaces;
271 160
272 std::unique_ptr<ConnectParams> params(new ConnectParams); 161 std::unique_ptr<ConnectParams> params(new ConnectParams);
273 params->set_source(CreateServiceManagerIdentity()); 162 params->set_source(CreateServiceManagerIdentity());
274 params->set_target(Identity(name, mojom::kRootUserID)); 163 params->set_target(Identity(name, mojom::kRootUserID));
275 params->set_remote_interfaces(mojo::MakeRequest(&remote_interfaces)); 164 params->set_remote_interfaces(mojo::MakeRequest(&remote_interfaces));
276 service_manager_->Connect(std::move(params)); 165 service_manager_->Connect(std::move(params));
277 } 166 }
278 167
279 } // namespace service_manager 168 } // namespace service_manager
OLDNEW
« no previous file with comments | « services/service_manager/standalone/context.h ('k') | services/service_manager/tests/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698