Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
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 "mozilla/dom/FileSystemTaskBase.h"
9 #include "nsNetUtil.h" // Stream transport service.
10 #include "mozilla/dom/ContentChild.h"
11 #include "mozilla/dom/FileSystemBase.h"
12 #include "mozilla/dom/FileSystemRequestParent.h"
13 #include "mozilla/dom/FileSystemUtils.h"
14 #include "mozilla/dom/Promise.h"
15 #include "mozilla/dom/PContent.h"
16 #include "mozilla/unused.h"
17 #include "nsDOMFile.h"
19 namespace mozilla {
20 namespace dom {
22 FileSystemTaskBase::FileSystemTaskBase(FileSystemBase* aFileSystem)
23 : mErrorValue(NS_OK)
24 , mFileSystem(aFileSystem)
25 {
26 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
27 MOZ_ASSERT(aFileSystem, "aFileSystem should not be null.");
28 }
30 FileSystemTaskBase::FileSystemTaskBase(FileSystemBase* aFileSystem,
31 const FileSystemParams& aParam,
32 FileSystemRequestParent* aParent)
33 : mErrorValue(NS_OK)
34 , mFileSystem(aFileSystem)
35 , mRequestParent(aParent)
36 {
37 MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
38 "Only call from parent process!");
39 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
40 MOZ_ASSERT(aFileSystem, "aFileSystem should not be null.");
41 }
43 FileSystemTaskBase::~FileSystemTaskBase()
44 {
45 }
47 FileSystemBase*
48 FileSystemTaskBase::GetFileSystem() const
49 {
50 return mFileSystem.get();
51 }
53 void
54 FileSystemTaskBase::Start()
55 {
56 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
58 if (HasError()) {
59 NS_DispatchToMainThread(this);
60 return;
61 }
63 if (FileSystemUtils::IsParentProcess()) {
64 // Run in parent process.
65 // Start worker thread.
66 nsCOMPtr<nsIEventTarget> target
67 = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
68 NS_ASSERTION(target, "Must have stream transport service.");
69 target->Dispatch(this, NS_DISPATCH_NORMAL);
70 return;
71 }
73 // Run in child process.
74 if (mFileSystem->IsShutdown()) {
75 return;
76 }
78 // Retain a reference so the task object isn't deleted without IPDL's
79 // knowledge. The reference will be released by
80 // mozilla::dom::ContentChild::DeallocPFileSystemRequestChild.
81 NS_ADDREF_THIS();
82 ContentChild::GetSingleton()->SendPFileSystemRequestConstructor(this,
83 GetRequestParams(mFileSystem->ToString()));
84 }
86 NS_IMETHODIMP
87 FileSystemTaskBase::Run()
88 {
89 if (!NS_IsMainThread()) {
90 // Run worker thread tasks
91 nsresult rv = Work();
92 if (NS_FAILED(rv)) {
93 SetError(rv);
94 }
95 // Dispatch itself to main thread
96 NS_DispatchToMainThread(this);
97 return NS_OK;
98 }
100 // Run main thread tasks
101 HandleResult();
102 return NS_OK;
103 }
105 void
106 FileSystemTaskBase::HandleResult()
107 {
108 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
109 if (mFileSystem->IsShutdown()) {
110 return;
111 }
112 if (mRequestParent && mRequestParent->IsRunning()) {
113 unused << mRequestParent->Send__delete__(mRequestParent,
114 GetRequestResult());
115 } else {
116 HandlerCallback();
117 }
118 }
120 FileSystemResponseValue
121 FileSystemTaskBase::GetRequestResult() const
122 {
123 MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
124 "Only call from parent process!");
125 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
126 if (HasError()) {
127 return FileSystemErrorResponse(mErrorValue);
128 } else {
129 return GetSuccessRequestResult();
130 }
131 }
133 void
134 FileSystemTaskBase::SetRequestResult(const FileSystemResponseValue& aValue)
135 {
136 MOZ_ASSERT(!FileSystemUtils::IsParentProcess(),
137 "Only call from child process!");
138 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
139 if (aValue.type() == FileSystemResponseValue::TFileSystemErrorResponse) {
140 FileSystemErrorResponse r = aValue;
141 mErrorValue = r.error();
142 } else {
143 SetSuccessRequestResult(aValue);
144 }
145 }
147 bool
148 FileSystemTaskBase::Recv__delete__(const FileSystemResponseValue& aValue)
149 {
150 SetRequestResult(aValue);
151 HandlerCallback();
152 return true;
153 }
155 BlobParent*
156 FileSystemTaskBase::GetBlobParent(nsIDOMFile* aFile) const
157 {
158 MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
159 "Only call from parent process!");
160 MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
161 MOZ_ASSERT(aFile);
163 // Load the lazy dom file data from the parent before sending to the child.
164 nsString mimeType;
165 aFile->GetType(mimeType);
166 uint64_t fileSize;
167 aFile->GetSize(&fileSize);
168 uint64_t lastModifiedDate;
169 aFile->GetMozLastModifiedDate(&lastModifiedDate);
171 ContentParent* cp = static_cast<ContentParent*>(mRequestParent->Manager());
172 return cp->GetOrCreateActorForBlob(aFile);
173 }
175 void
176 FileSystemTaskBase::SetError(const nsresult& aErrorValue)
177 {
178 uint16_t module = NS_ERROR_GET_MODULE(aErrorValue);
179 if (module == NS_ERROR_MODULE_DOM_FILESYSTEM ||
180 module == NS_ERROR_MODULE_DOM_FILE ||
181 module == NS_ERROR_MODULE_DOM) {
182 mErrorValue = aErrorValue;
183 return;
184 }
186 switch (aErrorValue) {
187 case NS_OK:
188 mErrorValue = NS_OK;
189 return;
191 case NS_ERROR_FILE_INVALID_PATH:
192 case NS_ERROR_FILE_UNRECOGNIZED_PATH:
193 mErrorValue = NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
194 return;
196 case NS_ERROR_FILE_DESTINATION_NOT_DIR:
197 mErrorValue = NS_ERROR_DOM_FILESYSTEM_INVALID_MODIFICATION_ERR;
198 return;
200 case NS_ERROR_FILE_ACCESS_DENIED:
201 case NS_ERROR_FILE_DIR_NOT_EMPTY:
202 mErrorValue = NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR;
203 return;
205 case NS_ERROR_FILE_TARGET_DOES_NOT_EXIST:
206 case NS_ERROR_NOT_AVAILABLE:
207 mErrorValue = NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
208 return;
210 case NS_ERROR_FILE_ALREADY_EXISTS:
211 mErrorValue = NS_ERROR_DOM_FILESYSTEM_PATH_EXISTS_ERR;
212 return;
214 case NS_ERROR_FILE_NOT_DIRECTORY:
215 mErrorValue = NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
216 return;
218 case NS_ERROR_UNEXPECTED:
219 default:
220 mErrorValue = NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR;
221 return;
222 }
223 }
225 } // namespace dom
226 } // namespace mozilla