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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 // Service Manager. | 111 // Service Manager. |
112 class ServiceManager::Instance | 112 class ServiceManager::Instance |
113 : public mojom::Connector, | 113 : public mojom::Connector, |
114 public mojom::PIDReceiver, | 114 public mojom::PIDReceiver, |
115 public Service, | 115 public Service, |
116 public InterfaceFactory<mojom::ServiceManager>, | 116 public InterfaceFactory<mojom::ServiceManager>, |
117 public mojom::ServiceManager { | 117 public mojom::ServiceManager { |
118 public: | 118 public: |
119 Instance(service_manager::ServiceManager* service_manager, | 119 Instance(service_manager::ServiceManager* service_manager, |
120 const Identity& identity, | 120 const Identity& identity, |
121 const InterfaceProviderSpec& connection_spec) | 121 const InterfaceProviderSpecMap& interface_provider_specs) |
122 : service_manager_(service_manager), | 122 : service_manager_(service_manager), |
123 id_(GenerateUniqueID()), | 123 id_(GenerateUniqueID()), |
124 identity_(identity), | 124 identity_(identity), |
125 connection_spec_(connection_spec), | 125 interface_provider_specs_(interface_provider_specs), |
126 allow_any_application_(connection_spec.requires.count("*") == 1), | 126 allow_any_application_(GetConnectionSpec().requires.count("*") == 1), |
127 pid_receiver_binding_(this), | 127 pid_receiver_binding_(this), |
128 weak_factory_(this) { | 128 weak_factory_(this) { |
129 if (identity_.name() == kServiceManagerName || | 129 if (identity_.name() == kServiceManagerName || |
130 identity_.name() == kCatalogName) { | 130 identity_.name() == kCatalogName) { |
131 pid_ = base::Process::Current().Pid(); | 131 pid_ = base::Process::Current().Pid(); |
132 } | 132 } |
133 DCHECK_NE(mojom::kInvalidInstanceID, id_); | 133 DCHECK_NE(mojom::kInvalidInstanceID, id_); |
134 } | 134 } |
135 | 135 |
136 ~Instance() override { | 136 ~Instance() override { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { | 170 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { |
171 if (!service_.is_bound()) | 171 if (!service_.is_bound()) |
172 return false; | 172 return false; |
173 | 173 |
174 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); | 174 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); |
175 if (!params->connect_callback().is_null()) { | 175 if (!params->connect_callback().is_null()) { |
176 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | 176 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |
177 identity_.user_id()); | 177 identity_.user_id()); |
178 } | 178 } |
179 | 179 |
| 180 InterfaceProviderSpec connection_spec = GetConnectionSpec(); |
180 CapabilitySet capabilities; | 181 CapabilitySet capabilities; |
181 InterfaceSet interfaces; | 182 InterfaceSet interfaces; |
182 Instance* source = service_manager_->GetExistingInstance(params->source()); | 183 Instance* source = service_manager_->GetExistingInstance(params->source()); |
183 if (source) { | 184 if (source) { |
184 GetCapabilitiesAndInterfacesForConnection(source->connection_spec_, | 185 GetCapabilitiesAndInterfacesForConnection(source->GetConnectionSpec(), |
185 identity_, connection_spec_, | 186 identity_, connection_spec, |
186 &capabilities, &interfaces); | 187 &capabilities, &interfaces); |
187 } else { | 188 } else { |
188 interfaces.insert("*"); | 189 interfaces.insert("*"); |
189 } | 190 } |
190 | 191 |
191 // The target has specified that sources must request one of its provided | 192 // The target has specified that sources must request one of its provided |
192 // classes instead of specifying a wild-card for interfaces. | 193 // classes instead of specifying a wild-card for interfaces. |
193 if (HasCapability(connection_spec_, kCapability_ExplicitClass) && | 194 if (HasCapability(connection_spec, kCapability_ExplicitClass) && |
194 (interfaces.count("*") != 0)) { | 195 (interfaces.count("*") != 0)) { |
195 interfaces.erase("*"); | 196 interfaces.erase("*"); |
196 } | 197 } |
197 | 198 |
198 service_->OnConnect(params->source(), params->TakeRemoteInterfaces(), | 199 InterfaceProviderSpecMap specs; |
199 interfaces, capabilities); | 200 if (source) |
| 201 specs = source->interface_provider_specs_; |
| 202 service_->OnConnect(ServiceInfo(params->source(), specs), |
| 203 params->TakeRemoteInterfaces(), interfaces, |
| 204 capabilities); |
200 return true; | 205 return true; |
201 } | 206 } |
202 | 207 |
203 void StartWithService(mojom::ServicePtr service) { | 208 void StartWithService(mojom::ServicePtr service) { |
204 CHECK(!service_); | 209 CHECK(!service_); |
205 service_ = std::move(service); | 210 service_ = std::move(service); |
206 service_.set_connection_error_handler( | 211 service_.set_connection_error_handler( |
207 base::Bind(&Instance::OnServiceLost, base::Unretained(this), | 212 base::Bind(&Instance::OnServiceLost, base::Unretained(this), |
208 service_manager_->GetWeakPtr())); | 213 service_manager_->GetWeakPtr())); |
209 service_->OnStart(identity_, | 214 service_->OnStart(ServiceInfo(identity_, interface_provider_specs_), |
210 base::Bind(&Instance::OnInitializeResponse, | 215 base::Bind(&Instance::OnInitializeResponse, |
211 base::Unretained(this))); | 216 base::Unretained(this))); |
212 } | 217 } |
213 | 218 |
214 void StartWithClientProcessConnection( | 219 void StartWithClientProcessConnection( |
215 mojom::ClientProcessConnectionPtr client_process_connection) { | 220 mojom::ClientProcessConnectionPtr client_process_connection) { |
216 mojom::ServicePtr service; | 221 mojom::ServicePtr service; |
217 service.Bind(mojom::ServicePtrInfo( | 222 service.Bind(mojom::ServicePtrInfo( |
218 std::move(client_process_connection->service), 0)); | 223 std::move(client_process_connection->service), 0)); |
219 pid_receiver_binding_.Bind( | 224 pid_receiver_binding_.Bind( |
220 std::move(client_process_connection->pid_receiver_request)); | 225 std::move(client_process_connection->pid_receiver_request)); |
221 StartWithService(std::move(service)); | 226 StartWithService(std::move(service)); |
222 } | 227 } |
223 | 228 |
224 void StartWithFilePath(const base::FilePath& path) { | 229 void StartWithFilePath(const base::FilePath& path) { |
225 CHECK(!service_); | 230 CHECK(!service_); |
226 runner_ = service_manager_->native_runner_factory_->Create(path); | 231 runner_ = service_manager_->native_runner_factory_->Create(path); |
227 bool start_sandboxed = false; | 232 bool start_sandboxed = false; |
228 mojom::ServicePtr service = runner_->Start( | 233 mojom::ServicePtr service = runner_->Start( |
229 path, identity_, start_sandboxed, | 234 path, identity_, start_sandboxed, |
230 base::Bind(&Instance::PIDAvailable, weak_factory_.GetWeakPtr()), | 235 base::Bind(&Instance::PIDAvailable, weak_factory_.GetWeakPtr()), |
231 base::Bind(&Instance::OnRunnerCompleted, weak_factory_.GetWeakPtr())); | 236 base::Bind(&Instance::OnRunnerCompleted, weak_factory_.GetWeakPtr())); |
232 StartWithService(std::move(service)); | 237 StartWithService(std::move(service)); |
233 } | 238 } |
234 | 239 |
235 mojom::ServiceInfoPtr CreateServiceInfo() const { | 240 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const { |
236 mojom::ServiceInfoPtr info(mojom::ServiceInfo::New()); | 241 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New()); |
237 info->id = id_; | 242 info->id = id_; |
238 info->identity = identity_; | 243 info->identity = identity_; |
239 info->pid = pid_; | 244 info->pid = pid_; |
240 return info; | 245 return info; |
241 } | 246 } |
242 | 247 |
243 const InterfaceProviderSpec& connection_spec() const { | 248 const InterfaceProviderSpec& GetConnectionSpec() const { |
244 return connection_spec_; | 249 auto it = interface_provider_specs_.find( |
| 250 mojom::kServiceManager_ConnectorSpec); |
| 251 return it != interface_provider_specs_.end() ? it->second : empty_spec_; |
245 } | 252 } |
246 const Identity& identity() const { return identity_; } | 253 const Identity& identity() const { return identity_; } |
247 uint32_t id() const { return id_; } | 254 uint32_t id() const { return id_; } |
248 | 255 |
249 // Service: | 256 // Service: |
250 bool OnConnect(const Identity& remote_identity, | 257 bool OnConnect(const Identity& remote_identity, |
251 InterfaceRegistry* registry) override { | 258 InterfaceRegistry* registry) override { |
252 Instance* source = service_manager_->GetExistingInstance(remote_identity); | 259 Instance* source = service_manager_->GetExistingInstance(remote_identity); |
253 DCHECK(source); | 260 DCHECK(source); |
254 if (HasCapability(source->connection_spec_, kCapability_ServiceManager)) { | 261 if (HasCapability(source->GetConnectionSpec(), |
| 262 kCapability_ServiceManager)) { |
255 registry->AddInterface<mojom::ServiceManager>(this); | 263 registry->AddInterface<mojom::ServiceManager>(this); |
256 return true; | 264 return true; |
257 } | 265 } |
258 return false; | 266 return false; |
259 } | 267 } |
260 | 268 |
261 private: | 269 private: |
262 // mojom::Connector implementation: | 270 // mojom::Connector implementation: |
263 void Connect(const service_manager::Identity& in_target, | 271 void Connect(const service_manager::Identity& in_target, |
264 mojom::InterfaceProviderRequest remote_interfaces, | 272 mojom::InterfaceProviderRequest remote_interfaces, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 return false; | 332 return false; |
325 } | 333 } |
326 return true; | 334 return true; |
327 } | 335 } |
328 | 336 |
329 bool ValidateClientProcessConnection( | 337 bool ValidateClientProcessConnection( |
330 mojom::ClientProcessConnectionPtr* client_process_connection, | 338 mojom::ClientProcessConnectionPtr* client_process_connection, |
331 const Identity& target, | 339 const Identity& target, |
332 const ConnectCallback& callback) { | 340 const ConnectCallback& callback) { |
333 if (!client_process_connection->is_null()) { | 341 if (!client_process_connection->is_null()) { |
334 if (!HasCapability(connection_spec_, kCapability_ClientProcess)) { | 342 if (!HasCapability(GetConnectionSpec(), kCapability_ClientProcess)) { |
335 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " | 343 LOG(ERROR) << "Instance: " << identity_.name() << " attempting " |
336 << "to register an instance for a process it created for " | 344 << "to register an instance for a process it created for " |
337 << "target: " << target.name() << " without the " | 345 << "target: " << target.name() << " without the " |
338 << "service:service_manager{client_process} capability " | 346 << "service:service_manager{client_process} capability " |
339 << "class."; | 347 << "class."; |
340 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 348 callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
341 mojom::kInheritUserID); | 349 mojom::kInheritUserID); |
342 return false; | 350 return false; |
343 } | 351 } |
344 | 352 |
(...skipping 13 matching lines...) Expand all Loading... |
358 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, | 366 callback.Run(mojom::ConnectResult::INVALID_ARGUMENT, |
359 mojom::kInheritUserID); | 367 mojom::kInheritUserID); |
360 return false; | 368 return false; |
361 } | 369 } |
362 } | 370 } |
363 return true; | 371 return true; |
364 } | 372 } |
365 | 373 |
366 bool ValidateConnectionSpec(const Identity& target, | 374 bool ValidateConnectionSpec(const Identity& target, |
367 const ConnectCallback& callback) { | 375 const ConnectCallback& callback) { |
| 376 InterfaceProviderSpec connection_spec = GetConnectionSpec(); |
368 // TODO(beng): Need to do the following additional policy validation of | 377 // TODO(beng): Need to do the following additional policy validation of |
369 // whether this instance is allowed to connect using: | 378 // whether this instance is allowed to connect using: |
370 // - a non-null client_process_connection. | 379 // - a non-null client_process_connection. |
371 if (target.user_id() != identity_.user_id() && | 380 if (target.user_id() != identity_.user_id() && |
372 target.user_id() != mojom::kRootUserID && | 381 target.user_id() != mojom::kRootUserID && |
373 !HasCapability(connection_spec_, kCapability_UserID)) { | 382 !HasCapability(connection_spec, kCapability_UserID)) { |
374 LOG(ERROR) << "Instance: " << identity_.name() | 383 LOG(ERROR) << "Instance: " << identity_.name() |
375 << " running as: " << identity_.user_id() | 384 << " running as: " << identity_.user_id() |
376 << " attempting to connect to: " << target.name() | 385 << " attempting to connect to: " << target.name() |
377 << " as: " << target.user_id() << " without " | 386 << " as: " << target.user_id() << " without " |
378 << " the service:service_manager{user_id} capability."; | 387 << " the service:service_manager{user_id} capability."; |
379 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 388 callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
380 mojom::kInheritUserID); | 389 mojom::kInheritUserID); |
381 return false; | 390 return false; |
382 } | 391 } |
383 if (!target.instance().empty() && | 392 if (!target.instance().empty() && |
384 target.instance() != GetNamePath(target.name()) && | 393 target.instance() != GetNamePath(target.name()) && |
385 !HasCapability(connection_spec_, kCapability_InstanceName)) { | 394 !HasCapability(connection_spec, kCapability_InstanceName)) { |
386 LOG(ERROR) << "Instance: " << identity_.name() << " attempting to " | 395 LOG(ERROR) << "Instance: " << identity_.name() << " attempting to " |
387 << "connect to " << target.name() | 396 << "connect to " << target.name() |
388 << " using Instance name: " << target.instance() | 397 << " using Instance name: " << target.instance() |
389 << " without the " | 398 << " without the " |
390 << "service:service_manager{instance_name} capability."; | 399 << "service:service_manager{instance_name} capability."; |
391 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); | 400 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); |
392 return false; | 401 return false; |
393 } | 402 } |
394 | 403 |
395 if (allow_any_application_ || | 404 if (allow_any_application_ || |
396 connection_spec_.requires.find(target.name()) != | 405 connection_spec.requires.find(target.name()) != |
397 connection_spec_.requires.end()) { | 406 connection_spec.requires.end()) { |
398 return true; | 407 return true; |
399 } | 408 } |
400 LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " | 409 LOG(ERROR) << "InterfaceProviderSpec prevented connection from: " |
401 << identity_.name() << " to: " << target.name(); | 410 << identity_.name() << " to: " << target.name(); |
402 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); | 411 callback.Run(mojom::ConnectResult::ACCESS_DENIED, mojom::kInheritUserID); |
403 return false; | 412 return false; |
404 } | 413 } |
405 | 414 |
406 uint32_t GenerateUniqueID() const { | 415 uint32_t GenerateUniqueID() const { |
407 static uint32_t id = mojom::kInvalidInstanceID; | 416 static uint32_t id = mojom::kInvalidInstanceID; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 service_manager_->OnInstanceError(this); | 463 service_manager_->OnInstanceError(this); |
455 } | 464 } |
456 | 465 |
457 service_manager::ServiceManager* const service_manager_; | 466 service_manager::ServiceManager* const service_manager_; |
458 | 467 |
459 // An id that identifies this instance. Distinct from pid, as a single process | 468 // An id that identifies this instance. Distinct from pid, as a single process |
460 // may vend multiple application instances, and this object may exist before a | 469 // may vend multiple application instances, and this object may exist before a |
461 // process is launched. | 470 // process is launched. |
462 const uint32_t id_; | 471 const uint32_t id_; |
463 const Identity identity_; | 472 const Identity identity_; |
464 const InterfaceProviderSpec connection_spec_; | 473 const InterfaceProviderSpecMap interface_provider_specs_; |
| 474 const InterfaceProviderSpec empty_spec_; |
465 const bool allow_any_application_; | 475 const bool allow_any_application_; |
466 std::unique_ptr<NativeRunner> runner_; | 476 std::unique_ptr<NativeRunner> runner_; |
467 mojom::ServicePtr service_; | 477 mojom::ServicePtr service_; |
468 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; | 478 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; |
469 mojo::BindingSet<mojom::Connector> connectors_; | 479 mojo::BindingSet<mojom::Connector> connectors_; |
470 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; | 480 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; |
471 base::ProcessId pid_ = base::kNullProcessId; | 481 base::ProcessId pid_ = base::kNullProcessId; |
472 Instance* parent_ = nullptr; | 482 Instance* parent_ = nullptr; |
473 InstanceMap children_; | 483 InstanceMap children_; |
474 base::WeakPtrFactory<Instance> weak_factory_; | 484 base::WeakPtrFactory<Instance> weak_factory_; |
(...skipping 25 matching lines...) Expand all Loading... |
500 weak_ptr_factory_(this) { | 510 weak_ptr_factory_(this) { |
501 mojom::ServicePtr service; | 511 mojom::ServicePtr service; |
502 mojom::ServiceRequest request = mojo::GetProxy(&service); | 512 mojom::ServiceRequest request = mojo::GetProxy(&service); |
503 | 513 |
504 InterfaceProviderSpec spec; | 514 InterfaceProviderSpec spec; |
505 spec.provides[kCapability_ServiceManager].insert( | 515 spec.provides[kCapability_ServiceManager].insert( |
506 "service_manager::mojom::ServiceManager"); | 516 "service_manager::mojom::ServiceManager"); |
507 spec.requires["*"].insert("service_manager:service_factory"); | 517 spec.requires["*"].insert("service_manager:service_factory"); |
508 spec.requires["service:catalog"].insert("service_manager:resolver"); | 518 spec.requires["service:catalog"].insert("service_manager:resolver"); |
509 spec.requires["service:tracing"].insert("app"); | 519 spec.requires["service:tracing"].insert("app"); |
| 520 InterfaceProviderSpecMap specs; |
| 521 specs[mojom::kServiceManager_ConnectorSpec] = spec; |
510 | 522 |
511 service_manager_instance_ = | 523 service_manager_instance_ = |
512 CreateInstance(Identity(), CreateServiceManagerIdentity(), spec); | 524 CreateInstance(Identity(), CreateServiceManagerIdentity(), specs); |
513 service_manager_instance_->StartWithService(std::move(service)); | 525 service_manager_instance_->StartWithService(std::move(service)); |
514 singletons_.insert(kServiceManagerName); | 526 singletons_.insert(kServiceManagerName); |
515 service_context_.reset(new ServiceContext(this, std::move(request))); | 527 service_context_.reset(new ServiceContext(this, std::move(request))); |
516 | 528 |
517 if (catalog) | 529 if (catalog) |
518 InitCatalog(std::move(catalog)); | 530 InitCatalog(std::move(catalog)); |
519 } | 531 } |
520 | 532 |
521 ServiceManager::~ServiceManager() { | 533 ServiceManager::~ServiceManager() { |
522 // Ensure we tear down the ServiceManager instance last. This is to avoid | 534 // Ensure we tear down the ServiceManager instance last. This is to avoid |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 | 596 |
585 void ServiceManager::InitCatalog(mojom::ServicePtr catalog) { | 597 void ServiceManager::InitCatalog(mojom::ServicePtr catalog) { |
586 // TODO(beng): It'd be great to build this from the manifest, however there's | 598 // TODO(beng): It'd be great to build this from the manifest, however there's |
587 // a bit of a chicken-and-egg problem. | 599 // a bit of a chicken-and-egg problem. |
588 InterfaceProviderSpec spec; | 600 InterfaceProviderSpec spec; |
589 spec.provides["app"].insert("filesystem::mojom::Directory"); | 601 spec.provides["app"].insert("filesystem::mojom::Directory"); |
590 spec.provides["catalog:catalog"].insert("catalog::mojom::Catalog"); | 602 spec.provides["catalog:catalog"].insert("catalog::mojom::Catalog"); |
591 spec.provides["service_manager:resolver"].insert( | 603 spec.provides["service_manager:resolver"].insert( |
592 "service_manager::mojom::Resolver"); | 604 "service_manager::mojom::Resolver"); |
593 spec.provides["control"].insert("catalog::mojom::CatalogControl"); | 605 spec.provides["control"].insert("catalog::mojom::CatalogControl"); |
| 606 InterfaceProviderSpecMap specs; |
| 607 specs[mojom::kServiceManager_ConnectorSpec] = spec; |
| 608 |
594 Instance* instance = CreateInstance( | 609 Instance* instance = CreateInstance( |
595 CreateServiceManagerIdentity(), CreateCatalogIdentity(), spec); | 610 CreateServiceManagerIdentity(), CreateCatalogIdentity(), specs); |
596 singletons_.insert(kCatalogName); | 611 singletons_.insert(kCatalogName); |
597 instance->StartWithService(std::move(catalog)); | 612 instance->StartWithService(std::move(catalog)); |
598 } | 613 } |
599 | 614 |
600 mojom::Resolver* ServiceManager::GetResolver(const Identity& identity) { | 615 mojom::Resolver* ServiceManager::GetResolver(const Identity& identity) { |
601 auto iter = identity_to_resolver_.find(identity); | 616 auto iter = identity_to_resolver_.find(identity); |
602 if (iter != identity_to_resolver_.end()) | 617 if (iter != identity_to_resolver_.end()) |
603 return iter->second.get(); | 618 return iter->second.get(); |
604 | 619 |
605 mojom::ResolverPtr resolver_ptr; | 620 mojom::ResolverPtr resolver_ptr; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 | 717 |
703 bool ServiceManager::ConnectToExistingInstance( | 718 bool ServiceManager::ConnectToExistingInstance( |
704 std::unique_ptr<ConnectParams>* params) { | 719 std::unique_ptr<ConnectParams>* params) { |
705 Instance* instance = GetExistingInstance((*params)->target()); | 720 Instance* instance = GetExistingInstance((*params)->target()); |
706 return instance && instance->ConnectToService(params); | 721 return instance && instance->ConnectToService(params); |
707 } | 722 } |
708 | 723 |
709 ServiceManager::Instance* ServiceManager::CreateInstance( | 724 ServiceManager::Instance* ServiceManager::CreateInstance( |
710 const Identity& source, | 725 const Identity& source, |
711 const Identity& target, | 726 const Identity& target, |
712 const InterfaceProviderSpec& connection_spec) { | 727 const InterfaceProviderSpecMap& specs) { |
713 CHECK(target.user_id() != mojom::kInheritUserID); | 728 CHECK(target.user_id() != mojom::kInheritUserID); |
714 | 729 |
715 std::unique_ptr<Instance> instance( | 730 auto instance = base::MakeUnique<Instance>(this, target, specs); |
716 new Instance(this, target, connection_spec)); | |
717 Instance* raw_instance = instance.get(); | 731 Instance* raw_instance = instance.get(); |
718 | 732 |
719 Instance* source_instance = GetExistingInstance(source); | 733 Instance* source_instance = GetExistingInstance(source); |
720 if (source_instance) | 734 if (source_instance) |
721 source_instance->AddChild(std::move(instance)); | 735 source_instance->AddChild(std::move(instance)); |
722 else | 736 else |
723 root_instances_.insert(std::make_pair(raw_instance, std::move(instance))); | 737 root_instances_.insert(std::make_pair(raw_instance, std::move(instance))); |
724 | 738 |
725 // NOTE: |instance| has been passed elsewhere. Use |raw_instance| from this | 739 // NOTE: |instance| has been passed elsewhere. Use |raw_instance| from this |
726 // point forward. It's safe for the extent of this method. | 740 // point forward. It's safe for the extent of this method. |
727 | 741 |
728 auto result = | 742 auto result = |
729 identity_to_instance_.insert(std::make_pair(target, raw_instance)); | 743 identity_to_instance_.insert(std::make_pair(target, raw_instance)); |
730 DCHECK(result.second); | 744 DCHECK(result.second); |
731 | 745 |
732 mojom::ServiceInfoPtr info = raw_instance->CreateServiceInfo(); | 746 mojom::RunningServiceInfoPtr info = raw_instance->CreateRunningServiceInfo(); |
733 listeners_.ForAllPtrs([&info](mojom::ServiceManagerListener* listener) { | 747 listeners_.ForAllPtrs([&info](mojom::ServiceManagerListener* listener) { |
734 listener->OnServiceCreated(info.Clone()); | 748 listener->OnServiceCreated(info.Clone()); |
735 }); | 749 }); |
736 | 750 |
737 return raw_instance; | 751 return raw_instance; |
738 } | 752 } |
739 | 753 |
740 void ServiceManager::AddListener(mojom::ServiceManagerListenerPtr listener) { | 754 void ServiceManager::AddListener(mojom::ServiceManagerListenerPtr listener) { |
741 // TODO(beng): filter instances provided by those visible to this service. | 755 // TODO(beng): filter instances provided by those visible to this service. |
742 std::vector<mojom::ServiceInfoPtr> instances; | 756 std::vector<mojom::RunningServiceInfoPtr> instances; |
743 instances.reserve(identity_to_instance_.size()); | 757 instances.reserve(identity_to_instance_.size()); |
744 for (auto& instance : identity_to_instance_) | 758 for (auto& instance : identity_to_instance_) |
745 instances.push_back(instance.second->CreateServiceInfo()); | 759 instances.push_back(instance.second->CreateRunningServiceInfo()); |
746 listener->OnInit(std::move(instances)); | 760 listener->OnInit(std::move(instances)); |
747 | 761 |
748 listeners_.AddPtr(std::move(listener)); | 762 listeners_.AddPtr(std::move(listener)); |
749 } | 763 } |
750 | 764 |
751 void ServiceManager::CreateServiceWithFactory(const Identity& service_factory, | 765 void ServiceManager::CreateServiceWithFactory(const Identity& service_factory, |
752 const std::string& name, | 766 const std::string& name, |
753 mojom::ServiceRequest request) { | 767 mojom::ServiceRequest request) { |
754 mojom::ServiceFactory* factory = GetServiceFactory(service_factory); | 768 mojom::ServiceFactory* factory = GetServiceFactory(service_factory); |
755 factory->CreateService(std::move(request), name); | 769 factory->CreateService(std::move(request), name); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 // If this request was originated by a specific Instance and that Instance is | 802 // If this request was originated by a specific Instance and that Instance is |
789 // no longer around, we ignore this response. | 803 // no longer around, we ignore this response. |
790 if (has_source_instance && !source_instance) | 804 if (has_source_instance && !source_instance) |
791 return; | 805 return; |
792 | 806 |
793 std::string instance_name = params->target().instance(); | 807 std::string instance_name = params->target().instance(); |
794 if (instance_name == GetNamePath(params->target().name()) && | 808 if (instance_name == GetNamePath(params->target().name()) && |
795 result->qualifier != GetNamePath(result->resolved_name)) { | 809 result->qualifier != GetNamePath(result->resolved_name)) { |
796 instance_name = result->qualifier; | 810 instance_name = result->qualifier; |
797 } | 811 } |
798 // |result->connection_spec| can be null when there is no manifest, e.g. for | 812 // |result->interface_provider_specs| can be empty when there is no manifest, |
799 // URL types not resolvable by the resolver. | 813 // e.g. for URL types not resolvable by the resolver. |
800 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); | 814 InterfaceProviderSpec connection_spec = GetPermissiveInterfaceProviderSpec(); |
801 if (result->connection_spec.has_value()) | 815 auto it = result->interface_provider_specs.find( |
802 connection_spec = result->connection_spec.value(); | 816 mojom::kServiceManager_ConnectorSpec); |
| 817 if (it != result->interface_provider_specs.end()) |
| 818 connection_spec = it->second; |
803 | 819 |
804 const std::string user_id = | 820 const std::string user_id = |
805 HasCapability(connection_spec, kCapability_AllUsers) | 821 HasCapability(connection_spec, kCapability_AllUsers) |
806 ? base::GenerateGUID() : params->target().user_id(); | 822 ? base::GenerateGUID() : params->target().user_id(); |
807 const Identity target(params->target().name(), user_id, instance_name); | 823 const Identity target(params->target().name(), user_id, instance_name); |
808 params->set_target(target); | 824 params->set_target(target); |
809 | 825 |
810 // It's possible that when this manifest request was issued, another one was | 826 // It's possible that when this manifest request was issued, another one was |
811 // already in-progress and completed by the time this one did, and so the | 827 // already in-progress and completed by the time this one did, and so the |
812 // requested application may already be running. | 828 // requested application may already be running. |
(...skipping 12 matching lines...) Expand all Loading... |
825 if (HasCapability(connection_spec, kCapability_AllUsers)) { | 841 if (HasCapability(connection_spec, kCapability_AllUsers)) { |
826 singletons_.insert(target.name()); | 842 singletons_.insert(target.name()); |
827 source_identity_for_creation = CreateServiceManagerIdentity(); | 843 source_identity_for_creation = CreateServiceManagerIdentity(); |
828 } else { | 844 } else { |
829 source_identity_for_creation = params->source(); | 845 source_identity_for_creation = params->source(); |
830 } | 846 } |
831 | 847 |
832 mojom::ClientProcessConnectionPtr client_process_connection = | 848 mojom::ClientProcessConnectionPtr client_process_connection = |
833 params->TakeClientProcessConnection(); | 849 params->TakeClientProcessConnection(); |
834 Instance* instance = CreateInstance(source_identity_for_creation, | 850 Instance* instance = CreateInstance(source_identity_for_creation, |
835 target, connection_spec); | 851 target, result->interface_provider_specs); |
836 | 852 |
837 // Below are various paths through which a new Instance can be bound to a | 853 // Below are various paths through which a new Instance can be bound to a |
838 // Service proxy. | 854 // Service proxy. |
839 if (service.is_bound()) { | 855 if (service.is_bound()) { |
840 // If a ServicePtr was provided, there's no more work to do: someone | 856 // If a ServicePtr was provided, there's no more work to do: someone |
841 // is already holding a corresponding ServiceRequest. | 857 // is already holding a corresponding ServiceRequest. |
842 instance->StartWithService(std::move(service)); | 858 instance->StartWithService(std::move(service)); |
843 } else if (!client_process_connection.is_null()) { | 859 } else if (!client_process_connection.is_null()) { |
844 // Likewise if a ClientProcessConnection was given via Connect(), it | 860 // Likewise if a ClientProcessConnection was given via Connect(), it |
845 // provides the Service proxy to use. | 861 // provides the Service proxy to use. |
846 instance->StartWithClientProcessConnection( | 862 instance->StartWithClientProcessConnection( |
847 std::move(client_process_connection)); | 863 std::move(client_process_connection)); |
848 } else { | 864 } else { |
849 // Otherwise we create a new Service pipe. | 865 // Otherwise we create a new Service pipe. |
850 mojom::ServiceRequest request = GetProxy(&service); | 866 mojom::ServiceRequest request = GetProxy(&service); |
851 CHECK(!result->package_path.empty() && result->connection_spec.has_value()); | 867 CHECK(!result->package_path.empty()); |
| 868 |
| 869 // The catalog was unable to read a manifest for this service. We can't do |
| 870 // anything more. |
| 871 // TODO(beng): There may be some cases where it's valid to have an empty |
| 872 // spec, so we should probably include a return value in |result|. |
| 873 if (result->interface_provider_specs.empty()) { |
| 874 if (!params->connect_callback().is_null()) |
| 875 params->connect_callback().Run(mojom::ConnectResult::ACCESS_DENIED, ""); |
| 876 return; |
| 877 } |
852 | 878 |
853 if (target.name() != result->resolved_name) { | 879 if (target.name() != result->resolved_name) { |
854 instance->StartWithService(std::move(service)); | 880 instance->StartWithService(std::move(service)); |
855 Identity factory(result->resolved_name, target.user_id(), | 881 Identity factory(result->resolved_name, target.user_id(), |
856 instance_name); | 882 instance_name); |
857 CreateServiceWithFactory(factory, target.name(), std::move(request)); | 883 CreateServiceWithFactory(factory, target.name(), std::move(request)); |
858 } else { | 884 } else { |
859 base::FilePath package_path; | 885 base::FilePath package_path; |
860 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( | 886 if (!service_overrides_ || !service_overrides_->GetExecutablePathOverride( |
861 target.name(), &package_path)) { | 887 target.name(), &package_path)) { |
(...skipping 20 matching lines...) Expand all Loading... |
882 // Now that the instance has a Service, we can connect to it. | 908 // Now that the instance has a Service, we can connect to it. |
883 bool connected = instance->ConnectToService(¶ms); | 909 bool connected = instance->ConnectToService(¶ms); |
884 DCHECK(connected); | 910 DCHECK(connected); |
885 } | 911 } |
886 | 912 |
887 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { | 913 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |
888 return weak_ptr_factory_.GetWeakPtr(); | 914 return weak_ptr_factory_.GetWeakPtr(); |
889 } | 915 } |
890 | 916 |
891 } // namespace service_manager | 917 } // namespace service_manager |
OLD | NEW |