Backed out 8 changesets (bug 1873776) for causing vendor failures. CLOSED TREE
[gecko.git] / dom / fs / child / FileSystemRequestHandler.cpp
blob939bd41115ba7c7e348ed92755a2446569ba49ed
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "fs/FileSystemRequestHandler.h"
9 #include "FileSystemEntryMetadataArray.h"
10 #include "fs/FileSystemConstants.h"
11 #include "mozilla/ResultVariant.h"
12 #include "mozilla/StaticPrefs_dom.h"
13 #include "mozilla/dom/BlobImpl.h"
14 #include "mozilla/dom/File.h"
15 #include "mozilla/dom/FileSystemAccessHandleChild.h"
16 #include "mozilla/dom/FileSystemDirectoryHandle.h"
17 #include "mozilla/dom/FileSystemFileHandle.h"
18 #include "mozilla/dom/FileSystemHandle.h"
19 #include "mozilla/dom/FileSystemHelpers.h"
20 #include "mozilla/dom/FileSystemLog.h"
21 #include "mozilla/dom/FileSystemManager.h"
22 #include "mozilla/dom/FileSystemManagerChild.h"
23 #include "mozilla/dom/FileSystemSyncAccessHandle.h"
24 #include "mozilla/dom/FileSystemWritableFileStream.h"
25 #include "mozilla/dom/FileSystemWritableFileStreamChild.h"
26 #include "mozilla/dom/IPCBlobUtils.h"
27 #include "mozilla/dom/Promise.h"
28 #include "mozilla/dom/WorkerCommon.h"
29 #include "mozilla/dom/WorkerRef.h"
30 #include "mozilla/dom/fs/IPCRejectReporter.h"
31 #include "mozilla/dom/quota/QuotaCommon.h"
32 #include "mozilla/dom/quota/ResultExtensions.h"
33 #include "mozilla/ipc/RandomAccessStreamUtils.h"
35 namespace mozilla::dom::fs {
37 using mozilla::ipc::RejectCallback;
39 namespace {
41 void HandleFailedStatus(nsresult aError, const RefPtr<Promise>& aPromise) {
42 switch (aError) {
43 case NS_ERROR_FILE_ACCESS_DENIED:
44 aPromise->MaybeRejectWithNotAllowedError("Permission denied");
45 break;
46 case NS_ERROR_FILE_NOT_FOUND:
47 [[fallthrough]];
48 case NS_ERROR_DOM_NOT_FOUND_ERR:
49 aPromise->MaybeRejectWithNotFoundError("Entry not found");
50 break;
51 case NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR:
52 aPromise->MaybeRejectWithInvalidModificationError("Disallowed by system");
53 break;
54 case NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR:
55 aPromise->MaybeRejectWithNoModificationAllowedError(
56 "No modification allowed");
57 break;
58 case NS_ERROR_DOM_TYPE_MISMATCH_ERR:
59 aPromise->MaybeRejectWithTypeMismatchError("Wrong type");
60 break;
61 case NS_ERROR_DOM_INVALID_MODIFICATION_ERR:
62 aPromise->MaybeRejectWithInvalidModificationError("Invalid modification");
63 break;
64 default:
65 if (NS_FAILED(aError)) {
66 aPromise->MaybeRejectWithUnknownError("Unknown failure");
67 } else {
68 aPromise->MaybeResolveWithUndefined();
70 break;
74 bool MakeResolution(nsIGlobalObject* aGlobal,
75 FileSystemGetEntriesResponse&& aResponse,
76 const bool& /* aResult */,
77 RefPtr<FileSystemEntryMetadataArray>& aSink) {
78 // TODO: Add page size to FileSystemConstants, preallocate and handle overflow
79 const auto& listing = aResponse.get_FileSystemDirectoryListing();
81 for (const auto& it : listing.files()) {
82 aSink->AppendElement(it);
85 for (const auto& it : listing.directories()) {
86 aSink->AppendElement(it);
89 return true;
92 RefPtr<FileSystemDirectoryHandle> MakeResolution(
93 nsIGlobalObject* aGlobal, FileSystemGetHandleResponse&& aResponse,
94 const RefPtr<FileSystemDirectoryHandle>& /* aResult */,
95 RefPtr<FileSystemManager>& aManager) {
96 RefPtr<FileSystemDirectoryHandle> result = new FileSystemDirectoryHandle(
97 aGlobal, aManager,
98 FileSystemEntryMetadata(aResponse.get_EntryId(), kRootName,
99 /* directory */ true));
100 return result;
103 RefPtr<FileSystemDirectoryHandle> MakeResolution(
104 nsIGlobalObject* aGlobal, FileSystemGetHandleResponse&& aResponse,
105 const RefPtr<FileSystemDirectoryHandle>& /* aResult */, const Name& aName,
106 RefPtr<FileSystemManager>& aManager) {
107 RefPtr<FileSystemDirectoryHandle> result = new FileSystemDirectoryHandle(
108 aGlobal, aManager,
109 FileSystemEntryMetadata(aResponse.get_EntryId(), aName,
110 /* directory */ true));
112 return result;
115 RefPtr<FileSystemFileHandle> MakeResolution(
116 nsIGlobalObject* aGlobal, FileSystemGetHandleResponse&& aResponse,
117 const RefPtr<FileSystemFileHandle>& /* aResult */, const Name& aName,
118 RefPtr<FileSystemManager>& aManager) {
119 RefPtr<FileSystemFileHandle> result = new FileSystemFileHandle(
120 aGlobal, aManager,
121 FileSystemEntryMetadata(aResponse.get_EntryId(), aName,
122 /* directory */ false));
123 return result;
126 RefPtr<FileSystemSyncAccessHandle> MakeResolution(
127 nsIGlobalObject* aGlobal, FileSystemGetAccessHandleResponse&& aResponse,
128 const RefPtr<FileSystemSyncAccessHandle>& /* aReturns */,
129 const FileSystemEntryMetadata& aMetadata,
130 RefPtr<FileSystemManager>& aManager) {
131 auto& properties = aResponse.get_FileSystemAccessHandleProperties();
133 QM_TRY_UNWRAP(
134 RefPtr<FileSystemSyncAccessHandle> result,
135 FileSystemSyncAccessHandle::Create(
136 aGlobal, aManager, std::move(properties.streamParams()),
137 std::move(properties.accessHandleChildEndpoint()),
138 std::move(properties.accessHandleControlChildEndpoint()), aMetadata),
139 nullptr);
141 return result;
144 RefPtr<FileSystemWritableFileStream> MakeResolution(
145 nsIGlobalObject* aGlobal,
146 FileSystemGetWritableFileStreamResponse&& aResponse,
147 const RefPtr<FileSystemWritableFileStream>& /* aReturns */,
148 const FileSystemEntryMetadata& aMetadata,
149 RefPtr<FileSystemManager>& aManager) {
150 auto& properties = aResponse.get_FileSystemWritableFileStreamProperties();
152 auto* const actor = static_cast<FileSystemWritableFileStreamChild*>(
153 properties.writableFileStream().AsChild().get());
155 QM_TRY_UNWRAP(RefPtr<FileSystemWritableFileStream> result,
156 FileSystemWritableFileStream::Create(
157 aGlobal, aManager, std::move(properties.streamParams()),
158 actor, aMetadata),
159 nullptr);
161 return result;
164 RefPtr<File> MakeResolution(nsIGlobalObject* aGlobal,
165 FileSystemGetFileResponse&& aResponse,
166 const RefPtr<File>& /* aResult */,
167 const Name& aName,
168 RefPtr<FileSystemManager>& aManager) {
169 auto& fileProperties = aResponse.get_FileSystemFileProperties();
171 RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(fileProperties.file());
172 MOZ_ASSERT(blobImpl);
173 RefPtr<File> result = File::Create(aGlobal, blobImpl);
174 return result;
177 template <class TResponse, class... Args>
178 void ResolveCallback(
179 TResponse&& aResponse,
180 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
181 Args&&... args) {
182 MOZ_ASSERT(aPromise);
183 QM_TRY(OkIf(Promise::PromiseState::Pending == aPromise->State()), QM_VOID);
185 if (TResponse::Tnsresult == aResponse.type()) {
186 HandleFailedStatus(aResponse.get_nsresult(), aPromise);
187 return;
190 auto resolution = MakeResolution(aPromise->GetParentObject(),
191 std::forward<TResponse>(aResponse),
192 std::forward<Args>(args)...);
193 if (!resolution) {
194 aPromise->MaybeRejectWithUnknownError("Could not complete request");
195 return;
198 aPromise->MaybeResolve(resolution);
201 template <>
202 void ResolveCallback(
203 FileSystemRemoveEntryResponse&& aResponse,
204 RefPtr<Promise> aPromise) { // NOLINT(performance-unnecessary-value-param)
205 MOZ_ASSERT(aPromise);
206 QM_TRY(OkIf(Promise::PromiseState::Pending == aPromise->State()), QM_VOID);
208 if (FileSystemRemoveEntryResponse::Tvoid_t == aResponse.type()) {
209 aPromise->MaybeResolveWithUndefined();
210 return;
213 MOZ_ASSERT(FileSystemRemoveEntryResponse::Tnsresult == aResponse.type());
214 HandleFailedStatus(aResponse.get_nsresult(), aPromise);
217 template <>
218 void ResolveCallback(
219 FileSystemMoveEntryResponse&& aResponse,
220 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
221 FileSystemEntryMetadata* const& aEntry, const Name& aName) {
222 MOZ_ASSERT(aPromise);
223 QM_TRY(OkIf(Promise::PromiseState::Pending == aPromise->State()), QM_VOID);
225 if (FileSystemMoveEntryResponse::TEntryId == aResponse.type()) {
226 if (aEntry) {
227 aEntry->entryId() = std::move(aResponse.get_EntryId());
228 aEntry->entryName() = aName;
231 aPromise->MaybeResolveWithUndefined();
232 return;
234 MOZ_ASSERT(FileSystemMoveEntryResponse::Tnsresult == aResponse.type());
235 const auto& status = aResponse.get_nsresult();
236 MOZ_ASSERT(NS_FAILED(status));
237 HandleFailedStatus(status, aPromise);
240 template <>
241 void ResolveCallback(FileSystemResolveResponse&& aResponse,
242 // NOLINTNEXTLINE(performance-unnecessary-value-param)
243 RefPtr<Promise> aPromise) {
244 MOZ_ASSERT(aPromise);
245 QM_TRY(OkIf(Promise::PromiseState::Pending == aPromise->State()), QM_VOID);
247 if (FileSystemResolveResponse::Tnsresult == aResponse.type()) {
248 HandleFailedStatus(aResponse.get_nsresult(), aPromise);
249 return;
252 auto& maybePath = aResponse.get_MaybeFileSystemPath();
253 if (maybePath.isSome()) {
254 aPromise->MaybeResolve(maybePath.value().path());
255 return;
258 // Spec says if there is no parent/child relationship, return null
259 aPromise->MaybeResolve(JS::NullHandleValue);
262 template <class TResponse, class TReturns, class... Args,
263 std::enable_if_t<std::is_same<TReturns, void>::value, bool> = true>
264 mozilla::ipc::ResolveCallback<TResponse> SelectResolveCallback(
265 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
266 Args&&... args) {
267 using TOverload = void (*)(TResponse&&, RefPtr<Promise>, Args...);
268 return static_cast<std::function<void(TResponse&&)>>(
269 // NOLINTNEXTLINE(modernize-avoid-bind)
270 std::bind(static_cast<TOverload>(ResolveCallback), std::placeholders::_1,
271 aPromise, std::forward<Args>(args)...));
274 template <class TResponse, class TReturns, class... Args,
275 std::enable_if_t<!std::is_same<TReturns, void>::value, bool> = true>
276 mozilla::ipc::ResolveCallback<TResponse> SelectResolveCallback(
277 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
278 Args&&... args) {
279 using TOverload =
280 void (*)(TResponse&&, RefPtr<Promise>, const TReturns&, Args...);
281 return static_cast<std::function<void(TResponse&&)>>(
282 // NOLINTNEXTLINE(modernize-avoid-bind)
283 std::bind(static_cast<TOverload>(ResolveCallback), std::placeholders::_1,
284 aPromise, TReturns(), std::forward<Args>(args)...));
287 void RejectCallback(
288 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
289 mozilla::ipc::ResponseRejectReason aReason) {
290 IPCRejectReporter(aReason);
291 QM_TRY(OkIf(Promise::PromiseState::Pending == aPromise->State()), QM_VOID);
292 aPromise->MaybeRejectWithUndefined();
295 mozilla::ipc::RejectCallback GetRejectCallback(
296 RefPtr<Promise> aPromise) { // NOLINT(performance-unnecessary-value-param)
297 return static_cast<mozilla::ipc::RejectCallback>(
298 // NOLINTNEXTLINE(modernize-avoid-bind)
299 std::bind(RejectCallback, aPromise, std::placeholders::_1));
302 struct BeginRequestFailureCallback {
303 explicit BeginRequestFailureCallback(RefPtr<Promise> aPromise)
304 : mPromise(std::move(aPromise)) {}
306 void operator()(nsresult aRv) const {
307 if (aRv == NS_ERROR_DOM_SECURITY_ERR) {
308 mPromise->MaybeRejectWithSecurityError(
309 "Security error when calling GetDirectory");
310 return;
312 mPromise->MaybeRejectWithUnknownError("Could not create actor");
315 RefPtr<Promise> mPromise;
318 } // namespace
320 void FileSystemRequestHandler::GetRootHandle(
321 RefPtr<FileSystemManager>
322 aManager, // NOLINT(performance-unnecessary-value-param)
323 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
324 ErrorResult& aError) {
325 MOZ_ASSERT(aManager);
326 MOZ_ASSERT(aPromise);
327 LOG(("GetRootHandle"));
329 if (aManager->IsShutdown()) {
330 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
331 return;
334 aManager->BeginRequest(
335 [onResolve = SelectResolveCallback<FileSystemGetHandleResponse,
336 RefPtr<FileSystemDirectoryHandle>>(
337 aPromise, aManager),
338 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
339 actor->SendGetRootHandle(std::move(onResolve), std::move(onReject));
341 BeginRequestFailureCallback(aPromise));
344 void FileSystemRequestHandler::GetDirectoryHandle(
345 RefPtr<FileSystemManager>& aManager,
346 const FileSystemChildMetadata& aDirectory, bool aCreate,
347 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
348 ErrorResult& aError) {
349 MOZ_ASSERT(aManager);
350 MOZ_ASSERT(!aDirectory.parentId().IsEmpty());
351 MOZ_ASSERT(aPromise);
352 LOG(("GetDirectoryHandle"));
354 if (aManager->IsShutdown()) {
355 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
356 return;
359 if (!IsValidName(aDirectory.childName())) {
360 aPromise->MaybeRejectWithTypeError("Invalid directory name");
361 return;
364 aManager->BeginRequest(
365 [request = FileSystemGetHandleRequest(aDirectory, aCreate),
366 onResolve = SelectResolveCallback<FileSystemGetHandleResponse,
367 RefPtr<FileSystemDirectoryHandle>>(
368 aPromise, aDirectory.childName(), aManager),
369 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
370 actor->SendGetDirectoryHandle(request, std::move(onResolve),
371 std::move(onReject));
373 BeginRequestFailureCallback(aPromise));
376 void FileSystemRequestHandler::GetFileHandle(
377 RefPtr<FileSystemManager>& aManager, const FileSystemChildMetadata& aFile,
378 bool aCreate,
379 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
380 ErrorResult& aError) {
381 MOZ_ASSERT(aManager);
382 MOZ_ASSERT(!aFile.parentId().IsEmpty());
383 MOZ_ASSERT(aPromise);
384 LOG(("GetFileHandle"));
386 if (aManager->IsShutdown()) {
387 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
388 return;
391 if (!IsValidName(aFile.childName())) {
392 aPromise->MaybeRejectWithTypeError("Invalid filename");
393 return;
396 aManager->BeginRequest(
397 [request = FileSystemGetHandleRequest(aFile, aCreate),
398 onResolve = SelectResolveCallback<FileSystemGetHandleResponse,
399 RefPtr<FileSystemFileHandle>>(
400 aPromise, aFile.childName(), aManager),
401 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
402 actor->SendGetFileHandle(request, std::move(onResolve),
403 std::move(onReject));
405 BeginRequestFailureCallback(aPromise));
408 void FileSystemRequestHandler::GetAccessHandle(
409 RefPtr<FileSystemManager>& aManager, const FileSystemEntryMetadata& aFile,
410 const RefPtr<Promise>& aPromise, ErrorResult& aError) {
411 MOZ_ASSERT(aManager);
412 MOZ_ASSERT(aPromise);
413 LOG(("GetAccessHandle %s", NS_ConvertUTF16toUTF8(aFile.entryName()).get()));
415 if (aManager->IsShutdown()) {
416 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
417 return;
420 aManager->BeginRequest(
421 [request = FileSystemGetAccessHandleRequest(aFile.entryId()),
422 onResolve = SelectResolveCallback<FileSystemGetAccessHandleResponse,
423 RefPtr<FileSystemSyncAccessHandle>>(
424 aPromise, aFile, aManager),
425 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
426 actor->SendGetAccessHandle(request, std::move(onResolve),
427 std::move(onReject));
429 BeginRequestFailureCallback(aPromise));
432 void FileSystemRequestHandler::GetWritable(RefPtr<FileSystemManager>& aManager,
433 const FileSystemEntryMetadata& aFile,
434 bool aKeepData,
435 const RefPtr<Promise>& aPromise,
436 ErrorResult& aError) {
437 MOZ_ASSERT(aManager);
438 MOZ_ASSERT(aPromise);
439 LOG(("GetWritable %s keep %d", NS_ConvertUTF16toUTF8(aFile.entryName()).get(),
440 aKeepData));
442 // XXX This should be removed once bug 1798513 is fixed.
443 if (!StaticPrefs::dom_fs_writable_file_stream_enabled()) {
444 aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
445 return;
448 if (aManager->IsShutdown()) {
449 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
450 return;
453 aManager->BeginRequest(
454 [request = FileSystemGetWritableRequest(aFile.entryId(), aKeepData),
455 onResolve =
456 SelectResolveCallback<FileSystemGetWritableFileStreamResponse,
457 RefPtr<FileSystemWritableFileStream>>(
458 aPromise, aFile, aManager),
459 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
460 actor->SendGetWritable(request, std::move(onResolve),
461 std::move(onReject));
463 [promise = aPromise](const auto&) {
464 promise->MaybeRejectWithUnknownError("Could not create actor");
468 void FileSystemRequestHandler::GetFile(
469 RefPtr<FileSystemManager>& aManager, const FileSystemEntryMetadata& aFile,
470 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
471 ErrorResult& aError) {
472 MOZ_ASSERT(aManager);
473 MOZ_ASSERT(!aFile.entryId().IsEmpty());
474 MOZ_ASSERT(aPromise);
475 LOG(("GetFile %s", NS_ConvertUTF16toUTF8(aFile.entryName()).get()));
477 if (aManager->IsShutdown()) {
478 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
479 return;
482 aManager->BeginRequest(
483 [request = FileSystemGetFileRequest(aFile.entryId()),
484 onResolve =
485 SelectResolveCallback<FileSystemGetFileResponse, RefPtr<File>>(
486 aPromise, aFile.entryName(), aManager),
487 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
488 actor->SendGetFile(request, std::move(onResolve), std::move(onReject));
490 BeginRequestFailureCallback(aPromise));
493 void FileSystemRequestHandler::GetEntries(
494 RefPtr<FileSystemManager>& aManager, const EntryId& aDirectory,
495 PageNumber aPage,
496 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
497 RefPtr<FileSystemEntryMetadataArray>& aSink, ErrorResult& aError) {
498 MOZ_ASSERT(aManager);
499 MOZ_ASSERT(!aDirectory.IsEmpty());
500 MOZ_ASSERT(aPromise);
501 LOG(("GetEntries, page %u", aPage));
503 if (aManager->IsShutdown()) {
504 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
505 return;
508 aManager->BeginRequest(
509 [request = FileSystemGetEntriesRequest(aDirectory, aPage),
510 onResolve = SelectResolveCallback<FileSystemGetEntriesResponse, bool>(
511 aPromise, aSink),
512 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
513 actor->SendGetEntries(request, std::move(onResolve),
514 std::move(onReject));
516 BeginRequestFailureCallback(aPromise));
519 void FileSystemRequestHandler::RemoveEntry(
520 RefPtr<FileSystemManager>& aManager, const FileSystemChildMetadata& aEntry,
521 bool aRecursive,
522 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
523 ErrorResult& aError) {
524 MOZ_ASSERT(aManager);
525 MOZ_ASSERT(!aEntry.parentId().IsEmpty());
526 MOZ_ASSERT(aPromise);
527 LOG(("RemoveEntry"));
529 if (aManager->IsShutdown()) {
530 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
531 return;
534 if (!IsValidName(aEntry.childName())) {
535 aPromise->MaybeRejectWithTypeError("Invalid name");
536 return;
539 aManager->BeginRequest(
540 [request = FileSystemRemoveEntryRequest(aEntry, aRecursive),
541 onResolve =
542 SelectResolveCallback<FileSystemRemoveEntryResponse, void>(aPromise),
543 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
544 actor->SendRemoveEntry(request, std::move(onResolve),
545 std::move(onReject));
547 BeginRequestFailureCallback(aPromise));
550 void FileSystemRequestHandler::MoveEntry(
551 RefPtr<FileSystemManager>& aManager, FileSystemHandle* aHandle,
552 FileSystemEntryMetadata* const aEntry,
553 const FileSystemChildMetadata& aNewEntry,
554 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
555 ErrorResult& aError) {
556 MOZ_ASSERT(aEntry);
557 MOZ_ASSERT(!aEntry->entryId().IsEmpty());
558 MOZ_ASSERT(aPromise);
559 LOG(("MoveEntry"));
561 if (aManager->IsShutdown()) {
562 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
563 return;
566 // reject invalid names: empty, path separators, current & parent directories
567 if (!IsValidName(aNewEntry.childName())) {
568 aPromise->MaybeRejectWithTypeError("Invalid name");
569 return;
572 aManager->BeginRequest(
573 [request = FileSystemMoveEntryRequest(*aEntry, aNewEntry),
574 onResolve = SelectResolveCallback<FileSystemMoveEntryResponse, void>(
575 aPromise, aEntry, aNewEntry.childName()),
576 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
577 actor->SendMoveEntry(request, std::move(onResolve),
578 std::move(onReject));
580 BeginRequestFailureCallback(aPromise));
583 void FileSystemRequestHandler::RenameEntry(
584 RefPtr<FileSystemManager>& aManager, FileSystemHandle* aHandle,
585 FileSystemEntryMetadata* const aEntry, const Name& aName,
586 RefPtr<Promise> aPromise, // NOLINT(performance-unnecessary-value-param)
587 ErrorResult& aError) {
588 MOZ_ASSERT(aEntry);
589 MOZ_ASSERT(!aEntry->entryId().IsEmpty());
590 MOZ_ASSERT(aPromise);
591 LOG(("RenameEntry"));
593 if (aManager->IsShutdown()) {
594 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
595 return;
598 // reject invalid names: empty, path separators, current & parent directories
599 if (!IsValidName(aName)) {
600 aPromise->MaybeRejectWithTypeError("Invalid name");
601 return;
604 aManager->BeginRequest(
605 [request = FileSystemRenameEntryRequest(*aEntry, aName),
606 onResolve = SelectResolveCallback<FileSystemMoveEntryResponse, void>(
607 aPromise, aEntry, aName),
608 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
609 actor->SendRenameEntry(request, std::move(onResolve),
610 std::move(onReject));
612 BeginRequestFailureCallback(aPromise));
615 void FileSystemRequestHandler::Resolve(
616 RefPtr<FileSystemManager>& aManager,
617 // NOLINTNEXTLINE(performance-unnecessary-value-param)
618 const FileSystemEntryPair& aEndpoints, RefPtr<Promise> aPromise,
619 ErrorResult& aError) {
620 MOZ_ASSERT(aManager);
621 MOZ_ASSERT(!aEndpoints.parentId().IsEmpty());
622 MOZ_ASSERT(!aEndpoints.childId().IsEmpty());
623 MOZ_ASSERT(aPromise);
624 LOG(("Resolve"));
626 if (aManager->IsShutdown()) {
627 aError.Throw(NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
628 return;
631 aManager->BeginRequest(
632 [request = FileSystemResolveRequest(aEndpoints),
633 onResolve =
634 SelectResolveCallback<FileSystemResolveResponse, void>(aPromise),
635 onReject = GetRejectCallback(aPromise)](const auto& actor) mutable {
636 actor->SendResolve(request, std::move(onResolve), std::move(onReject));
638 BeginRequestFailureCallback(aPromise));
641 } // namespace mozilla::dom::fs