Bug 1761089: Add support for getFile() to FileSystemHandles in OPFS r=dom-storage-reviewers,jari,janv

Depends on D154482

Differential Revision: https://phabricator.services.mozilla.com/D146986
This commit is contained in:
Randell Jesup 2022-09-13 17:43:44 +00:00
Родитель a32dfd5297
Коммит bafc711011
6 изменённых файлов: 67 добавлений и 23 удалений

Просмотреть файл

@ -53,7 +53,7 @@ already_AddRefed<Promise> FileSystemFileHandle::GetFile(ErrorResult& aError) {
return nullptr; return nullptr;
} }
promise->MaybeReject(NS_ERROR_NOT_IMPLEMENTED); mRequestHandler->GetFile(mManager, mMetadata, promise);
return promise.forget(); return promise.forget();
} }

Просмотреть файл

@ -18,6 +18,9 @@ FileSystemManagerChild::AllocPFileSystemAccessHandleChild(
::mozilla::ipc::IPCResult FileSystemManagerChild::RecvCloseAll( ::mozilla::ipc::IPCResult FileSystemManagerChild::RecvCloseAll(
CloseAllResolver&& aResolver) { CloseAllResolver&& aResolver) {
// NOTE: getFile() creates blobs that read the data from the child;
// we'll need to abort any reads and resolve this call only when all
// blobs are closed.
for (const auto& item : ManagedPFileSystemAccessHandleChild()) { for (const auto& item : ManagedPFileSystemAccessHandleChild()) {
auto* child = static_cast<FileSystemAccessHandleChild*>(item); auto* child = static_cast<FileSystemAccessHandleChild*>(item);
child->Close(); child->Close();

Просмотреть файл

@ -8,6 +8,7 @@
#include "FileSystemEntryMetadataArray.h" #include "FileSystemEntryMetadataArray.h"
#include "fs/FileSystemConstants.h" #include "fs/FileSystemConstants.h"
#include "mozilla/dom/BlobImpl.h"
#include "mozilla/dom/File.h" #include "mozilla/dom/File.h"
#include "mozilla/dom/FileSystemAccessHandleChild.h" #include "mozilla/dom/FileSystemAccessHandleChild.h"
#include "mozilla/dom/FileSystemDirectoryHandle.h" #include "mozilla/dom/FileSystemDirectoryHandle.h"
@ -17,6 +18,7 @@
#include "mozilla/dom/FileSystemManager.h" #include "mozilla/dom/FileSystemManager.h"
#include "mozilla/dom/FileSystemManagerChild.h" #include "mozilla/dom/FileSystemManagerChild.h"
#include "mozilla/dom/FileSystemSyncAccessHandle.h" #include "mozilla/dom/FileSystemSyncAccessHandle.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/Promise.h" #include "mozilla/dom/Promise.h"
#include "mozilla/dom/quota/QuotaCommon.h" #include "mozilla/dom/quota/QuotaCommon.h"
@ -35,20 +37,6 @@ using mozilla::ipc::RejectCallback;
namespace { namespace {
// TODO: This is just a dummy implementation
RefPtr<File> MakeGetFileResult(nsIGlobalObject* aGlobal, const nsString& aName,
const nsString& aType,
int64_t aLastModifiedMilliSeconds,
nsTArray<Name>&& aPath, IPCBlob&& /* aFile */,
RefPtr<FileSystemManager>& aManager) {
// TODO: Replace with a real implementation
RefPtr<File> result = File::CreateMemoryFileWithCustomLastModified(
aGlobal, static_cast<void*>(new uint8_t[1]), sizeof(uint8_t), aName,
aType, aLastModifiedMilliSeconds);
return result;
}
bool MakeResolution(nsIGlobalObject* aGlobal, bool MakeResolution(nsIGlobalObject* aGlobal,
FileSystemGetEntriesResponse&& aResponse, FileSystemGetEntriesResponse&& aResponse,
const bool& /* aResult */, const bool& /* aResult */,
@ -123,10 +111,11 @@ RefPtr<File> MakeResolution(nsIGlobalObject* aGlobal,
const Name& aName, const Name& aName,
RefPtr<FileSystemManager>& aManager) { RefPtr<FileSystemManager>& aManager) {
auto& fileProperties = aResponse.get_FileSystemFileProperties(); auto& fileProperties = aResponse.get_FileSystemFileProperties();
return MakeGetFileResult(aGlobal, aName, fileProperties.type(),
fileProperties.last_modified_ms(), RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(fileProperties.file());
std::move(fileProperties.path()), MOZ_ASSERT(blobImpl);
std::move(fileProperties.file()), aManager); RefPtr<File> result = File::Create(aGlobal, blobImpl);
return result;
} }
template <class TResponse, class... Args> template <class TResponse, class... Args>

Просмотреть файл

@ -8,9 +8,11 @@
#include "FileSystemDatabaseManager.h" #include "FileSystemDatabaseManager.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/dom/FileBlobImpl.h"
#include "mozilla/dom/FileSystemAccessHandleParent.h" #include "mozilla/dom/FileSystemAccessHandleParent.h"
#include "mozilla/dom/FileSystemDataManager.h" #include "mozilla/dom/FileSystemDataManager.h"
#include "mozilla/dom/FileSystemTypes.h" #include "mozilla/dom/FileSystemTypes.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/QMResult.h" #include "mozilla/dom/QMResult.h"
#include "mozilla/dom/quota/ForwardDecls.h" #include "mozilla/dom/quota/ForwardDecls.h"
#include "mozilla/dom/quota/QuotaCommon.h" #include "mozilla/dom/quota/QuotaCommon.h"
@ -173,9 +175,40 @@ IPCResult FileSystemManagerParent::RecvGetFile(
FileSystemGetFileRequest&& aRequest, GetFileResolver&& aResolver) { FileSystemGetFileRequest&& aRequest, GetFileResolver&& aResolver) {
AssertIsOnIOTarget(); AssertIsOnIOTarget();
FileSystemGetFileResponse response(NS_ERROR_NOT_IMPLEMENTED); // XXX Spec https://www.w3.org/TR/FileAPI/#dfn-file wants us to snapshot the
aResolver(response); // state of the file at getFile() time
// You can create a File with getFile() even if the file is locked
// XXX factor out this part of the code for accesshandle/ and getfile
auto reportError = [aResolver](nsresult rv) {
LOG(("getFile() Failed!"));
aResolver(rv);
};
nsString type;
fs::TimeStamp lastModifiedMilliSeconds;
fs::Path path;
nsCOMPtr<nsIFile> fileObject;
QM_TRY(MOZ_TO_RESULT(mDataManager->MutableDatabaseManagerPtr()->GetFile(
{aRequest.entryId(), aRequest.entryId()}, type,
lastModifiedMilliSeconds, path, fileObject)),
IPC_OK(), reportError);
if (MOZ_LOG_TEST(gOPFSLog, mozilla::LogLevel::Debug)) {
nsAutoString path;
if (NS_SUCCEEDED(fileObject->GetPath(path))) {
LOG(("Opening %s", NS_ConvertUTF16toUTF8(path).get()));
}
}
RefPtr<BlobImpl> blob = MakeRefPtr<FileBlobImpl>(fileObject);
IPCBlob ipcBlob;
QM_TRY(MOZ_TO_RESULT(IPCBlobUtils::Serialize(blob, ipcBlob)), IPC_OK(),
reportError);
aResolver(
FileSystemFileProperties(lastModifiedMilliSeconds, ipcBlob, type, path));
return IPC_OK(); return IPC_OK();
} }

Просмотреть файл

@ -160,7 +160,7 @@ nsresult GetFileAttributes(const FileSystemConnection& aConnection,
const nsLiteralCString getFileLocation = const nsLiteralCString getFileLocation =
"SELECT type FROM Files INNER JOIN Entries USING(handle) WHERE handle = :entryId;"_ns; "SELECT type FROM Files INNER JOIN Entries USING(handle) WHERE handle = :entryId;"_ns;
// TODO: Request this from filemanager who makes the system call // TODO: bug 1790391: Request this from filemanager who makes the system call
aLastModifiedMilliSeconds = 0; aLastModifiedMilliSeconds = 0;
QM_TRY_UNWRAP(ResultStatement stmt, QM_TRY_UNWRAP(ResultStatement stmt,

Просмотреть файл

@ -11,13 +11,17 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/dom/FileBlobImpl.h"
#include "mozilla/dom/FileSystemManager.h" #include "mozilla/dom/FileSystemManager.h"
#include "mozilla/dom/FileSystemManagerChild.h" #include "mozilla/dom/FileSystemManagerChild.h"
#include "mozilla/dom/IPCBlob.h" #include "mozilla/dom/IPCBlob.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/PFileSystemManager.h" #include "mozilla/dom/PFileSystemManager.h"
#include "mozilla/dom/StorageManager.h" #include "mozilla/dom/StorageManager.h"
#include "mozilla/ipc/FileDescriptorUtils.h" #include "mozilla/ipc/FileDescriptorUtils.h"
#include "mozilla/ipc/IPCCore.h" #include "mozilla/ipc/IPCCore.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
using ::testing::_; using ::testing::_;
using ::testing::ByRef; using ::testing::ByRef;
@ -143,9 +147,24 @@ TEST_F(TestFileSystemRequestHandler, isGetFileHandleSuccessful) {
TEST_F(TestFileSystemRequestHandler, isGetFileSuccessful) { TEST_F(TestFileSystemRequestHandler, isGetFileSuccessful) {
auto fakeResponse = [](const auto& /* aRequest */, auto&& aResolve, auto fakeResponse = [](const auto& /* aRequest */, auto&& aResolve,
auto&& /* aReject */) { auto&& /* aReject */) {
// We have to create a temporary file
nsCOMPtr<nsIFile> tmpfile;
nsresult rv =
NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpfile));
ASSERT_EQ(NS_SUCCEEDED(rv), true);
rv = tmpfile->AppendNative("GetFileTestBlob"_ns);
ASSERT_EQ(NS_SUCCEEDED(rv), true);
rv = tmpfile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0666);
ASSERT_EQ(NS_SUCCEEDED(rv), true);
auto blob = MakeRefPtr<FileBlobImpl>(tmpfile);
TimeStamp last_modified_ms = 0; TimeStamp last_modified_ms = 0;
mozilla::dom::IPCBlob file;
ContentType type = u"txt"_ns; ContentType type = u"txt"_ns;
IPCBlob file;
IPCBlobUtils::Serialize(blob, file);
nsTArray<Name> path; nsTArray<Name> path;
path.AppendElement(u"root"_ns); path.AppendElement(u"root"_ns);