blob: 8019b361a325cbbedd5dd245677bea8e8a50886f [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2019 The Chromium Authors
Wez4798d0852019-02-15 20:28:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/fuchsia/startup_context.h"
6
Avi Drissman933398e2022-01-22 00:55:427#include <tuple>
8
Wez4798d0852019-02-15 20:28:149#include <fuchsia/io/cpp/fidl.h>
Sergey Ulanovd81f26f2019-08-13 01:54:0810#include <lib/sys/cpp/outgoing_directory.h>
11#include <lib/sys/cpp/service_directory.h>
Wez4798d0852019-02-15 20:28:1412
David Dorwin3f503b82022-04-20 04:07:0313#include "base/check_op.h"
Sergey Ulanov278b19f2019-03-12 00:19:5914#include "base/fuchsia/file_utils.h"
David Dorwin37fad18d2021-04-08 15:03:0115#include "base/fuchsia/fuchsia_logging.h"
Hans Wennborg9f3bb63d2020-04-21 11:12:3816#include "base/logging.h"
Sergey Ulanov278b19f2019-03-12 00:19:5917
Wez4798d0852019-02-15 20:28:1418namespace base {
Wez4798d0852019-02-15 20:28:1419
Tamir Dubersteinbf7bf292022-03-25 16:48:4520StartupContext::StartupContext(fuchsia::sys::StartupInfo startup_info) {
Sergey Ulanovd81f26f2019-08-13 01:54:0821 std::unique_ptr<sys::ServiceDirectory> incoming_services;
22
Wez4798d0852019-02-15 20:28:1423 // Component manager generates |flat_namespace|, so things are horribly broken
24 // if |flat_namespace| is malformed.
Sergey Ulanovd81f26f2019-08-13 01:54:0825 CHECK_EQ(startup_info.flat_namespace.directories.size(),
26 startup_info.flat_namespace.paths.size());
Wez4798d0852019-02-15 20:28:1427
Sergey Ulanovd81f26f2019-08-13 01:54:0828 // Find the /svc directory and wrap it into a sys::ServiceDirectory.
29 for (size_t i = 0; i < startup_info.flat_namespace.paths.size(); ++i) {
30 if (startup_info.flat_namespace.paths[i] == kServiceDirectoryPath) {
31 incoming_services = std::make_unique<sys::ServiceDirectory>(
32 std::move(startup_info.flat_namespace.directories[i]));
Wez4798d0852019-02-15 20:28:1433 break;
34 }
35 }
Wez669a04e02019-02-20 18:53:2436
Wez4e3dbc12019-03-06 18:47:2437 // TODO(https://crbug.com/933834): Remove these workarounds when we migrate to
Wez669a04e02019-02-20 18:53:2438 // the new component manager.
Sergey Ulanovd81f26f2019-08-13 01:54:0839 if (!incoming_services && startup_info.launch_info.flat_namespace) {
Wez669a04e02019-02-20 18:53:2440 LOG(WARNING) << "Falling back to LaunchInfo namespace";
41 for (size_t i = 0;
Sergey Ulanovd81f26f2019-08-13 01:54:0842 i < startup_info.launch_info.flat_namespace->paths.size(); ++i) {
43 if (startup_info.launch_info.flat_namespace->paths[i] ==
Sergey Ulanov278b19f2019-03-12 00:19:5944 kServiceDirectoryPath) {
Sergey Ulanovd81f26f2019-08-13 01:54:0845 incoming_services = std::make_unique<sys::ServiceDirectory>(
46 std::move(startup_info.launch_info.flat_namespace->directories[i]));
Wez669a04e02019-02-20 18:53:2447 break;
48 }
49 }
50 }
Sergey Ulanovd81f26f2019-08-13 01:54:0851
52 if (!incoming_services && startup_info.launch_info.additional_services) {
Wez4e3dbc12019-03-06 18:47:2453 LOG(WARNING) << "Falling back to additional ServiceList services";
54
Sergey Ulanovd81f26f2019-08-13 01:54:0855 // Construct a OutgoingDirectory and publish the additional services into
56 // it.
Wez4e3dbc12019-03-06 18:47:2457 additional_services_.Bind(
Sergey Ulanovd81f26f2019-08-13 01:54:0858 std::move(startup_info.launch_info.additional_services->provider));
59 additional_services_directory_ = std::make_unique<sys::OutgoingDirectory>();
60 for (auto& name : startup_info.launch_info.additional_services->names) {
David Dorwin37fad18d2021-04-08 15:03:0161 zx_status_t status = additional_services_directory_->AddPublicService(
Sergey Ulanovd81f26f2019-08-13 01:54:0862 std::make_unique<vfs::Service>([this, name](
63 zx::channel channel,
64 async_dispatcher_t* dispatcher) {
65 additional_services_->ConnectToService(name, std::move(channel));
66 }),
67 name);
David Dorwin37fad18d2021-04-08 15:03:0168 ZX_CHECK(status == ZX_OK, status)
69 << "AddPublicService(" << name << ") failed";
Wez4e3dbc12019-03-06 18:47:2470 }
71
Sergey Ulanovd81f26f2019-08-13 01:54:0872 // Publish those services to the caller as |incoming_services|.
Tamir Dubersteinbf7bf292022-03-25 16:48:4573 fidl::InterfaceHandle<fuchsia::io::Directory> incoming_directory;
Sergey Ulanovd81f26f2019-08-13 01:54:0874 additional_services_directory_->GetOrCreateDirectory("svc")->Serve(
Tamir Duberstein48b694c2022-03-30 17:04:5675 fuchsia::io::OpenFlags::RIGHT_READABLE |
76 fuchsia::io::OpenFlags::RIGHT_WRITABLE,
Sergey Ulanovd81f26f2019-08-13 01:54:0877 incoming_directory.NewRequest().TakeChannel());
78 incoming_services =
79 std::make_unique<sys::ServiceDirectory>(std::move(incoming_directory));
Wez4e3dbc12019-03-06 18:47:2480 }
Sergey Ulanov9f8e78a2019-06-19 22:41:2981
Sergey Ulanovd81f26f2019-08-13 01:54:0882 if (!incoming_services) {
Sergey Ulanov9f8e78a2019-06-19 22:41:2983 LOG(WARNING) << "Component started without a service directory";
84
Wezeba2d0ab2020-02-04 18:03:4585 // Create a dummy ServiceDirectory with a channel that's not
Sergey Ulanov9f8e78a2019-06-19 22:41:2986 // connected on the other end.
Tamir Dubersteinbf7bf292022-03-25 16:48:4587 fidl::InterfaceHandle<fuchsia::io::Directory> dummy_directory;
Avi Drissman933398e2022-01-22 00:55:4288 std::ignore = dummy_directory.NewRequest();
Sergey Ulanovd81f26f2019-08-13 01:54:0889 incoming_services =
90 std::make_unique<sys::ServiceDirectory>(std::move(dummy_directory));
Sergey Ulanov9f8e78a2019-06-19 22:41:2991 }
Sergey Ulanovd81f26f2019-08-13 01:54:0892
93 component_context_ =
94 std::make_unique<sys::ComponentContext>(std::move(incoming_services));
95 outgoing_directory_request_ =
96 std::move(startup_info.launch_info.directory_request);
Wez4798d0852019-02-15 20:28:1497}
98
Sergey Ulanovd81f26f2019-08-13 01:54:0899StartupContext::~StartupContext() = default;
100
101void StartupContext::ServeOutgoingDirectory() {
102 DCHECK(outgoing_directory_request_);
103 component_context_->outgoing()->Serve(std::move(outgoing_directory_request_));
Sergey Ulanovbdb0f9552019-07-27 00:41:22104}
105
Wez4798d0852019-02-15 20:28:14106} // namespace base