Bug 1824753 [wpt PR 39216] - [FLEDGE] Add WPT test that FLEDGE is not allowed in...
[gecko.git] / dom / filesystem / GetFileOrDirectoryTask.cpp
blob7f7d1c2816b77f2b4bff4c9e133224c29e274793
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "GetFileOrDirectoryTask.h"
9 #include "js/Value.h"
10 #include "mozilla/dom/FileBlobImpl.h"
11 #include "mozilla/dom/FileSystemBase.h"
12 #include "mozilla/dom/FileSystemUtils.h"
13 #include "mozilla/dom/PFileSystemParams.h"
14 #include "mozilla/dom/Promise.h"
15 #include "mozilla/dom/IPCBlobUtils.h"
16 #include "mozilla/ipc/BackgroundParent.h"
17 #include "nsIFile.h"
18 #include "nsString.h"
20 namespace mozilla::dom {
22 /**
23 * GetFileOrDirectoryTaskChild
26 /* static */
27 already_AddRefed<GetFileOrDirectoryTaskChild>
28 GetFileOrDirectoryTaskChild::Create(FileSystemBase* aFileSystem,
29 nsIFile* aTargetPath, ErrorResult& aRv) {
30 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
31 MOZ_ASSERT(aFileSystem);
33 nsCOMPtr<nsIGlobalObject> globalObject = aFileSystem->GetParentObject();
34 if (NS_WARN_IF(!globalObject)) {
35 aRv.Throw(NS_ERROR_FAILURE);
36 return nullptr;
39 RefPtr<GetFileOrDirectoryTaskChild> task =
40 new GetFileOrDirectoryTaskChild(globalObject, aFileSystem, aTargetPath);
42 // aTargetPath can be null. In this case SetError will be called.
44 task->mPromise = Promise::Create(globalObject, aRv);
45 if (NS_WARN_IF(aRv.Failed())) {
46 return nullptr;
49 return task.forget();
52 GetFileOrDirectoryTaskChild::GetFileOrDirectoryTaskChild(
53 nsIGlobalObject* aGlobalObject, FileSystemBase* aFileSystem,
54 nsIFile* aTargetPath)
55 : FileSystemTaskChildBase(aGlobalObject, aFileSystem),
56 mTargetPath(aTargetPath) {
57 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
58 MOZ_ASSERT(aFileSystem);
61 GetFileOrDirectoryTaskChild::~GetFileOrDirectoryTaskChild() {
62 MOZ_ASSERT(NS_IsMainThread());
65 already_AddRefed<Promise> GetFileOrDirectoryTaskChild::GetPromise() {
66 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
67 return RefPtr<Promise>(mPromise).forget();
70 FileSystemParams GetFileOrDirectoryTaskChild::GetRequestParams(
71 const nsString& aSerializedDOMPath, ErrorResult& aRv) const {
72 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
74 nsAutoString path;
75 aRv = mTargetPath->GetPath(path);
76 if (NS_WARN_IF(aRv.Failed())) {
77 return FileSystemGetFileOrDirectoryParams();
80 return FileSystemGetFileOrDirectoryParams(aSerializedDOMPath, path);
83 void GetFileOrDirectoryTaskChild::SetSuccessRequestResult(
84 const FileSystemResponseValue& aValue, ErrorResult& aRv) {
85 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
86 switch (aValue.type()) {
87 case FileSystemResponseValue::TFileSystemFileResponse: {
88 FileSystemFileResponse r = aValue;
90 RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(r.blob());
91 MOZ_ASSERT(blobImpl);
93 nsCOMPtr<nsIGlobalObject> globalObject = mFileSystem->GetParentObject();
94 MOZ_ASSERT(globalObject);
96 mResultFile = File::Create(globalObject, blobImpl);
97 if (NS_WARN_IF(!mResultFile)) {
98 aRv.Throw(NS_ERROR_FAILURE);
100 break;
102 case FileSystemResponseValue::TFileSystemDirectoryResponse: {
103 FileSystemDirectoryResponse r = aValue;
105 nsCOMPtr<nsIFile> file;
106 aRv = NS_NewLocalFile(r.realPath(), true, getter_AddRefs(file));
107 if (NS_WARN_IF(aRv.Failed())) {
108 return;
111 mResultDirectory =
112 Directory::Create(mFileSystem->GetParentObject(), file, mFileSystem);
113 MOZ_ASSERT(mResultDirectory);
114 break;
116 default: {
117 MOZ_CRASH("not reached");
118 break;
123 void GetFileOrDirectoryTaskChild::HandlerCallback() {
124 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
125 if (mFileSystem->IsShutdown()) {
126 mPromise = nullptr;
127 return;
130 if (HasError()) {
131 mPromise->MaybeReject(mErrorValue);
132 mPromise = nullptr;
133 return;
136 if (mResultDirectory) {
137 mPromise->MaybeResolve(mResultDirectory);
138 mResultDirectory = nullptr;
139 mPromise = nullptr;
140 return;
143 MOZ_ASSERT(mResultFile);
144 mPromise->MaybeResolve(mResultFile);
145 mResultFile = nullptr;
146 mPromise = nullptr;
150 * GetFileOrDirectoryTaskParent
153 /* static */
154 already_AddRefed<GetFileOrDirectoryTaskParent>
155 GetFileOrDirectoryTaskParent::Create(
156 FileSystemBase* aFileSystem,
157 const FileSystemGetFileOrDirectoryParams& aParam,
158 FileSystemRequestParent* aParent, ErrorResult& aRv) {
159 MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
160 mozilla::ipc::AssertIsOnBackgroundThread();
161 MOZ_ASSERT(aFileSystem);
163 RefPtr<GetFileOrDirectoryTaskParent> task =
164 new GetFileOrDirectoryTaskParent(aFileSystem, aParam, aParent);
166 aRv = NS_NewLocalFile(aParam.realPath(), true,
167 getter_AddRefs(task->mTargetPath));
168 if (NS_WARN_IF(aRv.Failed())) {
169 return nullptr;
172 return task.forget();
175 GetFileOrDirectoryTaskParent::GetFileOrDirectoryTaskParent(
176 FileSystemBase* aFileSystem,
177 const FileSystemGetFileOrDirectoryParams& aParam,
178 FileSystemRequestParent* aParent)
179 : FileSystemTaskParentBase(aFileSystem, aParam, aParent),
180 mIsDirectory(false) {
181 MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
182 mozilla::ipc::AssertIsOnBackgroundThread();
183 MOZ_ASSERT(aFileSystem);
186 FileSystemResponseValue GetFileOrDirectoryTaskParent::GetSuccessRequestResult(
187 ErrorResult& aRv) const {
188 mozilla::ipc::AssertIsOnBackgroundThread();
190 nsAutoString path;
191 aRv = mTargetPath->GetPath(path);
192 if (NS_WARN_IF(aRv.Failed())) {
193 return FileSystemDirectoryResponse();
196 if (mIsDirectory) {
197 return FileSystemDirectoryResponse(path);
200 RefPtr<BlobImpl> blobImpl = new FileBlobImpl(mTargetPath);
202 IPCBlob ipcBlob;
203 aRv = IPCBlobUtils::Serialize(blobImpl, ipcBlob);
204 if (NS_WARN_IF(aRv.Failed())) {
205 return FileSystemDirectoryResponse();
208 return FileSystemFileResponse(ipcBlob);
211 nsresult GetFileOrDirectoryTaskParent::IOWork() {
212 MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
213 MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
215 if (mFileSystem->IsShutdown()) {
216 return NS_ERROR_FAILURE;
219 // Whether we want to get the root directory.
220 bool exists;
221 nsresult rv = mTargetPath->Exists(&exists);
222 if (NS_WARN_IF(NS_FAILED(rv))) {
223 return rv;
226 if (!exists) {
227 if (!mFileSystem->ShouldCreateDirectory()) {
228 return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
231 rv = mTargetPath->Create(nsIFile::DIRECTORY_TYPE, 0777);
232 if (NS_WARN_IF(NS_FAILED(rv))) {
233 return rv;
237 // Get isDirectory.
238 rv = mTargetPath->IsDirectory(&mIsDirectory);
239 if (NS_WARN_IF(NS_FAILED(rv))) {
240 return rv;
243 if (mIsDirectory) {
244 return NS_OK;
247 bool isFile;
248 // Get isFile
249 rv = mTargetPath->IsFile(&isFile);
250 if (NS_WARN_IF(NS_FAILED(rv))) {
251 return rv;
254 if (!isFile) {
255 // Neither directory or file.
256 return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
259 if (!mFileSystem->IsSafeFile(mTargetPath)) {
260 return NS_ERROR_DOM_SECURITY_ERR;
263 return NS_OK;
266 nsresult GetFileOrDirectoryTaskParent::GetTargetPath(nsAString& aPath) const {
267 return mTargetPath->GetPath(aPath);
270 } // namespace mozilla::dom