OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/service_manager.h" | 5 #include "services/service_manager/service_manager.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 29 matching lines...) Expand all Loading... |
40 namespace { | 40 namespace { |
41 | 41 |
42 const char kCapability_UserID[] = "service_manager:user_id"; | 42 const char kCapability_UserID[] = "service_manager:user_id"; |
43 const char kCapability_ClientProcess[] = "service_manager:client_process"; | 43 const char kCapability_ClientProcess[] = "service_manager:client_process"; |
44 const char kCapability_InstanceName[] = "service_manager:instance_name"; | 44 const char kCapability_InstanceName[] = "service_manager:instance_name"; |
45 const char kCapability_AllUsers[] = "service_manager:all_users"; | 45 const char kCapability_AllUsers[] = "service_manager:all_users"; |
46 const char kCapability_InstancePerChild[] = | 46 const char kCapability_InstancePerChild[] = |
47 "service_manager:instance_per_child"; | 47 "service_manager:instance_per_child"; |
48 const char kCapability_ServiceManager[] = "service_manager:service_manager"; | 48 const char kCapability_ServiceManager[] = "service_manager:service_manager"; |
49 | 49 |
50 bool Succeeded(mojom::ConnectResult result) { | |
51 return result == mojom::ConnectResult::SUCCEEDED; | |
52 } | |
53 | |
54 void RunCallback(ConnectParams* params, | |
55 mojom::ConnectResult result, | |
56 const std::string& user_id) { | |
57 if (!params->connect_callback().is_null()) { | |
58 params->connect_callback().Run(result, user_id); | |
59 return; | |
60 } | |
61 if (!params->bind_interface_callback().is_null()) | |
62 params->bind_interface_callback().Run(result, user_id); | |
63 } | |
64 | |
65 } // namespace | 50 } // namespace |
66 | 51 |
67 Identity CreateServiceManagerIdentity() { | 52 Identity CreateServiceManagerIdentity() { |
68 return Identity(service_manager::mojom::kServiceName, mojom::kRootUserID); | 53 return Identity(service_manager::mojom::kServiceName, mojom::kRootUserID); |
69 } | 54 } |
70 | 55 |
71 Identity CreateCatalogIdentity() { | 56 Identity CreateCatalogIdentity() { |
72 return Identity(catalog::mojom::kServiceName, mojom::kRootUserID); | 57 return Identity(catalog::mojom::kServiceName, mojom::kRootUserID); |
73 } | 58 } |
74 | 59 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 } else { | 118 } else { |
134 // Notify the ServiceManager that this Instance is really going away. | 119 // Notify the ServiceManager that this Instance is really going away. |
135 service_manager_->OnInstanceStopped(identity_); | 120 service_manager_->OnInstanceStopped(identity_); |
136 } | 121 } |
137 } | 122 } |
138 | 123 |
139 ~Instance() override { | 124 ~Instance() override { |
140 Stop(); | 125 Stop(); |
141 } | 126 } |
142 | 127 |
143 bool OnConnect(std::unique_ptr<ConnectParams>* in_params) { | 128 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { |
144 if (!service_.is_bound()) | 129 if (!service_.is_bound()) |
145 return false; | 130 return false; |
146 | 131 |
147 std::unique_ptr<ConnectParams> params(std::move(*in_params)); | 132 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); |
148 if (!params->connect_callback().is_null()) { | 133 if (!params->connect_callback().is_null()) { |
149 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | 134 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |
150 identity_.user_id()); | 135 identity_.user_id()); |
151 } | 136 } |
152 | 137 |
153 InterfaceProviderSpecMap specs; | 138 InterfaceProviderSpecMap specs; |
154 Instance* source = | 139 Instance* source = service_manager_->GetExistingInstance(params->source()); |
155 service_manager_->GetExistingInstance(params->source()); | |
156 if (source) | 140 if (source) |
157 specs = source->interface_provider_specs_; | 141 specs = source->interface_provider_specs_; |
158 | 142 |
159 pending_service_connections_++; | 143 pending_service_connections_++; |
160 service_->OnConnect(ServiceInfo(params->source(), specs), | 144 service_->OnConnect(ServiceInfo(params->source(), specs), |
161 params->TakeRemoteInterfaces(), | 145 params->TakeRemoteInterfaces(), |
162 base::Bind(&Instance::OnConnectComplete, | 146 base::Bind(&Instance::OnConnectComplete, |
163 base::Unretained(this))); | 147 base::Unretained(this))); |
164 return true; | 148 return true; |
165 } | 149 } |
166 | 150 |
167 bool OnBindInterface(std::unique_ptr<ConnectParams>* in_params) { | |
168 if (!service_.is_bound()) | |
169 return false; | |
170 | |
171 std::unique_ptr<ConnectParams> params(std::move(*in_params)); | |
172 InterfaceProviderSpecMap source_specs; | |
173 InterfaceProviderSpec source_connection_spec; | |
174 Instance* source = | |
175 service_manager_->GetExistingInstance(params->source()); | |
176 if (source) { | |
177 source_specs = source->interface_provider_specs_; | |
178 source_connection_spec = source->GetConnectionSpec(); | |
179 } | |
180 | |
181 InterfaceSet exposed = GetInterfacesToExpose(source_connection_spec, | |
182 identity_, | |
183 GetConnectionSpec()); | |
184 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) || | |
185 exposed.count(params->interface_name()) > 0; | |
186 if (!allowed) { | |
187 std::stringstream ss; | |
188 ss << "Connection InterfaceProviderSpec prevented service: " | |
189 << params->source().name() << " from binding interface: " | |
190 << params->interface_name() << " exposed by: " << identity_.name(); | |
191 LOG(ERROR) << ss.str(); | |
192 params->bind_interface_callback().Run(mojom::ConnectResult::ACCESS_DENIED, | |
193 identity_.user_id()); | |
194 return false; | |
195 } | |
196 | |
197 params->bind_interface_callback().Run(mojom::ConnectResult::SUCCEEDED, | |
198 identity_.user_id()); | |
199 | |
200 pending_service_connections_++; | |
201 service_->OnBindInterface( | |
202 ServiceInfo(params->source(), source_specs), | |
203 params->interface_name(), | |
204 params->TakeInterfaceRequestPipe(), | |
205 base::Bind(&Instance::OnConnectComplete, base::Unretained(this))); | |
206 return true; | |
207 } | |
208 | |
209 void OnConnectComplete() { | 151 void OnConnectComplete() { |
210 DCHECK_GT(pending_service_connections_, 0); | 152 DCHECK_GT(pending_service_connections_, 0); |
211 pending_service_connections_--; | 153 pending_service_connections_--; |
212 } | 154 } |
213 | 155 |
214 void StartWithService(mojom::ServicePtr service) { | 156 void StartWithService(mojom::ServicePtr service) { |
215 CHECK(!service_); | 157 CHECK(!service_); |
216 state_ = State::STARTING; | 158 state_ = State::STARTING; |
217 service_ = std::move(service); | 159 service_ = std::move(service); |
218 service_.set_connection_error_handler( | 160 service_.set_connection_error_handler( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 // The service was started but the service manager hasn't received the | 222 // The service was started but the service manager hasn't received the |
281 // initial response from it yet. | 223 // initial response from it yet. |
282 STARTING, | 224 STARTING, |
283 | 225 |
284 // The service was started successfully. | 226 // The service was started successfully. |
285 STARTED | 227 STARTED |
286 }; | 228 }; |
287 | 229 |
288 // mojom::Connector implementation: | 230 // mojom::Connector implementation: |
289 void StartService( | 231 void StartService( |
290 const Identity& in_target, | 232 const Identity& target, |
291 mojo::ScopedMessagePipeHandle service_handle, | 233 mojo::ScopedMessagePipeHandle service_handle, |
292 mojom::PIDReceiverRequest pid_receiver_request) override { | 234 mojom::PIDReceiverRequest pid_receiver_request) override { |
| 235 mojom::ServicePtr service; |
| 236 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); |
| 237 ConnectImpl( |
| 238 target, |
| 239 mojom::InterfaceProviderRequest(), |
| 240 std::move(service), |
| 241 std::move(pid_receiver_request), |
| 242 base::Bind( |
| 243 &service_manager::ServiceManager::Instance::EmptyConnectCallback, |
| 244 weak_factory_.GetWeakPtr())); |
| 245 } |
| 246 |
| 247 void Connect(const service_manager::Identity& target, |
| 248 mojom::InterfaceProviderRequest remote_interfaces, |
| 249 const ConnectCallback& callback) override { |
| 250 ConnectImpl(target, std::move(remote_interfaces), mojom::ServicePtr(), |
| 251 mojom::PIDReceiverRequest(), callback); |
| 252 } |
| 253 |
| 254 void BindInterface(const service_manager::Identity& target, |
| 255 const std::string& interface_name, |
| 256 mojo::ScopedMessagePipeHandle interface_pipe, |
| 257 const BindInterfaceCallback& callback) override { |
| 258 mojom::InterfaceProviderPtr remote_interfaces; |
| 259 ConnectImpl( |
| 260 target, |
| 261 MakeRequest(&remote_interfaces), |
| 262 mojom::ServicePtr(), |
| 263 mojom::PIDReceiverRequest(), |
| 264 base::Bind( |
| 265 &service_manager::ServiceManager::Instance::BindCallbackWrapper, |
| 266 weak_factory_.GetWeakPtr(), |
| 267 callback)); |
| 268 remote_interfaces->GetInterface(interface_name, std::move(interface_pipe)); |
| 269 // TODO(beng): Rather than just forwarding thru to InterfaceProvider, do |
| 270 // manifest policy intersection here. |
| 271 } |
| 272 |
| 273 void ConnectImpl(const service_manager::Identity& in_target, |
| 274 mojom::InterfaceProviderRequest remote_interfaces, |
| 275 mojom::ServicePtr service, |
| 276 mojom::PIDReceiverRequest pid_receiver_request, |
| 277 const ConnectCallback& callback) { |
293 Identity target = in_target; | 278 Identity target = in_target; |
294 mojom::ConnectResult result = | 279 if (target.user_id() == mojom::kInheritUserID) |
295 ValidateConnectParams(&target, nullptr, nullptr); | 280 target.set_user_id(identity_.user_id()); |
296 if (!Succeeded(result)) | 281 |
| 282 if (!ValidateIdentity(target, callback)) |
| 283 return; |
| 284 if (!ValidateClientProcessInfo(&service, &pid_receiver_request, target, |
| 285 callback)) { |
| 286 return; |
| 287 } |
| 288 if (!ValidateConnectionSpec(target, callback)) |
297 return; | 289 return; |
298 | 290 |
299 std::unique_ptr<ConnectParams> params(new ConnectParams); | 291 std::unique_ptr<ConnectParams> params(new ConnectParams); |
300 params->set_source(identity_); | 292 params->set_source(identity_); |
301 params->set_target(target); | 293 params->set_target(target); |
302 | 294 params->set_remote_interfaces(std::move(remote_interfaces)); |
303 mojom::ServicePtr service; | |
304 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); | |
305 params->set_client_process_info(std::move(service), | 295 params->set_client_process_info(std::move(service), |
306 std::move(pid_receiver_request)); | 296 std::move(pid_receiver_request)); |
307 service_manager_->Connect( | |
308 std::move(params), nullptr, weak_factory_.GetWeakPtr()); | |
309 } | |
310 | |
311 void Connect(const service_manager::Identity& in_target, | |
312 mojom::InterfaceProviderRequest remote_interfaces, | |
313 const ConnectCallback& callback) override { | |
314 Identity target = in_target; | |
315 mojom::ConnectResult result = | |
316 ValidateConnectParams(&target, nullptr, nullptr); | |
317 if (!Succeeded(result)) { | |
318 callback.Run(result, mojom::kInheritUserID); | |
319 return; | |
320 } | |
321 | |
322 std::unique_ptr<ConnectParams> params(new ConnectParams); | |
323 params->set_source(identity_); | |
324 params->set_target(target); | |
325 params->set_remote_interfaces(std::move(remote_interfaces)); | |
326 params->set_connect_callback(callback); | 297 params->set_connect_callback(callback); |
327 service_manager_->Connect( | 298 service_manager_->Connect( |
328 std::move(params), nullptr, weak_factory_.GetWeakPtr()); | 299 std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
329 } | 300 } |
330 | |
331 void BindInterface(const service_manager::Identity& in_target, | |
332 const std::string& interface_name, | |
333 mojo::ScopedMessagePipeHandle interface_pipe, | |
334 const BindInterfaceCallback& callback) override { | |
335 Identity target = in_target; | |
336 mojom::ConnectResult result = | |
337 ValidateConnectParams(&target, nullptr, nullptr); | |
338 if (!Succeeded(result)) { | |
339 callback.Run(result, mojom::kInheritUserID); | |
340 return; | |
341 } | |
342 | |
343 std::unique_ptr<ConnectParams> params(new ConnectParams); | |
344 params->set_source(identity_); | |
345 params->set_target(target); | |
346 params->set_interface_request_info(interface_name, | |
347 std::move(interface_pipe)); | |
348 params->set_bind_interface_callback(callback); | |
349 service_manager_->Connect( | |
350 std::move(params), nullptr, weak_factory_.GetWeakPtr()); | |
351 } | |
352 | 301 |
353 void Clone(mojom::ConnectorRequest request) override { | 302 void Clone(mojom::ConnectorRequest request) override { |
354 connectors_.AddBinding(this, std::move(request)); | 303 connectors_.AddBinding(this, std::move(request)); |
355 } | 304 } |
356 | 305 |
357 // mojom::PIDReceiver: | 306 // mojom::PIDReceiver: |
358 void SetPID(uint32_t pid) override { | 307 void SetPID(uint32_t pid) override { |
359 PIDAvailable(pid); | 308 PIDAvailable(pid); |
360 } | 309 } |
361 | 310 |
362 // InterfaceFactory<mojom::ServiceManager>: | 311 // InterfaceFactory<mojom::ServiceManager>: |
363 void Create(const Identity& remote_identity, | 312 void Create(const Identity& remote_identity, |
364 mojom::ServiceManagerRequest request) override { | 313 mojom::ServiceManagerRequest request) override { |
365 service_manager_bindings_.AddBinding(this, std::move(request)); | 314 service_manager_bindings_.AddBinding(this, std::move(request)); |
366 } | 315 } |
367 | 316 |
368 // mojom::ServiceManager implementation: | 317 // mojom::ServiceManager implementation: |
369 void AddListener(mojom::ServiceManagerListenerPtr listener) override { | 318 void AddListener(mojom::ServiceManagerListenerPtr listener) override { |
370 // TODO(beng): this should only track the instances matching this user, and | 319 // TODO(beng): this should only track the instances matching this user, and |
371 // root. | 320 // root. |
372 service_manager_->AddListener(std::move(listener)); | 321 service_manager_->AddListener(std::move(listener)); |
373 } | 322 } |
374 | 323 |
375 mojom::ConnectResult ValidateConnectParams( | 324 bool ValidateIdentity(const Identity& identity, |
376 Identity* target, | 325 const ConnectCallback& callback) { |
377 mojom::ServicePtr* service, | |
378 mojom::PIDReceiverRequest* pid_receiver_request) { | |
379 if (target->user_id() == mojom::kInheritUserID) | |
380 target->set_user_id(identity_.user_id()); | |
381 | |
382 mojom::ConnectResult result = ValidateIdentity(*target); | |
383 if (!Succeeded(result)) | |
384 return result; | |
385 | |
386 result = ValidateClientProcessInfo(service, pid_receiver_request, *target); | |
387 if (!Succeeded(result)) | |
388 return result; | |
389 return ValidateConnectionSpec(*target); | |
390 } | |
391 | |
392 mojom::ConnectResult ValidateIdentity(const Identity& identity) { | |
393 if (identity.name().empty()) { | 326 if (identity.name().empty()) { |
394 LOG(ERROR) << "Error: empty service name."; | 327 LOG(ERROR) << "Error: empty service name."; |
395 return mojom::ConnectResult::INVALID_ARGUMENT; | 328 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
| 329 mojom::kInheritUserID); |
| 330 return false; |
396 } | 331 } |
397 if (!base::IsValidGUID(identity.user_id())) { | 332 if (!base::IsValidGUID(identity.user_id())) { |
398 LOG(ERROR) << "Error: invalid user_id: " << identity.user_id(); | 333 LOG(ERROR) << "Error: invalid user_id: " << identity.user_id(); |
399 return mojom::ConnectResult::INVALID_ARGUMENT; | 334 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
| 335 mojom::kInheritUserID); |
| 336 return false; |
400 } | 337 } |
401 return mojom::ConnectResult::SUCCEEDED; | 338 return true; |
402 } | 339 } |
403 | 340 |
404 mojom::ConnectResult ValidateClientProcessInfo( | 341 bool ValidateClientProcessInfo( |
405 mojom::ServicePtr* service, | 342 mojom::ServicePtr* service, |
406 mojom::PIDReceiverRequest* pid_receiver_request, | 343 mojom::PIDReceiverRequest* pid_receiver_request, |
407 const Identity& target) { | 344 const Identity& target, |
408 if (service && pid_receiver_request && | 345 const ConnectCallback& callback) { |
409 (service->is_bound() || pid_receiver_request->is_pending())) { | 346 if (service->is_bound() || pid_receiver_request->is_pending()) { |
410 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { | 347 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { |
411 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " | 348 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " |
412 << "to register an instance for a process it created for " | 349 << "to register an instance for a process it created for " |
413 << "target: " << target.name() << " without the " | 350 << "target: " << target.name() << " without the " |
414 << "service_manager{client_process} capability " | 351 << "service_manager{client_process} capability " |
415 << "class."; | 352 << "class."; |
416 return mojom::ConnectResult::ACCESS_DENIED; | 353 callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
| 354 mojom::kInheritUserID); |
| 355 return false; |
417 } | 356 } |
418 | 357 |
419 if (!service->is_bound() || !pid_receiver_request->is_pending()) { | 358 if (!service->is_bound() || !pid_receiver_request->is_pending()) { |
420 LOG(ERROR) << "Must supply both service AND " | 359 LOG(ERROR) << "Must supply both service AND " |
421 << "pid_receiver_request when sending client process info"; | 360 << "pid_receiver_request when sending client process info"; |
422 return mojom::ConnectResult::INVALID_ARGUMENT; | 361 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
| 362 mojom::kInheritUserID); |
| 363 return false; |
423 } | 364 } |
424 if (service_manager_->GetExistingInstance(target)) { | 365 if (service_manager_->GetExistingInstance(target)) { |
425 LOG(ERROR) << "Cannot client process matching existing identity:" | 366 LOG(ERROR) << "Cannot client process matching existing identity:" |
426 << "Name: " << target.name() << " User: " | 367 << "Name: " << target.name() << " User: " |
427 << target.user_id() << " Instance: " << target.instance(); | 368 << target.user_id() << " Instance: " << target.instance(); |
428 return mojom::ConnectResult::INVALID_ARGUMENT; | 369 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
| 370 mojom::kInheritUserID); |
| 371 return false; |
429 } | 372 } |
430 } | 373 } |
431 return mojom::ConnectResult::SUCCEEDED; | 374 return true; |
432 } | 375 } |
433 | 376 |
434 mojom::ConnectResult ValidateConnectionSpec(const Identity& target) { | 377 bool ValidateConnectionSpec(const Identity& target, |
| 378 const ConnectCallback& callback) { |
435 InterfaceProviderSpec connection_spec = GetConnectionSpec(); | 379 InterfaceProviderSpec connection_spec = GetConnectionSpec(); |
436 // TODO(beng): Need to do the following additional policy validation of | 380 // TODO(beng): Need to do the following additional policy validation of |
437 // whether this instance is allowed to connect using: | 381 // whether this instance is allowed to connect using: |
438 // - non-null client process info. | 382 // - non-null client process info. |
439 if (target.user_id() != identity_.user_id() && | 383 if (target.user_id() != identity_.user_id() && |
440 target.user_id() != mojom::kRootUserID && | 384 target.user_id() != mojom::kRootUserID && |
441 !HasCapability(connection_spec, kCapability_UserID)) { | 385 !HasCapability(connection_spec, kCapability_UserID)) { |
442 LOG(ERROR) << "Instance: " << identity_.name() | 386 LOG(ERROR) << "Instance: " << identity_.name() |
443 << " running as: " << identity_.user_id() | 387 << " running as: " << identity_.user_id() |
444 << " attempting to connect to: " << target.name() | 388 << " attempting to connect to: " << target.name() |
445 << " as: " << target.user_id() << " without " | 389 << " as: " << target.user_id() << " without " |
446 << " the service:service_manager{user_id} capability."; | 390 << " the service:service_manager{user_id} capability."; |
447 return mojom::ConnectResult::ACCESS_DENIED; | 391 callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
| 392 mojom::kInheritUserID); |
| 393 return false; |
448 } | 394 } |
449 if (!target.instance().empty() && | 395 if (!target.instance().empty() && |
450 target.instance() != target.name() && | 396 target.instance() != target.name() && |
451 !HasCapability(connection_spec, kCapability_InstanceName)) { | 397 !HasCapability(connection_spec, kCapability_InstanceName)) { |
452 LOG(ERROR) << "Instance: " << identity_.name() << " attempting to " | 398 LOG(ERROR) << "Instance: " << identity_.name() << " attempting to " |
453 << "connect to " << target.name() | 399 << "connect to " << target.name() |
454 << " using Instance name: " << target.instance() | 400 << " using Instance name: " << target.instance() |
455 << " without the " | 401 << " without the " |
456 << "service_manager{instance_name} capability."; | 402 << "service_manager{instance_name} capability."; |
457 return mojom::ConnectResult::ACCESS_DENIED; | 403 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); |
| 404 return false; |
458 } | 405 } |
459 | 406 |
460 if (allow_any_application_ || | 407 if (allow_any_application_ || |
461 connection_spec.requires.find(target.name()) != | 408 connection_spec.requires.find(target.name()) != |
462 connection_spec.requires.end()) { | 409 connection_spec.requires.end()) { |
463 return mojom::ConnectResult::SUCCEEDED; | 410 return true; |
464 } | 411 } |
465 LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " | 412 LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " |
466 << identity_.name() << " to: " << target.name(); | 413 << identity_.name() << " to: " << target.name(); |
467 return mojom::ConnectResult::ACCESS_DENIED; | 414 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); |
| 415 return false; |
468 } | 416 } |
469 | 417 |
470 uint32_t GenerateUniqueID() const { | 418 uint32_t GenerateUniqueID() const { |
471 static uint32_t id = mojom::kInvalidInstanceID; | 419 static uint32_t id = mojom::kInvalidInstanceID; |
472 ++id; | 420 ++id; |
473 CHECK_NE(mojom::kInvalidInstanceID, id); | 421 CHECK_NE(mojom::kInvalidInstanceID, id); |
474 return id; | 422 return id; |
475 } | 423 } |
476 | 424 |
477 void PIDAvailable(base::ProcessId pid) { | 425 void PIDAvailable(base::ProcessId pid) { |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) { | 775 void ServiceManager::NotifyServiceFailedToStart(const Identity& identity) { |
828 listeners_.ForAllPtrs( | 776 listeners_.ForAllPtrs( |
829 [identity](mojom::ServiceManagerListener* listener) { | 777 [identity](mojom::ServiceManagerListener* listener) { |
830 listener->OnServiceFailedToStart(identity); | 778 listener->OnServiceFailedToStart(identity); |
831 }); | 779 }); |
832 } | 780 } |
833 | 781 |
834 bool ServiceManager::ConnectToExistingInstance( | 782 bool ServiceManager::ConnectToExistingInstance( |
835 std::unique_ptr<ConnectParams>* params) { | 783 std::unique_ptr<ConnectParams>* params) { |
836 Instance* instance = GetExistingInstance((*params)->target()); | 784 Instance* instance = GetExistingInstance((*params)->target()); |
837 if (instance) { | 785 return instance && instance->ConnectToService(params); |
838 if ((*params)->HasInterfaceRequestInfo()) { | |
839 instance->OnBindInterface(params); | |
840 return true; | |
841 } | |
842 return instance->OnConnect(params); | |
843 } | |
844 return false; | |
845 } | 786 } |
846 | 787 |
847 ServiceManager::Instance* ServiceManager::CreateInstance( | 788 ServiceManager::Instance* ServiceManager::CreateInstance( |
848 const Identity& source, | 789 const Identity& source, |
849 const Identity& target, | 790 const Identity& target, |
850 const InterfaceProviderSpecMap& specs) { | 791 const InterfaceProviderSpecMap& specs) { |
851 CHECK(target.user_id() != mojom::kInheritUserID); | 792 CHECK(target.user_id() != mojom::kInheritUserID); |
852 | 793 |
853 auto instance = base::MakeUnique<Instance>(this, target, specs); | 794 auto instance = base::MakeUnique<Instance>(this, target, specs); |
854 Instance* raw_instance = instance.get(); | 795 Instance* raw_instance = instance.get(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 mojom::ResolveResultPtr result, | 861 mojom::ResolveResultPtr result, |
921 mojom::ResolveResultPtr parent) { | 862 mojom::ResolveResultPtr parent) { |
922 // If this request was originated by a specific Instance and that Instance is | 863 // If this request was originated by a specific Instance and that Instance is |
923 // no longer around, we ignore this response. | 864 // no longer around, we ignore this response. |
924 if (has_source_instance && !source_instance) | 865 if (has_source_instance && !source_instance) |
925 return; | 866 return; |
926 | 867 |
927 // If name resolution failed, we drop the connection. | 868 // If name resolution failed, we drop the connection. |
928 if (!result) { | 869 if (!result) { |
929 LOG(ERROR) << "Failed to resolve service name: " << params->target().name(); | 870 LOG(ERROR) << "Failed to resolve service name: " << params->target().name(); |
930 RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); | 871 if (!params->connect_callback().is_null()) { |
| 872 params->connect_callback().Run( |
| 873 mojom::ConnectResult::INVALID_ARGUMENT, ""); |
| 874 } |
931 return; | 875 return; |
932 } | 876 } |
933 | 877 |
934 std::string instance_name = params->target().instance(); | 878 std::string instance_name = params->target().instance(); |
935 | 879 |
936 // |result->interface_provider_specs| can be empty when there is no manifest. | 880 // |result->interface_provider_specs| can be empty when there is no manifest. |
937 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); | 881 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); |
938 auto it = result->interface_provider_specs.find( | 882 auto it = result->interface_provider_specs.find( |
939 mojom::kServiceManager_ConnectorSpec); | 883 mojom::kServiceManager_ConnectorSpec); |
940 if (it != result->interface_provider_specs.end()) | 884 if (it != result->interface_provider_specs.end()) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 mojom::ServiceRequest request(&service); | 934 mojom::ServiceRequest request(&service); |
991 | 935 |
992 // The catalog was unable to read a manifest for this service. We can't do | 936 // The catalog was unable to read a manifest for this service. We can't do |
993 // anything more. | 937 // anything more. |
994 // TODO(beng): There may be some cases where it's valid to have an empty | 938 // TODO(beng): There may be some cases where it's valid to have an empty |
995 // spec, so we should probably include a return value in |result|. | 939 // spec, so we should probably include a return value in |result|. |
996 if (result->interface_provider_specs.empty()) { | 940 if (result->interface_provider_specs.empty()) { |
997 LOG(ERROR) | 941 LOG(ERROR) |
998 << "Error: The catalog was unable to read a manifest for service \"" | 942 << "Error: The catalog was unable to read a manifest for service \"" |
999 << result->name << "\"."; | 943 << result->name << "\"."; |
1000 RunCallback(params.get(), mojom::ConnectResult::ACCESS_DENIED, ""); | 944 if (!params->connect_callback().is_null()) |
| 945 params->connect_callback().Run(mojom::ConnectResult::ACCESS_DENIED, ""); |
1001 return; | 946 return; |
1002 } | 947 } |
1003 | 948 |
1004 if (parent) { | 949 if (parent) { |
1005 // This service is provided by another service via a ServiceFactory. | 950 // This service is provided by another service via a ServiceFactory. |
1006 std::string target_user_id = target.user_id(); | 951 std::string target_user_id = target.user_id(); |
1007 std::string factory_instance_name = instance_name; | 952 std::string factory_instance_name = instance_name; |
1008 | 953 |
1009 auto spec_iter = parent->interface_provider_specs.find( | 954 auto spec_iter = parent->interface_provider_specs.find( |
1010 mojom::kServiceManager_ConnectorSpec); | 955 mojom::kServiceManager_ConnectorSpec); |
(...skipping 17 matching lines...) Expand all Loading... |
1028 } else { | 973 } else { |
1029 base::FilePath package_path; | 974 base::FilePath package_path; |
1030 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( | 975 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( |
1031 target.name(), &package_path)) { | 976 target.name(), &package_path)) { |
1032 package_path = result->package_path; | 977 package_path = result->package_path; |
1033 } | 978 } |
1034 DCHECK(!package_path.empty()); | 979 DCHECK(!package_path.empty()); |
1035 | 980 |
1036 if (!instance->StartWithFilePath(package_path)) { | 981 if (!instance->StartWithFilePath(package_path)) { |
1037 OnInstanceError(instance); | 982 OnInstanceError(instance); |
1038 RunCallback(params.get(), mojom::ConnectResult::INVALID_ARGUMENT, ""); | 983 if (!params->connect_callback().is_null()) { |
| 984 params->connect_callback().Run( |
| 985 mojom::ConnectResult::INVALID_ARGUMENT, ""); |
| 986 } |
1039 return; | 987 return; |
1040 } | 988 } |
1041 } | 989 } |
1042 } | 990 } |
1043 | 991 |
1044 // Now that the instance has a Service, we can connect to it. | 992 // Now that the instance has a Service, we can connect to it. |
1045 if (params->HasInterfaceRequestInfo()) { | 993 bool connected = instance->ConnectToService(¶ms); |
1046 instance->OnBindInterface(¶ms); | 994 DCHECK(connected); |
1047 } else { | |
1048 bool connected = instance->OnConnect(¶ms); | |
1049 DCHECK(connected); | |
1050 } | |
1051 } | 995 } |
1052 | 996 |
1053 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { | 997 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |
1054 return weak_ptr_factory_.GetWeakPtr(); | 998 return weak_ptr_factory_.GetWeakPtr(); |
1055 } | 999 } |
1056 | 1000 |
1057 } // namespace service_manager | 1001 } // namespace service_manager |
OLD | NEW |