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