summaryrefslogtreecommitdiffstats
path: root/dom/fs/shared
diff options
context:
space:
mode:
Diffstat (limited to 'dom/fs/shared')
-rw-r--r--dom/fs/shared/FileSystemHelpers.cpp22
-rw-r--r--dom/fs/shared/FileSystemHelpers.h147
-rw-r--r--dom/fs/shared/FileSystemLog.cpp13
-rw-r--r--dom/fs/shared/FileSystemLog.h23
-rw-r--r--dom/fs/shared/FileSystemTypes.h29
-rw-r--r--dom/fs/shared/IPCRejectReporter.cpp36
-rw-r--r--dom/fs/shared/IPCRejectReporter.h20
-rw-r--r--dom/fs/shared/ManagedMozPromiseRequestHolder.h37
-rw-r--r--dom/fs/shared/PFileSystemAccessHandle.ipdl21
-rw-r--r--dom/fs/shared/PFileSystemAccessHandleControl.ipdl18
-rw-r--r--dom/fs/shared/PFileSystemManager.ipdl412
-rw-r--r--dom/fs/shared/PFileSystemWritableFileStream.ipdl23
-rw-r--r--dom/fs/shared/TargetPtrHolder.h58
-rw-r--r--dom/fs/shared/moz.build34
14 files changed, 893 insertions, 0 deletions
diff --git a/dom/fs/shared/FileSystemHelpers.cpp b/dom/fs/shared/FileSystemHelpers.cpp
new file mode 100644
index 0000000000..24f1fc7fb8
--- /dev/null
+++ b/dom/fs/shared/FileSystemHelpers.cpp
@@ -0,0 +1,22 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "FileSystemHelpers.h"
+
+#include "nsString.h"
+
+namespace mozilla::dom::fs {
+
+bool IsValidName(const mozilla::dom::fs::Name& aName) {
+ return !(aName.IsVoid() || aName.Length() == 0 ||
+#ifdef XP_WIN
+ aName.FindChar('\\') != kNotFound ||
+#endif
+ aName.FindChar('/') != kNotFound || aName.EqualsLiteral(".") ||
+ aName.EqualsLiteral(".."));
+}
+
+} // namespace mozilla::dom::fs
diff --git a/dom/fs/shared/FileSystemHelpers.h b/dom/fs/shared/FileSystemHelpers.h
new file mode 100644
index 0000000000..26a820f343
--- /dev/null
+++ b/dom/fs/shared/FileSystemHelpers.h
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DOM_FS_SHARED_FILESYSTEMHELPERS_H_
+#define DOM_FS_SHARED_FILESYSTEMHELPERS_H_
+
+#include "FileSystemTypes.h"
+#include "mozilla/RefPtr.h"
+
+namespace mozilla::dom::fs {
+
+// XXX Consider moving this class template to MFBT.
+
+// A wrapper class template on top of the RefPtr. The RefPtr provides us the
+// automatic reference counting of objects with AddRef() and Release() methods.
+// `Registered` provides automatic registration counting of objects with
+// Register() and Unregister() methods. Registration counting works similarly
+// as reference counting, but objects are not deleted when the number of
+// registrations drops to zero (that's managed by reference counting). Instead,
+// an object can trigger an asynchronous close operation which still needs to
+// hold and use the referenced object. Example:
+//
+// using BoolPromise = MozPromise<bool, nsresult, false>;
+//
+// class MyObject {
+// public:
+// NS_INLINE_DECL_REFCOUNTING(MyObject)
+//
+// void Register() {
+// mRegCnt++;
+// }
+//
+// void Unregister() {
+// mRegCnt--;
+// if (mRegCnt == 0) {
+// BeginClose();
+// }
+// }
+//
+// private:
+// RefPtr<BoolPromise> BeginClose() {
+// return InvokeAsync(mIOTaskQueue, __func__,
+// []() {
+// return BoolPromise::CreateAndResolve(true, __func__);
+// })
+// ->Then(GetCurrentSerialEventTarget(), __func__,
+// [self = RefPtr<MyObject>(this)](
+// const BoolPromise::ResolveOrRejectValue&) {
+// return self->mIOTaskQueue->BeginShutdown();
+// })
+// ->Then(GetCurrentSerialEventTarget(), __func__,
+// [self = RefPtr<MyObject>(this)](
+// const ShutdownPromise::ResolveOrRejectValue&) {
+// return BoolPromise::CreateAndResolve(true, __func__);
+// });
+// }
+//
+// RefPtr<TaskQueue> mIOTaskQueue;
+// uint32_t mRegCnt = 0;
+// };
+
+template <class T>
+class Registered {
+ private:
+ RefPtr<T> mObject;
+
+ public:
+ ~Registered() {
+ if (mObject) {
+ mObject->Unregister();
+ }
+ }
+
+ Registered() = default;
+
+ Registered(const Registered& aOther) : mObject(aOther.mObject) {
+ mObject->Register();
+ }
+
+ Registered(Registered&& aOther) noexcept = default;
+
+ MOZ_IMPLICIT Registered(RefPtr<T> aObject) : mObject(std::move(aObject)) {
+ if (mObject) {
+ mObject->Register();
+ }
+ }
+
+ Registered<T>& operator=(decltype(nullptr)) {
+ RefPtr<T> oldObject = std::move(mObject);
+ mObject = nullptr;
+ if (oldObject) {
+ oldObject->Unregister();
+ }
+ return *this;
+ }
+
+ Registered<T>& operator=(const Registered<T>& aRhs) {
+ if (aRhs.mObject) {
+ aRhs.mObject->Register();
+ }
+ RefPtr<T> oldObject = std::move(mObject);
+ mObject = aRhs.mObject;
+ if (oldObject) {
+ oldObject->Unregister();
+ }
+ return *this;
+ }
+
+ Registered<T>& operator=(Registered<T>&& aRhs) noexcept {
+ RefPtr<T> oldObject = std::move(mObject);
+ mObject = std::move(aRhs.mObject);
+ aRhs.mObject = nullptr;
+ if (oldObject) {
+ oldObject->Unregister();
+ }
+ return *this;
+ }
+
+ const RefPtr<T>& inspect() const { return mObject; }
+
+ RefPtr<T> unwrap() {
+ RefPtr<T> oldObject = std::move(mObject);
+ mObject = nullptr;
+ if (oldObject) {
+ oldObject->Unregister();
+ }
+ return oldObject;
+ }
+
+ T* get() const { return mObject; }
+
+ operator T*() const& { return get(); }
+
+ T* operator->() const { return get(); }
+};
+
+// Spec says valid names don't include (os-dependent) path separators,
+// and is not equal to a dot . or two dots ..
+// We want to use the same validator from both child and parent.
+bool IsValidName(const fs::Name& aName);
+
+} // namespace mozilla::dom::fs
+
+#endif // DOM_FS_SHARED_FILESYSTEMHELPERS_H_
diff --git a/dom/fs/shared/FileSystemLog.cpp b/dom/fs/shared/FileSystemLog.cpp
new file mode 100644
index 0000000000..91afb3fc8f
--- /dev/null
+++ b/dom/fs/shared/FileSystemLog.cpp
@@ -0,0 +1,13 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "FileSystemLog.h"
+
+namespace mozilla {
+
+LazyLogModule gOPFSLog("OPFS");
+
+}
diff --git a/dom/fs/shared/FileSystemLog.h b/dom/fs/shared/FileSystemLog.h
new file mode 100644
index 0000000000..6ea6d4ae77
--- /dev/null
+++ b/dom/fs/shared/FileSystemLog.h
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DOM_FS_SHARED_FILESYSTEMLOG_H_
+#define DOM_FS_SHARED_FILESYSTEMLOG_H_
+
+#include "mozilla/Logging.h"
+
+namespace mozilla {
+extern LazyLogModule gOPFSLog;
+}
+
+#define LOG(args) MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Debug, args)
+
+#define LOG_VERBOSE(args) \
+ MOZ_LOG(mozilla::gOPFSLog, mozilla::LogLevel::Verbose, args)
+
+#define LOG_ENABLED() MOZ_LOG_TEST(mozilla::gOPFSLog, mozilla::LogLevel::Debug)
+
+#endif // DOM_FS_SHARED_FILESYSTEMLOG_H
diff --git a/dom/fs/shared/FileSystemTypes.h b/dom/fs/shared/FileSystemTypes.h
new file mode 100644
index 0000000000..3841698c71
--- /dev/null
+++ b/dom/fs/shared/FileSystemTypes.h
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DOM_FS_FILESYSTEMTYPES_H_
+#define DOM_FS_FILESYSTEMTYPES_H_
+
+#include "nsStringFwd.h"
+
+template <class T>
+class nsTArray;
+
+namespace mozilla::dom::fs {
+
+using ContentType = nsCString;
+using DatabaseVersion = int32_t;
+using EntryId = nsCString;
+using Name = nsString;
+using Origin = nsCString;
+using PageNumber = int32_t;
+using Path = nsTArray<Name>;
+using TimeStamp = int64_t;
+using Usage = int64_t;
+
+} // namespace mozilla::dom::fs
+
+#endif // DOM_FS_FILESYSTEMTYPES_H_
diff --git a/dom/fs/shared/IPCRejectReporter.cpp b/dom/fs/shared/IPCRejectReporter.cpp
new file mode 100644
index 0000000000..6f5f40b95c
--- /dev/null
+++ b/dom/fs/shared/IPCRejectReporter.cpp
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/quota/QuotaCommon.h"
+#include "mozilla/ipc/MessageChannel.h"
+
+namespace mozilla::dom::fs {
+
+// TODO: Find a better way to deal with these errors
+void IPCRejectReporter(mozilla::ipc::ResponseRejectReason aReason) {
+ switch (aReason) {
+ case mozilla::ipc::ResponseRejectReason::ActorDestroyed:
+ // This is ok
+ break;
+ case mozilla::ipc::ResponseRejectReason::HandlerRejected:
+ QM_TRY(OkIf(false), QM_VOID);
+ break;
+ case mozilla::ipc::ResponseRejectReason::ChannelClosed:
+ QM_TRY(OkIf(false), QM_VOID);
+ break;
+ case mozilla::ipc::ResponseRejectReason::ResolverDestroyed:
+ QM_TRY(OkIf(false), QM_VOID);
+ break;
+ case mozilla::ipc::ResponseRejectReason::SendError:
+ QM_TRY(OkIf(false), QM_VOID);
+ break;
+ default:
+ QM_TRY(OkIf(false), QM_VOID);
+ break;
+ }
+}
+
+} // namespace mozilla::dom::fs
diff --git a/dom/fs/shared/IPCRejectReporter.h b/dom/fs/shared/IPCRejectReporter.h
new file mode 100644
index 0000000000..db98ac917c
--- /dev/null
+++ b/dom/fs/shared/IPCRejectReporter.h
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+namespace mozilla {
+
+namespace ipc {
+
+enum class ResponseRejectReason;
+
+} // namespace ipc
+
+namespace dom::fs {
+
+void IPCRejectReporter(mozilla::ipc::ResponseRejectReason aReason);
+
+} // namespace dom::fs
+} // namespace mozilla
diff --git a/dom/fs/shared/ManagedMozPromiseRequestHolder.h b/dom/fs/shared/ManagedMozPromiseRequestHolder.h
new file mode 100644
index 0000000000..1b039577a3
--- /dev/null
+++ b/dom/fs/shared/ManagedMozPromiseRequestHolder.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DOM_FS_SHARED_MANAGEDMOZPROMISEREQUESTHOLDER_H_
+#define DOM_FS_SHARED_MANAGEDMOZPROMISEREQUESTHOLDER_H_
+
+#include "mozilla/MozPromise.h"
+#include "mozilla/RefPtr.h"
+#include "nsISupportsImpl.h"
+
+namespace mozilla::dom::fs {
+
+template <typename Manager, typename PromiseType>
+class ManagedMozPromiseRequestHolder final
+ : public MozPromiseRequestHolder<PromiseType> {
+ public:
+ explicit ManagedMozPromiseRequestHolder(Manager* aManager)
+ : mManager(aManager) {
+ mManager->RegisterPromiseRequestHolder(this);
+ }
+
+ NS_INLINE_DECL_REFCOUNTING(ManagedMozPromiseRequestHolder)
+
+ private:
+ ~ManagedMozPromiseRequestHolder() {
+ mManager->UnregisterPromiseRequestHolder(this);
+ }
+
+ RefPtr<Manager> mManager;
+};
+
+} // namespace mozilla::dom::fs
+
+#endif // DOM_FS_SHARED_MANAGEDMOZPROMISEREQUESTHOLDER_H_
diff --git a/dom/fs/shared/PFileSystemAccessHandle.ipdl b/dom/fs/shared/PFileSystemAccessHandle.ipdl
new file mode 100644
index 0000000000..164f5f9062
--- /dev/null
+++ b/dom/fs/shared/PFileSystemAccessHandle.ipdl
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PFileSystemManager;
+
+namespace mozilla {
+namespace dom {
+
+async protocol PFileSystemAccessHandle
+{
+ manager PFileSystemManager;
+
+ parent:
+ async Close();
+
+ async __delete__();
+};
+
+} // namespace dom
+} // namespace mozilla
diff --git a/dom/fs/shared/PFileSystemAccessHandleControl.ipdl b/dom/fs/shared/PFileSystemAccessHandleControl.ipdl
new file mode 100644
index 0000000000..1380a50e02
--- /dev/null
+++ b/dom/fs/shared/PFileSystemAccessHandleControl.ipdl
@@ -0,0 +1,18 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+using struct mozilla::void_t from "mozilla/ipc/IPCCore.h";
+
+namespace mozilla {
+namespace dom {
+
+async protocol PFileSystemAccessHandleControl
+{
+ parent:
+ async Close()
+ returns(void_t ok);
+};
+
+} // namespace dom
+} // namespace mozilla
diff --git a/dom/fs/shared/PFileSystemManager.ipdl b/dom/fs/shared/PFileSystemManager.ipdl
new file mode 100644
index 0000000000..917e375aaa
--- /dev/null
+++ b/dom/fs/shared/PFileSystemManager.ipdl
@@ -0,0 +1,412 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PFileSystemAccessHandle;
+include protocol PFileSystemAccessHandleControl;
+include protocol PFileSystemWritableFileStream;
+
+include IPCBlob;
+include RandomAccessStreamParams;
+
+using mozilla::dom::fs::ContentType from "mozilla/dom/FileSystemTypes.h";
+using mozilla::dom::fs::EntryId from "mozilla/dom/FileSystemTypes.h";
+using mozilla::dom::fs::Name from "mozilla/dom/FileSystemTypes.h";
+using mozilla::dom::fs::Origin from "mozilla/dom/FileSystemTypes.h";
+using mozilla::dom::fs::PageNumber from "mozilla/dom/FileSystemTypes.h";
+using mozilla::dom::fs::TimeStamp from "mozilla/dom/FileSystemTypes.h";
+using struct mozilla::void_t from "mozilla/ipc/IPCCore.h";
+
+namespace mozilla {
+namespace dom {
+namespace fs {
+
+/**
+ * Identifies a file or a directory and contains its user provided name.
+ */
+struct FileSystemEntryMetadata
+{
+ EntryId entryId;
+ Name entryName;
+ bool directory;
+};
+
+/**
+ * Identifies a file or a directory with its parent identifier and
+ * user provided name.
+ */
+struct FileSystemChildMetadata
+{
+ EntryId parentId;
+ Name childName;
+};
+
+/**
+ * Identifies a file with its parent directory and name, and
+ * indicates whether the file may be created if it is missing.
+ */
+struct FileSystemGetHandleRequest
+{
+ FileSystemChildMetadata handle;
+ bool create;
+};
+
+/**
+ * Contains a file or directory or an error.
+ */
+union FileSystemGetHandleResponse
+{
+ nsresult;
+ EntryId;
+};
+
+/**
+ * Contains an identifier for a parent directory and a page number
+ * which is used to fetch the next set of entries when the directory
+ * contains so many items that communicating all of them in one message
+ * is an impractical.
+ */
+struct FileSystemGetEntriesRequest
+{
+ EntryId parentId;
+ PageNumber page;
+};
+
+/**
+ * Contains a set of directories and files
+ * under the same parent directory.
+ */
+struct FileSystemDirectoryListing
+{
+ FileSystemEntryMetadata[] directories;
+ FileSystemEntryMetadata[] files;
+};
+
+/**
+ * Contains a set of entries or an error.
+ */
+union FileSystemGetEntriesResponse
+{
+ nsresult;
+ FileSystemDirectoryListing;
+};
+
+/**
+ * Contains entry handle information.
+ */
+struct FileSystemGetFileRequest
+{
+ EntryId entryId;
+};
+
+/**
+ * Contains the properties of a file and a file descriptor.
+ * The properties may differ from the properties of the
+ * underlying object of the file descriptor.
+ */
+struct FileSystemFileProperties
+{
+ TimeStamp last_modified_ms;
+ IPCBlob file;
+ ContentType type;
+ Name[] path;
+};
+
+/**
+ * Contains file properties or an error.
+ */
+union FileSystemGetFileResponse
+{
+ nsresult;
+ FileSystemFileProperties;
+};
+
+/**
+ * Contains entry handle information.
+ */
+struct FileSystemGetAccessHandleRequest
+{
+ EntryId entryId;
+};
+
+struct FileSystemAccessHandleProperties
+{
+ RandomAccessStreamParams streamParams;
+ ManagedEndpoint<PFileSystemAccessHandleChild> accessHandleChildEndpoint;
+ Endpoint<PFileSystemAccessHandleControlChild> accessHandleControlChildEndpoint;
+};
+
+union FileSystemGetAccessHandleResponse
+{
+ nsresult;
+ FileSystemAccessHandleProperties;
+};
+
+/**
+ * Contains entry handle information.
+ */
+struct FileSystemGetWritableRequest
+{
+ EntryId entryId;
+ bool keepData;
+};
+
+struct FileSystemWritableFileStreamProperties
+{
+ RandomAccessStreamParams streamParams;
+ PFileSystemWritableFileStream writableFileStream;
+};
+
+union FileSystemGetWritableFileStreamResponse
+{
+ nsresult;
+ FileSystemWritableFileStreamProperties;
+};
+
+/**
+ * Represents a pair of file system entries which
+ * are not necessarily connected by a path.
+ */
+struct FileSystemEntryPair
+{
+ EntryId parentId;
+ EntryId childId;
+};
+
+/**
+ * Contains a pair of file system entries.
+ */
+struct FileSystemResolveRequest
+{
+ FileSystemEntryPair endpoints;
+};
+
+/**
+ * Contains a file system path.
+ */
+struct FileSystemPath
+{
+ Name[] path;
+};
+
+/**
+ * Contains a potentially empty path or an error.
+ */
+union FileSystemResolveResponse
+{
+ nsresult;
+ FileSystemPath?;
+};
+
+/**
+ * Identifies a file with its parent directory and name, and
+ * indicates whether all the children of a directory may be removed.
+ */
+struct FileSystemRemoveEntryRequest
+{
+ FileSystemChildMetadata handle;
+ bool recursive;
+};
+
+/**
+ * Contains an error or nothing.
+ */
+union FileSystemRemoveEntryResponse
+{
+ nsresult;
+ void_t;
+};
+
+/**
+ * Identifies a file/directory to be moved and the new name, and the
+ * destination directory
+ */
+struct FileSystemMoveEntryRequest
+{
+ FileSystemEntryMetadata handle;
+ FileSystemChildMetadata destHandle;
+};
+
+/**
+ * Identifies a file/directory to be renamed and the new name
+ */
+struct FileSystemRenameEntryRequest
+{
+ FileSystemEntryMetadata handle;
+ Name name;
+};
+
+/**
+ * Contains an error or the new entryId
+ */
+union FileSystemMoveEntryResponse
+{
+ nsresult;
+ void_t;
+};
+
+} // namespace fs
+
+async protocol PFileSystemManager
+{
+ manages PFileSystemAccessHandle;
+ manages PFileSystemWritableFileStream;
+
+ parent:
+ /**
+ * TODO: documentation
+ */
+ [VirtualSendImpl]
+ async GetRootHandle()
+ returns(FileSystemGetHandleResponse response);
+
+ /**
+ * Initiates an asynchronous request for the handle of
+ * a subdirectory with a given name under the current directory.
+ *
+ * Invalid names are rejected with an appropriate error.
+ *
+ * If the subdirectory exists, a handle to it is always returned.
+ *
+ * If no child of any kind with the given name exists and
+ * the create-flag of the input is set, the subdirectory will be created,
+ * otherwise an appropriate error is returned.
+ *
+ * @param[in] handle request containing a create flag
+ *
+ * @returns error or entry handle
+ */
+ [VirtualSendImpl]
+ async GetDirectoryHandle(FileSystemGetHandleRequest request)
+ returns(FileSystemGetHandleResponse handle);
+
+ /**
+ * Initiates an asynchronous request for the handle to
+ * a file with a given name under the current directory.
+ *
+ * Invalid names are rejected with an appropriate error.
+ *
+ * If the file exists, a handle to it is always returned.
+ *
+ * If no child of any kind with the given name exists and
+ * the create-flag of the input is set, the file will be created,
+ * otherwise an appropriate error is returned.
+ *
+ * @param[in] handle request containing a create flag
+ *
+ * @returns error or entry handle
+ */
+ [VirtualSendImpl]
+ async GetFileHandle(FileSystemGetHandleRequest request)
+ returns(FileSystemGetHandleResponse handle);
+
+ /**
+ * Initiates an asynchronous request for a read-only object representing the
+ * file corresponding to the current file handle.
+ *
+ * The returned object provides read-only access.
+ *
+ * If the underlying file object is modified through a mutable interface,
+ * the returned value is considered stale. Concurrent changes are not
+ * guaranteed to be visible or invisible. Using a stale object
+ * returns appropriate errors when the results are unpredictable.
+ *
+ * @param[in] request for a file object
+ *
+ * @returns error or file object
+ */
+ [VirtualSendImpl]
+ async GetFile(FileSystemGetFileRequest request)
+ returns(FileSystemGetFileResponse response);
+
+ /**
+ * TODO: documentation
+ */
+ [VirtualSendImpl]
+ async GetAccessHandle(FileSystemGetAccessHandleRequest request)
+ returns(FileSystemGetAccessHandleResponse response);
+
+ /**
+ * TODO: documentation
+ */
+ [VirtualSendImpl]
+ async GetWritable(FileSystemGetWritableRequest request)
+ returns(FileSystemGetWritableFileStreamResponse fileData);
+
+ /**
+ * Initiates an asynchronous request for the file system path
+ * associated with a file system entry.
+ *
+ * @param[in] request identifying a file object
+ *
+ * @returns error or file system path
+ */
+ [VirtualSendImpl]
+ async Resolve(FileSystemResolveRequest request)
+ returns(FileSystemResolveResponse response);
+
+ /**
+ * Initiates an asynchronous request for an iterator to the child entries
+ * under the calling directory handle.
+ *
+ * If the directory item names or the directory structure is modified while
+ * the iterator is in use, the iterator remains safe to use but no guarantees
+ * are made regarding the visibility of the concurrent changes.
+ * It is possible that a file which is added after the iteration has begun
+ * will not be returned, or that among the values there are invalid file
+ * handles whose underlying objects have been removed after the iteration
+ * started.
+ *
+ * @param[in] request for a iterator
+ *
+ * @returns error or iterator
+ */
+ [VirtualSendImpl]
+ async GetEntries(FileSystemGetEntriesRequest request)
+ returns(FileSystemGetEntriesResponse entries);
+
+ /**
+ * Initiates an asynchronous request to delete a directory or file with a
+ * given name under the calling directory handle.
+ *
+ * If recursive flag of the request is not set, a request to remove a
+ * non-empty directory returns an appropriate error, otherwise all the child
+ * files and directories are made to vanish.
+ *
+ * The recursive flag has no impact on files.
+ *
+ * @param[in] request containing a recursive flag
+ *
+ * @returns error information
+ */
+ [VirtualSendImpl]
+ async RemoveEntry(FileSystemRemoveEntryRequest request)
+ returns(FileSystemRemoveEntryResponse response);
+
+ /**
+ * Initiates an asynchronous request to move a directory or file with a
+ * given name to a given destination and new name.
+ *
+ * @returns error information
+ */
+ async MoveEntry(FileSystemMoveEntryRequest request)
+ returns(FileSystemMoveEntryResponse response);
+
+ /**
+ * Initiates an asynchronous request to rename a directory or file
+ *
+ * @returns error information
+ */
+ async RenameEntry(FileSystemRenameEntryRequest request)
+ returns(FileSystemMoveEntryResponse response);
+
+ child:
+ async PFileSystemWritableFileStream();
+
+ async CloseAll()
+ returns(nsresult rv);
+};
+
+} // namespace dom
+} // namespace mozilla
+
diff --git a/dom/fs/shared/PFileSystemWritableFileStream.ipdl b/dom/fs/shared/PFileSystemWritableFileStream.ipdl
new file mode 100644
index 0000000000..c71e4cbf43
--- /dev/null
+++ b/dom/fs/shared/PFileSystemWritableFileStream.ipdl
@@ -0,0 +1,23 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PFileSystemManager;
+
+using struct mozilla::void_t from "mozilla/ipc/IPCCore.h";
+
+namespace mozilla {
+namespace dom {
+
+async protocol PFileSystemWritableFileStream
+{
+ manager PFileSystemManager;
+
+ parent:
+ async Close() returns(void_t ok);
+
+ async __delete__();
+};
+
+} // namespace dom
+} // namespace mozilla
diff --git a/dom/fs/shared/TargetPtrHolder.h b/dom/fs/shared/TargetPtrHolder.h
new file mode 100644
index 0000000000..952fc075b9
--- /dev/null
+++ b/dom/fs/shared/TargetPtrHolder.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DOM_FS_SHARED_TARGETPTRHOLDER_H_
+#define DOM_FS_SHARED_TARGETPTRHOLDER_H_
+
+#include "mozilla/RefPtr.h"
+#include "nsCOMPtr.h"
+#include "nsThreadUtils.h"
+
+namespace mozilla::dom::fs {
+
+// TODO: Remove this ad hoc class when bug 1805830 is fixed.
+template <typename T>
+class TargetPtrHolder {
+ public:
+ MOZ_IMPLICIT TargetPtrHolder(T* aRawPtr)
+ : mTarget(GetCurrentSerialEventTarget()), mPtr(aRawPtr) {
+ MOZ_ASSERT(mPtr);
+ }
+
+ TargetPtrHolder(const TargetPtrHolder&) = default;
+
+ TargetPtrHolder& operator=(const TargetPtrHolder&) = default;
+
+ TargetPtrHolder(TargetPtrHolder&&) = default;
+
+ TargetPtrHolder& operator=(TargetPtrHolder&&) = default;
+
+ ~TargetPtrHolder() {
+ if (!mPtr) {
+ return;
+ }
+
+ NS_ProxyRelease("TargetPtrHolder::mPtr", mTarget, mPtr.forget());
+ }
+
+ T* get() const {
+ MOZ_ASSERT(mPtr);
+
+ return mPtr.get();
+ }
+
+ T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return get(); }
+
+ bool operator!() { return !mPtr.get(); }
+
+ private:
+ nsCOMPtr<nsISerialEventTarget> mTarget;
+ RefPtr<T> mPtr;
+};
+
+} // namespace mozilla::dom::fs
+
+#endif // DOM_FS_SHARED_TARGETPTRHOLDER_H_
diff --git a/dom/fs/shared/moz.build b/dom/fs/shared/moz.build
new file mode 100644
index 0000000000..1aaa2574ae
--- /dev/null
+++ b/dom/fs/shared/moz.build
@@ -0,0 +1,34 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+EXPORTS.mozilla.dom += [
+ "FileSystemHelpers.h",
+ "FileSystemLog.h",
+ "FileSystemTypes.h",
+]
+
+EXPORTS.mozilla.dom.fs += [
+ "IPCRejectReporter.h",
+ "ManagedMozPromiseRequestHolder.h",
+ "TargetPtrHolder.h",
+]
+
+UNIFIED_SOURCES += [
+ "FileSystemHelpers.cpp",
+ "FileSystemLog.cpp",
+ "IPCRejectReporter.cpp",
+]
+
+FINAL_LIBRARY = "xul"
+
+IPDL_SOURCES += [
+ "PFileSystemAccessHandle.ipdl",
+ "PFileSystemAccessHandleControl.ipdl",
+ "PFileSystemManager.ipdl",
+ "PFileSystemWritableFileStream.ipdl",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")