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 |