| // Copyright 2019 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 <lib/modular/testing/cpp/fake_component.h> |
| |
| namespace modular_testing { |
| namespace { |
| constexpr char kServiceRootPath[] = "/svc"; |
| |
| std::unique_ptr<sys::ComponentContext> CreateComponentContext( |
| fuchsia::sys::StartupInfo* startup_info, async_dispatcher_t* dispatcher) { |
| fuchsia::sys::FlatNamespace& flat = startup_info->flat_namespace; |
| if (flat.paths.size() != flat.directories.size()) { |
| return nullptr; |
| } |
| |
| zx::channel service_root; |
| for (size_t i = 0; i < flat.paths.size(); ++i) { |
| if (flat.paths.at(i) == kServiceRootPath) { |
| service_root = std::move(flat.directories.at(i)); |
| break; |
| } |
| } |
| |
| return std::make_unique<sys::ComponentContext>( |
| std::make_unique<sys::ServiceDirectory>(std::move(service_root)), dispatcher); |
| } |
| } // namespace |
| |
| FakeComponent::FakeComponent(Args args) : args_(std::move(args)) {} |
| FakeComponent::~FakeComponent() = default; |
| |
| modular_testing::TestHarnessBuilder::InterceptOptions FakeComponent::BuildInterceptOptions( |
| async_dispatcher_t* dispatcher) { |
| modular_testing::TestHarnessBuilder::InterceptOptions options; |
| options.url = args_.url; |
| options.sandbox_services = args_.sandbox_services; |
| options.launch_handler = |
| [this, dispatcher](fuchsia::sys::StartupInfo startup_info, |
| fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent> |
| intercepted_component) { |
| intercepted_component_ptr_.Bind(std::move(intercepted_component), dispatcher); |
| intercepted_component_ptr_.events().OnKill = [this] { |
| component_context_.reset(); |
| OnDestroy(); |
| }; |
| |
| component_context_ = CreateComponentContext(&startup_info, dispatcher); |
| component_context_->outgoing()->AddPublicService( |
| lifecycle_bindings_.GetHandler(this, dispatcher)); |
| |
| // Serve the outgoing directory once OnCreateAsync finishes. |
| auto serve_outgoing = [this, |
| outgoing_directory_request = |
| std::move(startup_info.launch_info.directory_request), |
| dispatcher]() mutable { |
| component_context_->outgoing()->Serve(std::move(outgoing_directory_request), dispatcher); |
| }; |
| |
| OnCreateAsync(std::move(startup_info), std::move(serve_outgoing)); |
| }; |
| |
| return options; |
| } |
| |
| std::string FakeComponent::url() const { return args_.url; } |
| bool FakeComponent::is_running() const { return !!component_context_; } |
| |
| sys::ComponentContext* FakeComponent::component_context() { return component_context_.get(); } |
| const sys::ComponentContext* FakeComponent::component_context() const { |
| return component_context_.get(); |
| } |
| |
| void FakeComponent::Exit(int64_t exit_code, fuchsia::sys::TerminationReason reason) { |
| if (intercepted_component_ptr_) { |
| intercepted_component_ptr_->Exit(exit_code, reason); |
| } |
| } |
| |
| void FakeComponent::Terminate() { Exit(0); } |
| |
| } // namespace modular_testing |