Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame^] | 1 | // Copyright 2019 The Chromium Authors |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 2 | // 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 Drissman | 933398e | 2022-01-22 00:55:42 | [diff] [blame] | 7 | #include <tuple> |
| 8 | |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 9 | #include <fuchsia/io/cpp/fidl.h> |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 10 | #include <lib/sys/cpp/outgoing_directory.h> |
| 11 | #include <lib/sys/cpp/service_directory.h> |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 12 | |
David Dorwin | 3f503b8 | 2022-04-20 04:07:03 | [diff] [blame] | 13 | #include "base/check_op.h" |
Sergey Ulanov | 278b19f | 2019-03-12 00:19:59 | [diff] [blame] | 14 | #include "base/fuchsia/file_utils.h" |
David Dorwin | 37fad18d | 2021-04-08 15:03:01 | [diff] [blame] | 15 | #include "base/fuchsia/fuchsia_logging.h" |
Hans Wennborg | 9f3bb63d | 2020-04-21 11:12:38 | [diff] [blame] | 16 | #include "base/logging.h" |
Sergey Ulanov | 278b19f | 2019-03-12 00:19:59 | [diff] [blame] | 17 | |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 18 | namespace base { |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 19 | |
Tamir Duberstein | bf7bf29 | 2022-03-25 16:48:45 | [diff] [blame] | 20 | StartupContext::StartupContext(fuchsia::sys::StartupInfo startup_info) { |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 21 | std::unique_ptr<sys::ServiceDirectory> incoming_services; |
| 22 | |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 23 | // Component manager generates |flat_namespace|, so things are horribly broken |
| 24 | // if |flat_namespace| is malformed. |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 25 | CHECK_EQ(startup_info.flat_namespace.directories.size(), |
| 26 | startup_info.flat_namespace.paths.size()); |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 27 | |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 28 | // 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])); |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 33 | break; |
| 34 | } |
| 35 | } |
Wez | 669a04e0 | 2019-02-20 18:53:24 | [diff] [blame] | 36 | |
Wez | 4e3dbc1 | 2019-03-06 18:47:24 | [diff] [blame] | 37 | // TODO(https://crbug.com/933834): Remove these workarounds when we migrate to |
Wez | 669a04e0 | 2019-02-20 18:53:24 | [diff] [blame] | 38 | // the new component manager. |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 39 | if (!incoming_services && startup_info.launch_info.flat_namespace) { |
Wez | 669a04e0 | 2019-02-20 18:53:24 | [diff] [blame] | 40 | LOG(WARNING) << "Falling back to LaunchInfo namespace"; |
| 41 | for (size_t i = 0; |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 42 | i < startup_info.launch_info.flat_namespace->paths.size(); ++i) { |
| 43 | if (startup_info.launch_info.flat_namespace->paths[i] == |
Sergey Ulanov | 278b19f | 2019-03-12 00:19:59 | [diff] [blame] | 44 | kServiceDirectoryPath) { |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 45 | incoming_services = std::make_unique<sys::ServiceDirectory>( |
| 46 | std::move(startup_info.launch_info.flat_namespace->directories[i])); |
Wez | 669a04e0 | 2019-02-20 18:53:24 | [diff] [blame] | 47 | break; |
| 48 | } |
| 49 | } |
| 50 | } |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 51 | |
| 52 | if (!incoming_services && startup_info.launch_info.additional_services) { |
Wez | 4e3dbc1 | 2019-03-06 18:47:24 | [diff] [blame] | 53 | LOG(WARNING) << "Falling back to additional ServiceList services"; |
| 54 | |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 55 | // Construct a OutgoingDirectory and publish the additional services into |
| 56 | // it. |
Wez | 4e3dbc1 | 2019-03-06 18:47:24 | [diff] [blame] | 57 | additional_services_.Bind( |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 58 | 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 Dorwin | 37fad18d | 2021-04-08 15:03:01 | [diff] [blame] | 61 | zx_status_t status = additional_services_directory_->AddPublicService( |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 62 | 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 Dorwin | 37fad18d | 2021-04-08 15:03:01 | [diff] [blame] | 68 | ZX_CHECK(status == ZX_OK, status) |
| 69 | << "AddPublicService(" << name << ") failed"; |
Wez | 4e3dbc1 | 2019-03-06 18:47:24 | [diff] [blame] | 70 | } |
| 71 | |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 72 | // Publish those services to the caller as |incoming_services|. |
Tamir Duberstein | bf7bf29 | 2022-03-25 16:48:45 | [diff] [blame] | 73 | fidl::InterfaceHandle<fuchsia::io::Directory> incoming_directory; |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 74 | additional_services_directory_->GetOrCreateDirectory("svc")->Serve( |
Tamir Duberstein | 48b694c | 2022-03-30 17:04:56 | [diff] [blame] | 75 | fuchsia::io::OpenFlags::RIGHT_READABLE | |
| 76 | fuchsia::io::OpenFlags::RIGHT_WRITABLE, |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 77 | incoming_directory.NewRequest().TakeChannel()); |
| 78 | incoming_services = |
| 79 | std::make_unique<sys::ServiceDirectory>(std::move(incoming_directory)); |
Wez | 4e3dbc1 | 2019-03-06 18:47:24 | [diff] [blame] | 80 | } |
Sergey Ulanov | 9f8e78a | 2019-06-19 22:41:29 | [diff] [blame] | 81 | |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 82 | if (!incoming_services) { |
Sergey Ulanov | 9f8e78a | 2019-06-19 22:41:29 | [diff] [blame] | 83 | LOG(WARNING) << "Component started without a service directory"; |
| 84 | |
Wez | eba2d0ab | 2020-02-04 18:03:45 | [diff] [blame] | 85 | // Create a dummy ServiceDirectory with a channel that's not |
Sergey Ulanov | 9f8e78a | 2019-06-19 22:41:29 | [diff] [blame] | 86 | // connected on the other end. |
Tamir Duberstein | bf7bf29 | 2022-03-25 16:48:45 | [diff] [blame] | 87 | fidl::InterfaceHandle<fuchsia::io::Directory> dummy_directory; |
Avi Drissman | 933398e | 2022-01-22 00:55:42 | [diff] [blame] | 88 | std::ignore = dummy_directory.NewRequest(); |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 89 | incoming_services = |
| 90 | std::make_unique<sys::ServiceDirectory>(std::move(dummy_directory)); |
Sergey Ulanov | 9f8e78a | 2019-06-19 22:41:29 | [diff] [blame] | 91 | } |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 92 | |
| 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); |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 97 | } |
| 98 | |
Sergey Ulanov | d81f26f | 2019-08-13 01:54:08 | [diff] [blame] | 99 | StartupContext::~StartupContext() = default; |
| 100 | |
| 101 | void StartupContext::ServeOutgoingDirectory() { |
| 102 | DCHECK(outgoing_directory_request_); |
| 103 | component_context_->outgoing()->Serve(std::move(outgoing_directory_request_)); |
Sergey Ulanov | bdb0f955 | 2019-07-27 00:41:22 | [diff] [blame] | 104 | } |
| 105 | |
Wez | 4798d085 | 2019-02-15 20:28:14 | [diff] [blame] | 106 | } // namespace base |