| // Copyright 2017 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 "peridot/lib/fidl/app_client.h" |
| |
| #include <fcntl.h> |
| |
| #include <fuchsia/sys/cpp/fidl.h> |
| #include <lib/fdio/limits.h> |
| #include <lib/fdio/util.h> |
| #include <lib/fsl/io/fd.h> |
| #include <lib/fxl/files/directory.h> |
| #include <lib/fxl/files/unique_fd.h> |
| #include <zircon/processargs.h> |
| |
| namespace modular { |
| AppClientBase::AppClientBase(fuchsia::sys::Launcher* const launcher, |
| fuchsia::modular::AppConfig config, |
| std::string data_origin, |
| fuchsia::sys::ServiceListPtr additional_services) |
| : AsyncHolderBase(config.url) { |
| fuchsia::sys::LaunchInfo launch_info; |
| launch_info.directory_request = services_.NewRequest(); |
| launch_info.url = config.url; |
| std::vector<std::string> args; |
| for (const auto& arg : *config.args) { |
| launch_info.arguments.push_back(arg); |
| } |
| |
| if (!data_origin.empty()) { |
| if (!files::CreateDirectory(data_origin)) { |
| FXL_LOG(ERROR) << "Unable to create directory at " << data_origin; |
| return; |
| } |
| launch_info.flat_namespace = fuchsia::sys::FlatNamespace::New(); |
| launch_info.flat_namespace->paths.push_back("/data"); |
| |
| fxl::UniqueFD dir(open(data_origin.c_str(), O_DIRECTORY | O_RDONLY)); |
| if (!dir.is_valid()) { |
| FXL_LOG(ERROR) << "Unable to open directory at " << data_origin |
| << ". errno: " << errno; |
| return; |
| } |
| |
| launch_info.flat_namespace->directories.push_back( |
| fsl::CloneChannelFromFileDescriptor(dir.get())); |
| if (!launch_info.flat_namespace->directories.at(0)) { |
| FXL_LOG(ERROR) << "Unable create a handle from " << data_origin; |
| return; |
| } |
| } |
| |
| if (additional_services) { |
| launch_info.additional_services = std::move(additional_services); |
| } |
| launcher->CreateComponent(std::move(launch_info), app_.NewRequest()); |
| } |
| |
| AppClientBase::~AppClientBase() = default; |
| |
| void AppClientBase::ImplTeardown(std::function<void()> done) { |
| ServiceTerminate(std::move(done)); |
| } |
| |
| void AppClientBase::ImplReset() { |
| app_.Unbind(); |
| ServiceUnbind(); |
| } |
| |
| void AppClientBase::SetAppErrorHandler( |
| const std::function<void()>& error_handler) { |
| app_.set_error_handler( |
| [error_handler](zx_status_t status) { error_handler(); }); |
| } |
| |
| void AppClientBase::ServiceTerminate(const std::function<void()>& /* done */) {} |
| |
| void AppClientBase::ServiceUnbind() {} |
| |
| template <> |
| void AppClient<fuchsia::modular::Lifecycle>::ServiceTerminate( |
| const std::function<void()>& done) { |
| SetAppErrorHandler(done); |
| if (primary_service()) |
| primary_service()->Terminate(); |
| } |
| |
| } // namespace modular |