1 // Copyright 2013 The Flutter 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
5 #include "service_provider_dir.h"
6
7 #include <lib/async/default.h>
8 #include <lib/fdio/directory.h>
9 #include <zircon/status.h>
10
11 namespace flutter_runner {
12
ServiceProviderDir()13 ServiceProviderDir::ServiceProviderDir() : root_(new vfs::PseudoDir()) {}
14
~ServiceProviderDir()15 ServiceProviderDir::~ServiceProviderDir() {}
16
set_fallback(fidl::InterfaceHandle<fuchsia::io::Directory> fallback_dir)17 void ServiceProviderDir::set_fallback(
18 fidl::InterfaceHandle<fuchsia::io::Directory> fallback_dir) {
19 fallback_dir_ = fallback_dir.TakeChannel();
20 }
21
AddService(const std::string & service_name,std::unique_ptr<vfs::Service> service)22 void ServiceProviderDir::AddService(const std::string& service_name,
23 std::unique_ptr<vfs::Service> service) {
24 root_->AddEntry(service_name, std::move(service));
25 }
26
GetAttr(fuchsia::io::NodeAttributes * out_attributes) const27 zx_status_t ServiceProviderDir::GetAttr(
28 fuchsia::io::NodeAttributes* out_attributes) const {
29 return root_->GetAttr(out_attributes);
30 }
31
Readdir(uint64_t offset,void * data,uint64_t len,uint64_t * out_offset,uint64_t * out_actual)32 zx_status_t ServiceProviderDir::Readdir(uint64_t offset,
33 void* data,
34 uint64_t len,
35 uint64_t* out_offset,
36 uint64_t* out_actual) {
37 // TODO(anmittal): enumerate fallback_dir_ in future once we have simple
38 // implementation of fuchsia.io.Directory.
39 return root_->Readdir(offset, data, len, out_offset, out_actual);
40 }
41
Lookup(const std::string & name,vfs::Node ** out) const42 zx_status_t ServiceProviderDir::Lookup(const std::string& name,
43 vfs::Node** out) const {
44 zx_status_t status = root_->Lookup(name, out);
45 if (status == ZX_OK) {
46 return status;
47 }
48 if (fallback_dir_) {
49 auto entry = fallback_services_.find(name);
50 if (entry != fallback_services_.end()) {
51 *out = entry->second.get();
52 } else {
53 auto service = std::make_unique<vfs::Service>(
54 [name = std::string(name.data(), name.length()),
55 dir = &fallback_dir_](zx::channel request,
56 async_dispatcher_t* dispatcher) {
57 fdio_service_connect_at(dir->get(), name.c_str(),
58 request.release());
59 });
60 *out = service.get();
61 fallback_services_[name] = std::move(service);
62 }
63 } else {
64 return ZX_ERR_NOT_FOUND;
65 }
66 return ZX_OK;
67 }
68
69 } // namespace flutter_runner
70