[flutter] Remove runner dependency on libfs.

Bug: DX-1069
Change-Id: If96807d09b27e79bf0db7355504fbe8a4e8ada0a
diff --git a/runtime/flutter_runner/BUILD.gn b/runtime/flutter_runner/BUILD.gn
index cd3130e..ed56073 100644
--- a/runtime/flutter_runner/BUILD.gn
+++ b/runtime/flutter_runner/BUILD.gn
@@ -151,7 +151,6 @@
              "//zircon/public/fidl/fuchsia-io",
              "//zircon/public/lib/async-cpp",
              "//zircon/public/lib/async-loop-cpp",
-             "//zircon/public/lib/fs",
              "//zircon/public/lib/trace",
              "//zircon/public/lib/trace-provider",
              "//zircon/public/lib/zx",
diff --git a/runtime/flutter_runner/component.cc b/runtime/flutter_runner/component.cc
index 6bd3fe1..cafcdae 100644
--- a/runtime/flutter_runner/component.cc
+++ b/runtime/flutter_runner/component.cc
@@ -5,11 +5,12 @@
 #include "component.h"
 
 #include <dlfcn.h>
-#include <fs/pseudo-dir.h>
-#include <fs/remote-dir.h>
+#include <lib/async/cpp/task.h>
 #include <lib/async-loop/cpp/loop.h>
 #include <lib/fdio/directory.h>
 #include <lib/fdio/namespace.h>
+#include <lib/vfs/cpp/remote_dir.h>
+#include <lib/vfs/cpp/service.h>
 #include <sys/stat.h>
 #include <zircon/dlfcn.h>
 #include <zircon/status.h>
@@ -77,8 +78,7 @@
     : termination_callback_(std::move(termination_callback)),
       debug_label_(DebugLabelForURL(startup_info.launch_info.url)),
       application_controller_(this),
-      outgoing_dir_(fbl::AdoptRef(new fs::PseudoDir())),
-      outgoing_vfs_(async_get_default_dispatcher()),
+      outgoing_dir_(new vfs::PseudoDir()),
       runner_incoming_services_(runner_incoming_services) {
   application_controller_.set_error_handler(
       [this](zx_status_t status) { Kill(); });
@@ -145,24 +145,21 @@
 
   // LaunchInfo::service_request optional.
   if (launch_info.directory_request) {
-    outgoing_vfs_.ServeDirectory(outgoing_dir_,
-                                 std::move(launch_info.directory_request));
+    outgoing_dir_->Serve(fuchsia::io::OPEN_FLAG_DIRECTORY,
+                         std::move(launch_info.directory_request));
   }
 
   directory_request_ = directory_ptr_.NewRequest();
 
-  fbl::RefPtr<ServiceProviderDir> service_provider_dir =
-      fbl::AdoptRef(new ServiceProviderDir);
-  outgoing_dir_->AddEntry("public", service_provider_dir);
-
   fidl::InterfaceHandle<fuchsia::io::Directory> flutter_public_dir;
-
   // TODO(anmittal): when fixing enumeration using new c++ vfs, make sure that
   // flutter_public_dir is only accessed once we recieve OnOpen Event.
   // That will prevent FL-175 for public directory
   auto request = flutter_public_dir.NewRequest().TakeChannel();
   fdio_service_connect_at(directory_ptr_.channel().get(), "public",
                           request.release());
+
+  auto service_provider_dir = std::make_unique<ServiceProviderDir>();
   service_provider_dir->set_fallback(std::move(flutter_public_dir));
 
   // Clone and check if client is servicing the directory.
@@ -188,7 +185,7 @@
           fdio_service_connect_at(directory_ptr_.channel().get(), dir_str,
                                   request.release());
           outgoing_dir_->AddEntry(
-              dir_str, fbl::AdoptRef(new fs::RemoteDir(dir.TakeChannel())));
+              dir_str, std::make_unique<vfs::RemoteDir>(dir.TakeChannel()));
         }
       };
 
@@ -203,21 +200,23 @@
 
   service_provider_dir->AddService(
       fuchsia::ui::viewsv1::ViewProvider::Name_,
-      fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
+      std::make_unique<vfs::Service>([this](zx::channel channel,
+                                            async_dispatcher_t* dispatcher) {
         v1_shells_bindings_.AddBinding(
             this, fidl::InterfaceRequest<fuchsia::ui::viewsv1::ViewProvider>(
                       std::move(channel)));
-        return ZX_OK;
-      })));
+      }));
 
   service_provider_dir->AddService(
       fuchsia::ui::app::ViewProvider::Name_,
-      fbl::AdoptRef(new fs::Service([this](zx::channel channel) {
+      std::make_unique<vfs::Service>([this](zx::channel channel,
+                                            async_dispatcher_t* dispatcher) {
         shells_bindings_.AddBinding(
             this, fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(
                       std::move(channel)));
-        return ZX_OK;
-      })));
+      }));
+
+  outgoing_dir_->AddEntry("public", std::move(service_provider_dir));
 
   // Setup the application controller binding.
   if (application_controller_request) {
diff --git a/runtime/flutter_runner/component.h b/runtime/flutter_runner/component.h
index ef518e4..3e00c68 100644
--- a/runtime/flutter_runner/component.h
+++ b/runtime/flutter_runner/component.h
@@ -9,8 +9,6 @@
 #include <memory>
 #include <set>
 
-#include <fs/pseudo-dir.h>
-#include <fs/synchronous-vfs.h>
 #include <fuchsia/io/cpp/fidl.h>
 #include <fuchsia/sys/cpp/fidl.h>
 #include <fuchsia/ui/app/cpp/fidl.h>
@@ -21,6 +19,7 @@
 #include <lib/fit/function.h>
 #include <lib/sys/cpp/service_directory.h>
 #include <lib/sys/cpp/component_context.h>
+#include <lib/vfs/cpp/pseudo_dir.h>
 #include <lib/zx/eventpair.h>
 
 #include "engine.h"
@@ -74,8 +73,7 @@
   fuchsia::io::DirectoryPtr directory_ptr_;
   fuchsia::io::NodePtr cloned_directory_ptr_;
   fidl::InterfaceRequest<fuchsia::io::Directory> directory_request_;
-  fbl::RefPtr<fs::PseudoDir> outgoing_dir_;
-  fs::SynchronousVfs outgoing_vfs_;
+  std::unique_ptr<vfs::PseudoDir> outgoing_dir_;
   std::unique_ptr<sys::ComponentContext> component_context_;
   std::shared_ptr<sys::ServiceDirectory> runner_incoming_services_;
   fidl::BindingSet<fuchsia::ui::app::ViewProvider> shells_bindings_;
diff --git a/runtime/flutter_runner/runner.cc b/runtime/flutter_runner/runner.cc
index 68541b7..f4bd0bd 100644
--- a/runtime/flutter_runner/runner.cc
+++ b/runtime/flutter_runner/runner.cc
@@ -4,6 +4,7 @@
 
 #include "runner.h"
 
+#include <lib/async/cpp/task.h>
 #include <trace-engine/instrumentation.h>
 #include <zircon/status.h>
 #include <zircon/types.h>
diff --git a/runtime/flutter_runner/service_provider_dir.cc b/runtime/flutter_runner/service_provider_dir.cc
index 94dc96e..d15d3fc 100644
--- a/runtime/flutter_runner/service_provider_dir.cc
+++ b/runtime/flutter_runner/service_provider_dir.cc
@@ -10,8 +10,7 @@
 
 namespace flutter {
 
-ServiceProviderDir::ServiceProviderDir()
-    : root_(fbl::AdoptRef(new fs::PseudoDir)), weak_factory_(this) {}
+ServiceProviderDir::ServiceProviderDir() : root_(new vfs::PseudoDir()) {}
 
 ServiceProviderDir::~ServiceProviderDir() {}
 
@@ -21,38 +20,43 @@
 }
 
 void ServiceProviderDir::AddService(const std::string& service_name,
-                                    fbl::RefPtr<fs::Service> service) {
+                                    std::unique_ptr<vfs::Service> service) {
   root_->AddEntry(service_name, std::move(service));
 }
 
-zx_status_t ServiceProviderDir::Getattr(vnattr_t* a) {
-  return root_->Getattr(a);
+zx_status_t ServiceProviderDir::GetAttr(
+    fuchsia::io::NodeAttributes* out_attributes) const {
+  return root_->GetAttr(out_attributes);
 }
 
-zx_status_t ServiceProviderDir::Readdir(fs::vdircookie_t* cookie, void* dirents,
-                                        size_t len, size_t* out_actual) {
+zx_status_t ServiceProviderDir::Readdir(uint64_t offset, void* data,
+                                        uint64_t len, uint64_t* out_offset,
+                                        uint64_t* out_actual) {
   // TODO(anmittal): enumerate fallback_dir_ in future once we have simple
   // implementation of fuchsia.io.Directory.
-  return root_->Readdir(cookie, dirents, len, out_actual);
+  return root_->Readdir(offset, data, len, out_offset, out_actual);
 }
 
-zx_status_t ServiceProviderDir::Lookup(fbl::RefPtr<fs::Vnode>* out,
-                                       fbl::StringPiece name) {
-  zx_status_t status = root_->Lookup(out, name);
+zx_status_t ServiceProviderDir::Lookup(const std::string& name,
+                                       vfs::Node** out) const {
+  zx_status_t status = root_->Lookup(name, out);
   if (status == ZX_OK) {
     return status;
   }
   if (fallback_dir_) {
-    *out = fbl::AdoptRef(new fs::Service(
-        [name = std::string(name.data(), name.length()),
-         ptr = weak_factory_.GetWeakPtr()](zx::channel request) {
-          if (ptr) {
-            fdio_service_connect_at(ptr->fallback_dir_.get(), name.c_str(),
-                                    request.release());
-            return ZX_OK;
-          }
-          return ZX_ERR_NOT_FOUND;
-        }));
+    auto entry = fallback_services_.find(name);
+    if (entry != fallback_services_.end()) {
+      *out = entry->second.get();
+    } else {
+      auto service = std::make_unique<vfs::Service>(
+          [name = std::string(name.data(), name.length()),
+           dir = &fallback_dir_](zx::channel request,
+                                 async_dispatcher_t* dispatcher) {
+        fdio_service_connect_at(dir->get(), name.c_str(), request.release());
+      });
+      *out = service.get();
+      fallback_services_[name] = std::move(service);
+    }
   } else {
     return ZX_ERR_NOT_FOUND;
   }
diff --git a/runtime/flutter_runner/service_provider_dir.h b/runtime/flutter_runner/service_provider_dir.h
index 2de44d7..7bd59bc 100644
--- a/runtime/flutter_runner/service_provider_dir.h
+++ b/runtime/flutter_runner/service_provider_dir.h
@@ -5,29 +5,28 @@
 #ifndef TOPAZ_RUNTIME_FLUTTER_RUNNER_SERVICE_PROVIDER_DIR_H_
 #define TOPAZ_RUNTIME_FLUTTER_RUNNER_SERVICE_PROVIDER_DIR_H_
 
+#include <map>
 #include <string>
 #include <unordered_set>
 #include <utility>
 #include <vector>
 
-#include <fs/pseudo-dir.h>
-#include <fs/service.h>
-#include <fs/synchronous-vfs.h>
 #include <fuchsia/io/cpp/fidl.h>
 #include <fuchsia/sys/cpp/fidl.h>
+#include <lib/vfs/cpp/pseudo_dir.h>
+#include <lib/vfs/cpp/service.h>
 
 #include "lib/fidl/cpp/binding_set.h"
 #include "lib/fxl/logging.h"
 #include "lib/fxl/macros.h"
-#include "lib/fxl/memory/weak_ptr.h"
 
 namespace flutter {
 
-// A directory-like object which dynamically creates Service vnodes
+// A directory-like object which dynamically creates Service nodes
 // for any file lookup. It also exposes service provider interface.
 //
 // It supports enumeration for only first level of services.
-class ServiceProviderDir : public fs::Vnode {
+class ServiceProviderDir : public vfs::Directory {
  public:
   ServiceProviderDir();
   ~ServiceProviderDir() override;
@@ -35,25 +34,33 @@
   void set_fallback(fidl::InterfaceHandle<fuchsia::io::Directory> fallback_dir);
 
   void AddService(const std::string& service_name,
-                  fbl::RefPtr<fs::Service> service);
+                  std::unique_ptr<vfs::Service> service);
 
   //
-  // Overridden from |fs::Vnode|:
+  // Overridden from |vfs::Node|:
   //
 
-  zx_status_t Lookup(fbl::RefPtr<fs::Vnode>* out, fbl::StringPiece name) final;
+  zx_status_t Lookup(const std::string& name, vfs::Node** out_node) const final;
 
-  zx_status_t Getattr(vnattr_t* a) final;
+  zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const final;
 
-  zx_status_t Readdir(fs::vdircookie_t* cookie, void* dirents, size_t len,
-                      size_t* out_actual) final;
+  zx_status_t Readdir(uint64_t offset, void* data, uint64_t len,
+                      uint64_t* out_offset, uint64_t* out_actual) final;
 
  private:
   // |root_| has all services offered by this provider (including those
   // inherited from the parent, if any).
-  fbl::RefPtr<fs::PseudoDir> root_;
+  std::unique_ptr<vfs::PseudoDir> root_;
   zx::channel fallback_dir_;
-  fxl::WeakPtrFactory<ServiceProviderDir> weak_factory_;
+  // The collection of services that have been looked up on the fallback
+  // directory. These services are just passthrough in the sense that they
+  // forward connection requests to the fallback directory. Since there is no
+  // good way in the present context to know whether these service entries
+  // actually match an existing service, and since the present object must own
+  // these entries, we keep them around until the present object gets deleted.
+  // Needs to be marked mutable so that it can be altered by the Lookup method.
+  mutable std::map<std::string,
+                   std::unique_ptr<vfs::Service>> fallback_services_;
 
   FXL_DISALLOW_COPY_AND_ASSIGN(ServiceProviderDir);
 };