Line data Source code
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/. */
6 :
7 : #include "GetFilesTask.h"
8 :
9 : #include "HTMLSplitOnSpacesTokenizer.h"
10 : #include "js/Value.h"
11 : #include "mozilla/dom/File.h"
12 : #include "mozilla/dom/FileSystemBase.h"
13 : #include "mozilla/dom/FileSystemUtils.h"
14 : #include "mozilla/dom/IPCBlobUtils.h"
15 : #include "mozilla/dom/PFileSystemParams.h"
16 : #include "mozilla/dom/Promise.h"
17 : #include "nsIFile.h"
18 : #include "nsStringGlue.h"
19 :
20 : namespace mozilla {
21 : namespace dom {
22 :
23 : /**
24 : * GetFilesTaskChild
25 : */
26 :
27 : /* static */ already_AddRefed<GetFilesTaskChild>
28 0 : GetFilesTaskChild::Create(FileSystemBase* aFileSystem,
29 : Directory* aDirectory,
30 : nsIFile* aTargetPath,
31 : bool aRecursiveFlag,
32 : ErrorResult& aRv)
33 : {
34 0 : MOZ_ASSERT(aFileSystem);
35 0 : MOZ_ASSERT(aDirectory);
36 0 : aFileSystem->AssertIsOnOwningThread();
37 :
38 : nsCOMPtr<nsIGlobalObject> globalObject =
39 0 : do_QueryInterface(aFileSystem->GetParentObject());
40 0 : if (NS_WARN_IF(!globalObject)) {
41 0 : aRv.Throw(NS_ERROR_FAILURE);
42 0 : return nullptr;
43 : }
44 :
45 : RefPtr<GetFilesTaskChild> task =
46 : new GetFilesTaskChild(globalObject, aFileSystem, aDirectory, aTargetPath,
47 0 : aRecursiveFlag);
48 :
49 : // aTargetPath can be null. In this case SetError will be called.
50 :
51 0 : task->mPromise = Promise::Create(globalObject, aRv);
52 0 : if (NS_WARN_IF(aRv.Failed())) {
53 0 : return nullptr;
54 : }
55 :
56 0 : return task.forget();
57 : }
58 :
59 0 : GetFilesTaskChild::GetFilesTaskChild(nsIGlobalObject *aGlobalObject,
60 : FileSystemBase* aFileSystem,
61 : Directory* aDirectory,
62 : nsIFile* aTargetPath,
63 0 : bool aRecursiveFlag)
64 : : FileSystemTaskChildBase(aGlobalObject, aFileSystem)
65 : , mDirectory(aDirectory)
66 : , mTargetPath(aTargetPath)
67 0 : , mRecursiveFlag(aRecursiveFlag)
68 : {
69 0 : MOZ_ASSERT(aFileSystem);
70 0 : MOZ_ASSERT(aDirectory);
71 0 : aFileSystem->AssertIsOnOwningThread();
72 0 : }
73 :
74 0 : GetFilesTaskChild::~GetFilesTaskChild()
75 : {
76 0 : mFileSystem->AssertIsOnOwningThread();
77 0 : }
78 :
79 : already_AddRefed<Promise>
80 0 : GetFilesTaskChild::GetPromise()
81 : {
82 0 : mFileSystem->AssertIsOnOwningThread();
83 0 : return RefPtr<Promise>(mPromise).forget();
84 : }
85 :
86 : FileSystemParams
87 0 : GetFilesTaskChild::GetRequestParams(const nsString& aSerializedDOMPath,
88 : ErrorResult& aRv) const
89 : {
90 0 : mFileSystem->AssertIsOnOwningThread();
91 :
92 0 : nsAutoString path;
93 0 : aRv = mTargetPath->GetPath(path);
94 0 : if (NS_WARN_IF(aRv.Failed())) {
95 0 : return FileSystemGetFilesParams();
96 : }
97 :
98 0 : nsAutoString domPath;
99 0 : mDirectory->GetPath(domPath, aRv);
100 0 : if (NS_WARN_IF(aRv.Failed())) {
101 0 : return FileSystemGetFilesParams();
102 : }
103 :
104 0 : return FileSystemGetFilesParams(aSerializedDOMPath, path, domPath,
105 0 : mRecursiveFlag);
106 : }
107 :
108 : void
109 0 : GetFilesTaskChild::SetSuccessRequestResult(const FileSystemResponseValue& aValue,
110 : ErrorResult& aRv)
111 : {
112 0 : mFileSystem->AssertIsOnOwningThread();
113 0 : MOZ_ASSERT(aValue.type() ==
114 : FileSystemResponseValue::TFileSystemFilesResponse);
115 :
116 0 : FileSystemFilesResponse r = aValue;
117 :
118 0 : if (!mTargetData.SetLength(r.data().Length(), mozilla::fallible_t())) {
119 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
120 0 : return;
121 : }
122 :
123 0 : for (uint32_t i = 0; i < r.data().Length(); ++i) {
124 0 : const FileSystemFileResponse& data = r.data()[i];
125 0 : RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(data.blob());
126 0 : MOZ_ASSERT(blobImpl);
127 :
128 0 : mTargetData[i] = File::Create(mFileSystem->GetParentObject(), blobImpl);
129 : }
130 : }
131 :
132 : void
133 0 : GetFilesTaskChild::HandlerCallback()
134 : {
135 0 : mFileSystem->AssertIsOnOwningThread();
136 0 : if (mFileSystem->IsShutdown()) {
137 0 : mPromise = nullptr;
138 0 : return;
139 : }
140 :
141 0 : if (HasError()) {
142 0 : mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
143 0 : mPromise = nullptr;
144 0 : return;
145 : }
146 :
147 0 : mPromise->MaybeResolve(mTargetData);
148 0 : mPromise = nullptr;
149 : }
150 :
151 : /**
152 : * GetFilesTaskParent
153 : */
154 :
155 : /* static */ already_AddRefed<GetFilesTaskParent>
156 0 : GetFilesTaskParent::Create(FileSystemBase* aFileSystem,
157 : const FileSystemGetFilesParams& aParam,
158 : FileSystemRequestParent* aParent,
159 : ErrorResult& aRv)
160 : {
161 0 : MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
162 0 : AssertIsOnBackgroundThread();
163 0 : MOZ_ASSERT(aFileSystem);
164 :
165 : RefPtr<GetFilesTaskParent> task =
166 0 : new GetFilesTaskParent(aFileSystem, aParam, aParent);
167 :
168 0 : aRv = NS_NewLocalFile(aParam.realPath(), true,
169 0 : getter_AddRefs(task->mTargetPath));
170 0 : if (NS_WARN_IF(aRv.Failed())) {
171 0 : return nullptr;
172 : }
173 :
174 0 : return task.forget();
175 : }
176 :
177 0 : GetFilesTaskParent::GetFilesTaskParent(FileSystemBase* aFileSystem,
178 : const FileSystemGetFilesParams& aParam,
179 0 : FileSystemRequestParent* aParent)
180 : : FileSystemTaskParentBase(aFileSystem, aParam, aParent)
181 0 : , GetFilesHelperBase(aParam.recursiveFlag())
182 0 : , mDirectoryDOMPath(aParam.domPath())
183 : {
184 0 : MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
185 0 : AssertIsOnBackgroundThread();
186 0 : MOZ_ASSERT(aFileSystem);
187 0 : }
188 :
189 : FileSystemResponseValue
190 0 : GetFilesTaskParent::GetSuccessRequestResult(ErrorResult& aRv) const
191 : {
192 0 : AssertIsOnBackgroundThread();
193 :
194 0 : FallibleTArray<FileSystemFileResponse> inputs;
195 0 : if (!inputs.SetLength(mTargetBlobImplArray.Length(), mozilla::fallible_t())) {
196 0 : FileSystemFilesResponse response;
197 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
198 0 : return response;
199 : }
200 :
201 0 : for (unsigned i = 0; i < mTargetBlobImplArray.Length(); i++) {
202 0 : IPCBlob ipcBlob;
203 0 : aRv = IPCBlobUtils::Serialize(mTargetBlobImplArray[i],
204 0 : mRequestParent->Manager(), ipcBlob);
205 0 : if (NS_WARN_IF(aRv.Failed())) {
206 0 : FileSystemFilesResponse response;
207 0 : return response;
208 : }
209 :
210 0 : inputs[i] = FileSystemFileResponse(ipcBlob);
211 : }
212 :
213 0 : FileSystemFilesResponse response;
214 0 : response.data().SwapElements(inputs);
215 0 : return response;
216 : }
217 :
218 : nsresult
219 0 : GetFilesTaskParent::IOWork()
220 : {
221 0 : MOZ_ASSERT(XRE_IsParentProcess(),
222 : "Only call from parent process!");
223 0 : MOZ_ASSERT(!NS_IsMainThread(), "Only call on I/O thread!");
224 :
225 0 : if (mFileSystem->IsShutdown()) {
226 0 : return NS_ERROR_FAILURE;
227 : }
228 :
229 : bool exists;
230 0 : nsresult rv = mTargetPath->Exists(&exists);
231 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
232 0 : return rv;
233 : }
234 :
235 0 : if (!exists) {
236 0 : return NS_OK;
237 : }
238 :
239 : bool isDir;
240 0 : rv = mTargetPath->IsDirectory(&isDir);
241 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
242 0 : return rv;
243 : }
244 :
245 0 : if (!isDir) {
246 0 : return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
247 : }
248 :
249 : // Get isDirectory.
250 0 : rv = ExploreDirectory(mDirectoryDOMPath, mTargetPath);
251 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
252 0 : return rv;
253 : }
254 :
255 0 : return NS_OK;
256 : }
257 :
258 : nsresult
259 0 : GetFilesTaskParent::GetTargetPath(nsAString& aPath) const
260 : {
261 0 : return mTargetPath->GetPath(aPath);
262 : }
263 :
264 : } // namespace dom
265 : } // namespace mozilla
|