| 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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 return; | 315 return; |
| 316 | 316 |
| 317 std::unique_ptr<ConnectParams> params(new ConnectParams); | 317 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 318 params->set_source(identity_); | 318 params->set_source(identity_); |
| 319 params->set_target(target); | 319 params->set_target(target); |
| 320 | 320 |
| 321 mojom::ServicePtr service; | 321 mojom::ServicePtr service; |
| 322 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); | 322 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); |
| 323 params->set_client_process_info(std::move(service), | 323 params->set_client_process_info(std::move(service), |
| 324 std::move(pid_receiver_request)); | 324 std::move(pid_receiver_request)); |
| 325 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); | 325 service_manager_->Connect( |
| 326 std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
| 326 } | 327 } |
| 327 | 328 |
| 328 void Connect(const service_manager::Identity& in_target, | 329 void Connect(const service_manager::Identity& in_target, |
| 329 mojom::InterfaceProviderRequest remote_interfaces, | 330 mojom::InterfaceProviderRequest remote_interfaces, |
| 330 const ConnectCallback& callback) override { | 331 const ConnectCallback& callback) override { |
| 331 Identity target = in_target; | 332 Identity target = in_target; |
| 332 mojom::ConnectResult result = | 333 mojom::ConnectResult result = |
| 333 ValidateConnectParams(&target, nullptr, nullptr); | 334 ValidateConnectParams(&target, nullptr, nullptr); |
| 334 if (!Succeeded(result)) { | 335 if (!Succeeded(result)) { |
| 335 callback.Run(result, mojom::kInheritUserID); | 336 callback.Run(result, mojom::kInheritUserID); |
| 336 return; | 337 return; |
| 337 } | 338 } |
| 338 | 339 |
| 339 std::unique_ptr<ConnectParams> params(new ConnectParams); | 340 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 340 params->set_source(identity_); | 341 params->set_source(identity_); |
| 341 params->set_target(target); | 342 params->set_target(target); |
| 342 params->set_remote_interfaces(std::move(remote_interfaces)); | 343 params->set_remote_interfaces(std::move(remote_interfaces)); |
| 343 params->set_connect_callback(callback); | 344 params->set_connect_callback(callback); |
| 344 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); | 345 service_manager_->Connect( |
| 346 std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
| 345 } | 347 } |
| 346 | 348 |
| 347 void BindInterface(const service_manager::Identity& in_target, | 349 void BindInterface(const service_manager::Identity& in_target, |
| 348 const std::string& interface_name, | 350 const std::string& interface_name, |
| 349 mojo::ScopedMessagePipeHandle interface_pipe, | 351 mojo::ScopedMessagePipeHandle interface_pipe, |
| 350 const BindInterfaceCallback& callback) override { | 352 const BindInterfaceCallback& callback) override { |
| 351 Identity target = in_target; | 353 Identity target = in_target; |
| 352 mojom::ConnectResult result = | 354 mojom::ConnectResult result = |
| 353 ValidateConnectParams(&target, nullptr, nullptr); | 355 ValidateConnectParams(&target, nullptr, nullptr); |
| 354 if (!Succeeded(result)) { | 356 if (!Succeeded(result)) { |
| 355 callback.Run(result, mojom::kInheritUserID); | 357 callback.Run(result, mojom::kInheritUserID); |
| 356 return; | 358 return; |
| 357 } | 359 } |
| 358 | 360 |
| 359 std::unique_ptr<ConnectParams> params(new ConnectParams); | 361 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 360 params->set_source(identity_); | 362 params->set_source(identity_); |
| 361 params->set_target(target); | 363 params->set_target(target); |
| 362 params->set_interface_request_info(interface_name, | 364 params->set_interface_request_info(interface_name, |
| 363 std::move(interface_pipe)); | 365 std::move(interface_pipe)); |
| 364 params->set_bind_interface_callback(callback); | 366 params->set_bind_interface_callback(callback); |
| 365 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); | 367 service_manager_->Connect( |
| 368 std::move(params), nullptr, weak_factory_.GetWeakPtr()); |
| 366 } | 369 } |
| 367 | 370 |
| 368 void Clone(mojom::ConnectorRequest request) override { | 371 void Clone(mojom::ConnectorRequest request) override { |
| 369 connectors_.AddBinding(this, std::move(request)); | 372 connectors_.AddBinding(this, std::move(request)); |
| 370 } | 373 } |
| 371 | 374 |
| 372 // mojom::PIDReceiver: | 375 // mojom::PIDReceiver: |
| 373 void SetPID(uint32_t pid) override { | 376 void SetPID(uint32_t pid) override { |
| 374 PIDAvailable(pid); | 377 PIDAvailable(pid); |
| 375 } | 378 } |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 std::unique_ptr<ServiceOverrides> overrides) { | 678 std::unique_ptr<ServiceOverrides> overrides) { |
| 676 service_overrides_ = std::move(overrides); | 679 service_overrides_ = std::move(overrides); |
| 677 } | 680 } |
| 678 | 681 |
| 679 void ServiceManager::SetInstanceQuitCallback( | 682 void ServiceManager::SetInstanceQuitCallback( |
| 680 base::Callback<void(const Identity&)> callback) { | 683 base::Callback<void(const Identity&)> callback) { |
| 681 instance_quit_callback_ = callback; | 684 instance_quit_callback_ = callback; |
| 682 } | 685 } |
| 683 | 686 |
| 684 void ServiceManager::Connect(std::unique_ptr<ConnectParams> params) { | 687 void ServiceManager::Connect(std::unique_ptr<ConnectParams> params) { |
| 685 Connect(std::move(params), nullptr); | 688 Connect(std::move(params), nullptr, nullptr); |
| 686 } | 689 } |
| 687 | 690 |
| 688 void ServiceManager::RegisterService( | 691 mojom::ServiceRequest ServiceManager::StartEmbedderService( |
| 689 const Identity& identity, | 692 const std::string& name) { |
| 690 mojom::ServicePtr service, | 693 std::unique_ptr<ConnectParams> params(new ConnectParams); |
| 691 mojom::PIDReceiverRequest pid_receiver_request) { | |
| 692 auto params = base::MakeUnique<ConnectParams>(); | |
| 693 | 694 |
| 694 if (!pid_receiver_request.is_pending()) { | 695 Identity embedder_identity(name, mojom::kRootUserID); |
| 695 mojom::PIDReceiverPtr pid_receiver; | 696 params->set_source(embedder_identity); |
| 696 pid_receiver_request = mojom::PIDReceiverRequest(&pid_receiver); | 697 params->set_target(embedder_identity); |
| 697 pid_receiver->SetPID(base::Process::Current().Pid()); | |
| 698 } | |
| 699 | 698 |
| 700 params->set_source(identity); | 699 mojom::ServicePtr service; |
| 701 params->set_target(identity); | 700 mojom::ServiceRequest request(&service); |
| 702 params->set_client_process_info( | 701 Connect(std::move(params), std::move(service), nullptr); |
| 703 std::move(service), std::move(pid_receiver_request)); | 702 |
| 704 Connect(std::move(params), nullptr); | 703 return request; |
| 705 } | 704 } |
| 706 | 705 |
| 707 //////////////////////////////////////////////////////////////////////////////// | 706 //////////////////////////////////////////////////////////////////////////////// |
| 708 // ServiceManager, private: | 707 // ServiceManager, private: |
| 709 | 708 |
| 710 void ServiceManager::InitCatalog(mojom::ServicePtr catalog) { | 709 void ServiceManager::InitCatalog(mojom::ServicePtr catalog) { |
| 711 // TODO(beng): It'd be great to build this from the manifest, however there's | 710 // TODO(beng): It'd be great to build this from the manifest, however there's |
| 712 // a bit of a chicken-and-egg problem. | 711 // a bit of a chicken-and-egg problem. |
| 713 InterfaceProviderSpec spec; | 712 InterfaceProviderSpec spec; |
| 714 spec.provides["app"].insert("filesystem::mojom::Directory"); | 713 spec.provides["app"].insert("filesystem::mojom::Directory"); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 | 758 |
| 760 void ServiceManager::OnInstanceStopped(const Identity& identity) { | 759 void ServiceManager::OnInstanceStopped(const Identity& identity) { |
| 761 listeners_.ForAllPtrs([identity](mojom::ServiceManagerListener* listener) { | 760 listeners_.ForAllPtrs([identity](mojom::ServiceManagerListener* listener) { |
| 762 listener->OnServiceStopped(identity); | 761 listener->OnServiceStopped(identity); |
| 763 }); | 762 }); |
| 764 if (!instance_quit_callback_.is_null()) | 763 if (!instance_quit_callback_.is_null()) |
| 765 instance_quit_callback_.Run(identity); | 764 instance_quit_callback_.Run(identity); |
| 766 } | 765 } |
| 767 | 766 |
| 768 void ServiceManager::Connect(std::unique_ptr<ConnectParams> params, | 767 void ServiceManager::Connect(std::unique_ptr<ConnectParams> params, |
| 768 mojom::ServicePtr service, |
| 769 base::WeakPtr<Instance> source_instance) { | 769 base::WeakPtr<Instance> source_instance) { |
| 770 TRACE_EVENT_INSTANT1("service_manager", "ServiceManager::Connect", | 770 TRACE_EVENT_INSTANT1("service_manager", "ServiceManager::Connect", |
| 771 TRACE_EVENT_SCOPE_THREAD, "original_name", | 771 TRACE_EVENT_SCOPE_THREAD, "original_name", |
| 772 params->target().name()); | 772 params->target().name()); |
| 773 DCHECK(!params->target().name().empty()); | 773 DCHECK(!params->target().name().empty()); |
| 774 DCHECK(base::IsValidGUID(params->target().user_id())); | 774 DCHECK(base::IsValidGUID(params->target().user_id())); |
| 775 DCHECK_NE(mojom::kInheritUserID, params->target().user_id()); | 775 DCHECK_NE(mojom::kInheritUserID, params->target().user_id()); |
| 776 DCHECK(!params->HasClientProcessInfo() || | 776 DCHECK(!service.is_bound() || !identity_to_instance_.count(params->target())); |
| 777 !identity_to_instance_.count(params->target())); | |
| 778 | 777 |
| 779 // Connect to an existing matching instance, if possible. | 778 // Connect to an existing matching instance, if possible. |
| 780 if (!params->HasClientProcessInfo() && ConnectToExistingInstance(¶ms)) | 779 if (!service.is_bound() && ConnectToExistingInstance(¶ms)) |
| 781 return; | 780 return; |
| 782 | 781 |
| 783 // The catalog needs to see the source identity as that of the originating | 782 // The catalog needs to see the source identity as that of the originating |
| 784 // app so it loads the correct store. Since the catalog is itself run as root | 783 // app so it loads the correct store. Since the catalog is itself run as root |
| 785 // when this re-enters Connect() it'll be handled by | 784 // when this re-enters Connect() it'll be handled by |
| 786 // ConnectToExistingInstance(). | 785 // ConnectToExistingInstance(). |
| 787 mojom::Resolver* resolver = GetResolver(Identity( | 786 mojom::Resolver* resolver = GetResolver(Identity( |
| 788 service_manager::mojom::kServiceName, params->target().user_id())); | 787 service_manager::mojom::kServiceName, params->target().user_id())); |
| 789 | 788 |
| 790 std::string name = params->target().name(); | 789 std::string name = params->target().name(); |
| 791 resolver->ResolveServiceName( | 790 resolver->ResolveServiceName( |
| 792 name, | 791 name, |
| 793 base::Bind(&service_manager::ServiceManager::OnGotResolvedName, | 792 base::Bind(&service_manager::ServiceManager::OnGotResolvedName, |
| 794 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms), | 793 weak_ptr_factory_.GetWeakPtr(), base::Passed(¶ms), |
| 795 !!source_instance, source_instance)); | 794 base::Passed(&service), !!source_instance, source_instance)); |
| 796 } | 795 } |
| 797 | 796 |
| 798 ServiceManager::Instance* ServiceManager::GetExistingInstance( | 797 ServiceManager::Instance* ServiceManager::GetExistingInstance( |
| 799 const Identity& identity) const { | 798 const Identity& identity) const { |
| 800 const auto& it = identity_to_instance_.find(identity); | 799 const auto& it = identity_to_instance_.find(identity); |
| 801 Instance* instance = it != identity_to_instance_.end() ? it->second : nullptr; | 800 Instance* instance = it != identity_to_instance_.end() ? it->second : nullptr; |
| 802 if (instance) | 801 if (instance) |
| 803 return instance; | 802 return instance; |
| 804 | 803 |
| 805 if (singletons_.find(identity.name()) != singletons_.end()) { | 804 if (singletons_.find(identity.name()) != singletons_.end()) { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 } | 925 } |
| 927 | 926 |
| 928 void ServiceManager::OnServiceFactoryLost(const Identity& which) { | 927 void ServiceManager::OnServiceFactoryLost(const Identity& which) { |
| 929 // Remove the mapping. | 928 // Remove the mapping. |
| 930 auto it = service_factories_.find(which); | 929 auto it = service_factories_.find(which); |
| 931 DCHECK(it != service_factories_.end()); | 930 DCHECK(it != service_factories_.end()); |
| 932 service_factories_.erase(it); | 931 service_factories_.erase(it); |
| 933 } | 932 } |
| 934 | 933 |
| 935 void ServiceManager::OnGotResolvedName(std::unique_ptr<ConnectParams> params, | 934 void ServiceManager::OnGotResolvedName(std::unique_ptr<ConnectParams> params, |
| 935 mojom::ServicePtr service, |
| 936 bool has_source_instance, | 936 bool has_source_instance, |
| 937 base::WeakPtr<Instance> source_instance, | 937 base::WeakPtr<Instance> source_instance, |
| 938 mojom::ResolveResultPtr result, | 938 mojom::ResolveResultPtr result, |
| 939 mojom::ResolveResultPtr parent) { | 939 mojom::ResolveResultPtr parent) { |
| 940 // If this request was originated by a specific Instance and that Instance is | 940 // If this request was originated by a specific Instance and that Instance is |
| 941 // no longer around, we ignore this response. | 941 // no longer around, we ignore this response. |
| 942 if (has_source_instance && !source_instance) | 942 if (has_source_instance && !source_instance) |
| 943 return; | 943 return; |
| 944 | 944 |
| 945 // If name resolution failed, we drop the connection. | 945 // If name resolution failed, we drop the connection. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 source_identity_for_creation = CreateServiceManagerIdentity(); | 985 source_identity_for_creation = CreateServiceManagerIdentity(); |
| 986 } else { | 986 } else { |
| 987 source_identity_for_creation = params->source(); | 987 source_identity_for_creation = params->source(); |
| 988 } | 988 } |
| 989 | 989 |
| 990 Instance* instance = CreateInstance(source_identity_for_creation, | 990 Instance* instance = CreateInstance(source_identity_for_creation, |
| 991 target, result->interface_provider_specs); | 991 target, result->interface_provider_specs); |
| 992 | 992 |
| 993 // Below are various paths through which a new Instance can be bound to a | 993 // Below are various paths through which a new Instance can be bound to a |
| 994 // Service proxy. | 994 // Service proxy. |
| 995 if (params->HasClientProcessInfo()) { | 995 if (service.is_bound()) { |
| 996 // This branch should be reachable only via a call to RegisterService() . We | 996 // If a ServicePtr was provided, there's no more work to do: someone |
| 997 // is already holding a corresponding ServiceRequest. |
| 998 instance->StartWithService(std::move(service)); |
| 999 } else if (params->HasClientProcessInfo()) { |
| 1000 // This branch should be reachable only via a call to RegisterService(). We |
| 997 // start the instance but return early before we connect to it. Clients will | 1001 // start the instance but return early before we connect to it. Clients will |
| 998 // call Connect() with the target identity subsequently. | 1002 // call Connect() with the target identity subsequently. |
| 999 instance->BindPIDReceiver(params->TakePIDReceiverRequest()); | 1003 instance->BindPIDReceiver(params->TakePIDReceiverRequest()); |
| 1000 instance->StartWithService(params->TakeService()); | 1004 instance->StartWithService(params->TakeService()); |
| 1001 return; | 1005 return; |
| 1002 } else { | 1006 } else { |
| 1003 // Otherwise we create a new Service pipe. | 1007 // Otherwise we create a new Service pipe. |
| 1004 mojom::ServicePtr service; | |
| 1005 mojom::ServiceRequest request(&service); | 1008 mojom::ServiceRequest request(&service); |
| 1006 | 1009 |
| 1007 // The catalog was unable to read a manifest for this service. We can't do | 1010 // The catalog was unable to read a manifest for this service. We can't do |
| 1008 // anything more. | 1011 // anything more. |
| 1009 // TODO(beng): There may be some cases where it's valid to have an empty | 1012 // TODO(beng): There may be some cases where it's valid to have an empty |
| 1010 // spec, so we should probably include a return value in |result|. | 1013 // spec, so we should probably include a return value in |result|. |
| 1011 if (result->interface_provider_specs.empty()) { | 1014 if (result->interface_provider_specs.empty()) { |
| 1012 LOG(ERROR) | 1015 LOG(ERROR) |
| 1013 << "Error: The catalog was unable to read a manifest for service \"" | 1016 << "Error: The catalog was unable to read a manifest for service \"" |
| 1014 << result->name << "\"."; | 1017 << result->name << "\"."; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 bool connected = instance->CallOnConnect(¶ms); | 1066 bool connected = instance->CallOnConnect(¶ms); |
| 1064 DCHECK(connected); | 1067 DCHECK(connected); |
| 1065 } | 1068 } |
| 1066 } | 1069 } |
| 1067 | 1070 |
| 1068 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { | 1071 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |
| 1069 return weak_ptr_factory_.GetWeakPtr(); | 1072 return weak_ptr_factory_.GetWeakPtr(); |
| 1070 } | 1073 } |
| 1071 | 1074 |
| 1072 } // namespace service_manager | 1075 } // namespace service_manager |
| OLD | NEW |