Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* vim: set ts=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 "RemoveTask.h"
9 #include "DOMError.h"
10 #include "mozilla/dom/FileSystemBase.h"
11 #include "mozilla/dom/FileSystemUtils.h"
12 #include "mozilla/dom/Promise.h"
13 #include "nsIDOMFile.h"
14 #include "nsIFile.h"
15 #include "nsStringGlue.h"
17 namespace mozilla {
18 namespace dom {
20 RemoveTask::RemoveTask(FileSystemBase* aFileSystem,
21 const nsAString& aDirPath,
22 nsIDOMFile* aTargetFile,
23 const nsAString& aTargetPath,
24 bool aRecursive)
25 : FileSystemTaskBase(aFileSystem)
26 , mDirRealPath(aDirPath)
27 , mTargetFile(aTargetFile)
28 , mTargetRealPath(aTargetPath)
29 , mRecursive(aRecursive)
30 , mReturnValue(false)
31 {
32 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
33 MOZ_ASSERT(aFileSystem);
34 nsCOMPtr<nsIGlobalObject> globalObject =
35 do_QueryInterface(aFileSystem->GetWindow());
36 if (!globalObject) {
37 return;
38 }
39 mPromise = new Promise(globalObject);
40 }
42 RemoveTask::RemoveTask(FileSystemBase* aFileSystem,
43 const FileSystemRemoveParams& aParam,
44 FileSystemRequestParent* aParent)
45 : FileSystemTaskBase(aFileSystem, aParam, aParent)
46 , mRecursive(false)
47 , mReturnValue(false)
48 {
49 MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
50 "Only call from parent process!");
51 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
52 MOZ_ASSERT(aFileSystem);
54 mDirRealPath = aParam.directory();
56 mRecursive = aParam.recursive();
58 const FileSystemPathOrFileValue& target = aParam.target();
60 if (target.type() == FileSystemPathOrFileValue::TnsString) {
61 mTargetRealPath = target;
62 return;
63 }
65 BlobParent* bp = static_cast<BlobParent*>(static_cast<PBlobParent*>(target));
66 nsCOMPtr<nsIDOMBlob> blob = bp->GetBlob();
67 mTargetFile = do_QueryInterface(blob);
68 MOZ_ASSERT(mTargetFile, "mTargetFile should not be null.");
69 }
71 RemoveTask::~RemoveTask()
72 {
73 MOZ_ASSERT(!mPromise || NS_IsMainThread(),
74 "mPromise should be released on main thread!");
75 }
77 already_AddRefed<Promise>
78 RemoveTask::GetPromise()
79 {
80 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
81 return nsRefPtr<Promise>(mPromise).forget();
82 }
84 FileSystemParams
85 RemoveTask::GetRequestParams(const nsString& aFileSystem) const
86 {
87 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
88 FileSystemRemoveParams param;
89 param.filesystem() = aFileSystem;
90 param.directory() = mDirRealPath;
91 param.recursive() = mRecursive;
92 if (mTargetFile) {
93 BlobChild* actor
94 = ContentChild::GetSingleton()->GetOrCreateActorForBlob(mTargetFile);
95 if (actor) {
96 param.target() = actor;
97 }
98 } else {
99 param.target() = mTargetRealPath;
100 }
101 return param;
102 }
104 FileSystemResponseValue
105 RemoveTask::GetSuccessRequestResult() const
106 {
107 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
108 return FileSystemBooleanResponse(mReturnValue);
109 }
111 void
112 RemoveTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue)
113 {
114 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
115 FileSystemBooleanResponse r = aValue;
116 mReturnValue = r.success();
117 }
119 nsresult
120 RemoveTask::Work()
121 {
122 MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
123 "Only call from parent process!");
124 MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
126 if (mFileSystem->IsShutdown()) {
127 return NS_ERROR_FAILURE;
128 }
130 // Get the DOM path if a DOMFile is passed as the target.
131 if (mTargetFile) {
132 if (!mFileSystem->GetRealPath(mTargetFile, mTargetRealPath)) {
133 return NS_ERROR_DOM_SECURITY_ERR;
134 }
135 if (!FileSystemUtils::IsDescendantPath(mDirRealPath, mTargetRealPath)) {
136 return NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR;
137 }
138 }
140 nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath);
141 if (!file) {
142 return NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
143 }
145 bool exists = false;
146 nsresult rv = file->Exists(&exists);
147 if (NS_WARN_IF(NS_FAILED(rv))) {
148 return rv;
149 }
151 if (!exists) {
152 mReturnValue = false;
153 return NS_OK;
154 }
156 bool isFile = false;
157 rv = file->IsFile(&isFile);
158 if (NS_WARN_IF(NS_FAILED(rv))) {
159 return rv;
160 }
162 if (isFile && !mFileSystem->IsSafeFile(file)) {
163 return NS_ERROR_DOM_SECURITY_ERR;
164 }
166 rv = file->Remove(mRecursive);
167 if (NS_WARN_IF(NS_FAILED(rv))) {
168 return rv;
169 }
171 mReturnValue = true;
173 return NS_OK;
174 }
176 void
177 RemoveTask::HandlerCallback()
178 {
179 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
180 if (mFileSystem->IsShutdown()) {
181 mPromise = nullptr;
182 return;
183 }
185 if (HasError()) {
186 nsRefPtr<DOMError> domError = new DOMError(mFileSystem->GetWindow(),
187 mErrorValue);
188 mPromise->MaybeReject(domError);
189 mPromise = nullptr;
190 return;
191 }
193 mPromise->MaybeResolve(mReturnValue);
194 mPromise = nullptr;
195 }
197 void
198 RemoveTask::GetPermissionAccessType(nsCString& aAccess) const
199 {
200 aAccess.AssignLiteral("write");
201 }
203 } // namespace dom
204 } // namespace mozilla