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