test_component_context_for_process.cc 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/fuchsia/test_component_context_for_process.h"
  5. #include <fuchsia/io/cpp/fidl.h>
  6. #include <lib/fdio/directory.h>
  7. #include <lib/fidl/cpp/interface_handle.h>
  8. #include <lib/sys/cpp/component_context.h>
  9. #include "base/files/file_enumerator.h"
  10. #include "base/fuchsia/filtered_service_directory.h"
  11. #include "base/fuchsia/fuchsia_logging.h"
  12. #include "base/fuchsia/process_context.h"
  13. #include "base/run_loop.h"
  14. namespace base {
  15. TestComponentContextForProcess::TestComponentContextForProcess(
  16. InitialState initial_state) {
  17. // TODO(https://crbug.com/1038786): Migrate to sys::ComponentContextProvider
  18. // once it provides access to an sys::OutgoingDirectory or PseudoDir through
  19. // which to publish additional_services().
  20. // Set up |incoming_services_| to use the ServiceDirectory from the current
  21. // default ComponentContext to fetch services from.
  22. context_services_ = std::make_unique<FilteredServiceDirectory>(
  23. base::ComponentContextForProcess()->svc());
  24. // Push all services from /svc to the test context if requested.
  25. if (initial_state == InitialState::kCloneAll) {
  26. base::FileEnumerator file_enum(base::FilePath("/svc"), false,
  27. base::FileEnumerator::FILES);
  28. for (auto file = file_enum.Next(); !file.empty(); file = file_enum.Next()) {
  29. AddService(file.BaseName().value());
  30. }
  31. }
  32. // Create a ServiceDirectory backed by the contents of |incoming_directory|.
  33. fidl::InterfaceHandle<::fuchsia::io::Directory> incoming_directory;
  34. zx_status_t status =
  35. context_services_->ConnectClient(incoming_directory.NewRequest());
  36. ZX_CHECK(status == ZX_OK, status) << "ConnectClient failed";
  37. auto incoming_services =
  38. std::make_shared<sys::ServiceDirectory>(std::move(incoming_directory));
  39. // Create the ComponentContext with the incoming directory connected to the
  40. // directory of |context_services_| published by the test, and with a request
  41. // for the process' root outgoing directory.
  42. fidl::InterfaceHandle<::fuchsia::io::Directory> published_root_directory;
  43. old_context_ = ReplaceComponentContextForProcessForTest(
  44. std::make_unique<sys::ComponentContext>(
  45. std::move(incoming_services),
  46. published_root_directory.NewRequest().TakeChannel()));
  47. // Connect to the "/svc" directory of the |published_root_directory| and wrap
  48. // that into a ServiceDirectory.
  49. fidl::InterfaceHandle<::fuchsia::io::Directory> published_services;
  50. status = fdio_service_connect_at(
  51. published_root_directory.channel().get(), "svc",
  52. published_services.NewRequest().TakeChannel().release());
  53. ZX_CHECK(status == ZX_OK, status) << "fdio_service_connect_at() to /svc";
  54. published_services_ =
  55. std::make_unique<sys::ServiceDirectory>(std::move(published_services));
  56. }
  57. TestComponentContextForProcess::~TestComponentContextForProcess() {
  58. ReplaceComponentContextForProcessForTest(std::move(old_context_));
  59. }
  60. sys::OutgoingDirectory* TestComponentContextForProcess::additional_services() {
  61. return context_services_->outgoing_directory();
  62. }
  63. void TestComponentContextForProcess::AddService(
  64. const base::StringPiece service) {
  65. zx_status_t status = context_services_->AddService(service);
  66. ZX_CHECK(status == ZX_OK, status) << "AddService(" << service << ") failed";
  67. }
  68. void TestComponentContextForProcess::AddServices(
  69. base::span<const base::StringPiece> services) {
  70. for (auto service : services)
  71. AddService(service);
  72. }
  73. } // namespace base