// Copyright 2020 The Chromium 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 "base/fuchsia/test_component_context_for_process.h" #include #include #include #include #include "base/files/file_enumerator.h" #include "base/fuchsia/filtered_service_directory.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/fuchsia/process_context.h" #include "base/run_loop.h" namespace base { TestComponentContextForProcess::TestComponentContextForProcess( InitialState initial_state) { // TODO(https://crbug.com/1038786): Migrate to sys::ComponentContextProvider // once it provides access to an sys::OutgoingDirectory or PseudoDir through // which to publish additional_services(). // Set up |incoming_services_| to use the ServiceDirectory from the current // default ComponentContext to fetch services from. context_services_ = std::make_unique( base::ComponentContextForProcess()->svc()); // Push all services from /svc to the test context if requested. if (initial_state == InitialState::kCloneAll) { base::FileEnumerator file_enum(base::FilePath("/svc"), false, base::FileEnumerator::FILES); for (auto file = file_enum.Next(); !file.empty(); file = file_enum.Next()) { AddService(file.BaseName().value()); } } // Create a ServiceDirectory backed by the contents of |incoming_directory|. fidl::InterfaceHandle<::fuchsia::io::Directory> incoming_directory; zx_status_t status = context_services_->ConnectClient(incoming_directory.NewRequest()); ZX_CHECK(status == ZX_OK, status) << "ConnectClient failed"; auto incoming_services = std::make_shared(std::move(incoming_directory)); // Create the ComponentContext with the incoming directory connected to the // directory of |context_services_| published by the test, and with a request // for the process' root outgoing directory. fidl::InterfaceHandle<::fuchsia::io::Directory> published_root_directory; old_context_ = ReplaceComponentContextForProcessForTest( std::make_unique( std::move(incoming_services), published_root_directory.NewRequest().TakeChannel())); // Connect to the "/svc" directory of the |published_root_directory| and wrap // that into a ServiceDirectory. fidl::InterfaceHandle<::fuchsia::io::Directory> published_services; status = fdio_service_connect_at( published_root_directory.channel().get(), "svc", published_services.NewRequest().TakeChannel().release()); ZX_CHECK(status == ZX_OK, status) << "fdio_service_connect_at() to /svc"; published_services_ = std::make_unique(std::move(published_services)); } TestComponentContextForProcess::~TestComponentContextForProcess() { ReplaceComponentContextForProcessForTest(std::move(old_context_)); } sys::OutgoingDirectory* TestComponentContextForProcess::additional_services() { return context_services_->outgoing_directory(); } void TestComponentContextForProcess::AddService( const base::StringPiece service) { zx_status_t status = context_services_->AddService(service); ZX_CHECK(status == ZX_OK, status) << "AddService(" << service << ") failed"; } void TestComponentContextForProcess::AddServices( base::span services) { for (auto service : services) AddService(service); } } // namespace base