| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "garnet/bin/netconnector/responding_service_host.h" |
| |
| #include "lib/fidl/cpp/clone.h" |
| #include "src/lib/fxl/logging.h" |
| |
| namespace netconnector { |
| |
| RespondingServiceHost::RespondingServiceHost( |
| const fuchsia::sys::EnvironmentPtr& environment) { |
| FXL_DCHECK(environment); |
| environment->GetLauncher(launcher_.NewRequest()); |
| } |
| |
| RespondingServiceHost::~RespondingServiceHost() {} |
| |
| void RespondingServiceHost::RegisterSingleton( |
| const std::string& service_name, fuchsia::sys::LaunchInfoPtr launch_info) { |
| service_namespace_.AddServiceForName( |
| [this, service_name, launch_info = std::move(launch_info)]( |
| zx::channel client_handle) mutable { |
| FXL_VLOG(2) << "Handling request for service " << service_name; |
| |
| auto iter = service_providers_by_name_.find(service_name); |
| |
| if (iter == service_providers_by_name_.end()) { |
| FXL_VLOG(1) << "Launching " << launch_info->url << " for service " |
| << service_name; |
| |
| // TODO(dalesat): Create application-specific environment. |
| // We're launching this application in the environment supplied to |
| // the constructor. Instead, we should be launching it in a new |
| // environment that is restricted based on app permissions. |
| |
| fuchsia::sys::LaunchInfo dup_launch_info; |
| dup_launch_info.url = launch_info->url; |
| fidl::Clone(launch_info->arguments, &dup_launch_info.arguments); |
| component::Services services; |
| dup_launch_info.directory_request = services.NewRequest(); |
| |
| fuchsia::sys::ComponentControllerPtr controller; |
| launcher_->CreateComponent(std::move(dup_launch_info), |
| controller.NewRequest()); |
| |
| controller.set_error_handler( |
| [this, service_name](zx_status_t status) { |
| FXL_LOG(INFO) |
| << "Service " << service_name << " provider disconnected"; |
| service_providers_by_name_.erase(service_name); |
| }); |
| |
| std::tie(iter, std::ignore) = service_providers_by_name_.emplace( |
| std::make_pair<const std::string&, ServicesHolder>( |
| service_name, {std::move(services), std::move(controller)})); |
| } |
| |
| iter->second.ConnectToService(service_name, std::move(client_handle)); |
| }, |
| service_name); |
| } |
| |
| void RespondingServiceHost::RegisterProvider( |
| const std::string& service_name, |
| fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> handle) { |
| fuchsia::sys::ServiceProviderPtr service_provider = handle.Bind(); |
| |
| service_provider.set_error_handler([this, service_name](zx_status_t status) { |
| FXL_LOG(INFO) << "Service " << service_name << " provider disconnected"; |
| service_providers_by_name_.erase(service_name); |
| }); |
| |
| service_providers_by_name_.emplace(service_name, std::move(service_provider)); |
| |
| service_namespace_.AddServiceForName( |
| [this, service_name](zx::channel client_handle) { |
| FXL_VLOG(2) << "Servicing provided service request for " |
| << service_name; |
| auto iter = service_providers_by_name_.find(service_name); |
| FXL_DCHECK(iter != service_providers_by_name_.end()); |
| iter->second.ConnectToService(service_name, std::move(client_handle)); |
| }, |
| service_name); |
| } |
| |
| void RespondingServiceHost::ServicesHolder::ConnectToService( |
| const std::string& service_name, zx::channel c) { |
| if (is_service_provider_) { |
| service_provider_->ConnectToService(service_name, std::move(c)); |
| return; |
| } |
| |
| services_.ConnectToService(std::move(c), service_name); |
| } |
| |
| } // namespace netconnector |