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 : #ifndef mozilla_dom_FileSystemTaskBase_h
8 : #define mozilla_dom_FileSystemTaskBase_h
9 :
10 : #include "mozilla/ErrorResult.h"
11 : #include "mozilla/dom/FileSystemRequestParent.h"
12 : #include "mozilla/dom/PFileSystemRequestChild.h"
13 : #include "nsIIPCBackgroundChildCreateCallback.h"
14 : #include "nsThreadUtils.h"
15 :
16 : namespace mozilla {
17 : namespace dom {
18 :
19 : class BlobImpl;
20 : class FileSystemBase;
21 : class FileSystemParams;
22 :
23 : /*
24 : * The base class to implement a Task class.
25 : * The file system operations can only be performed in the parent process. In
26 : * order to avoid duplicated code, we used PBackground for child-parent and
27 : * parent-parent communications.
28 : *
29 : * The following diagram illustrates the how a API call from the content page
30 : * starts a task and gets call back results.
31 : *
32 : * The left block is the call sequence inside any process loading content, while
33 : * the right block is the call sequence only inside the parent process.
34 : *
35 : * Page
36 : * |
37 : * | (1)
38 : * ______|_________________________ | _________________________________
39 : * | | | | | |
40 : * | | | | | |
41 : * | V | IPC | PBackground thread on |
42 : * | [new FileSystemTaskChildBase()] | | | the parent process |
43 : * | | | | | |
44 : * | | (2) | | |
45 : * | V | (3) | |
46 : * | [GetRequestParams]------------------->[new FileSystemTaskParentBase()] |
47 : * | | | | |
48 : * | | | | | (4) _____________ |
49 : * | | | | | | | |
50 : * | | | | | | I/O Thread | |
51 : * | | | | | | | |
52 : * | | | | ---------> [IOWork] | |
53 : * | | IPC | | | | |
54 : * | | | | | | (5) | |
55 : * | | | | -------------- | |
56 : * | | | | | |_____________| |
57 : * | | | | | |
58 : * | | | | V |
59 : * | | | | [HandleResult] |
60 : * | | | | | |
61 : * | | | | (6) |
62 : * | | (7) | V |
63 : * | [SetRequestResult]<---------------------[GetRequestResult] |
64 : * | | | | |
65 : * | | (8) | | | |
66 : * | V | | | |
67 : * |[HandlerCallback] | IPC | |
68 : * |_______|_________________________| | |_________________________________|
69 : * | |
70 : * V
71 : * Page
72 : *
73 : * 1. From the process that is handling the request
74 : * Child/Parent (it can be in any process):
75 : * (1) Call FileSystem API from content page with JS. Create a task and run.
76 : * The base constructor [FileSystemTaskChildBase()] of the task should be
77 : * called.
78 : * (2) Forward the task to the parent process through the IPC and call
79 : * [GetRequestParams] to prepare the parameters of the IPC.
80 : * Parent:
81 : * (3) The parent process receives IPC and handle it in
82 : * FileystemRequestParent. Get the IPC parameters and create a task to run the
83 : * IPC task.
84 : * (4) The task operation will be performed in the member function of [IOWork].
85 : * A I/O thread will be created to run that function. If error occurs
86 : * during the operation, call [SetError] to record the error and then abort.
87 : * (5) After finishing the task operation, call [HandleResult] to send the
88 : * result back to the child process though the IPC.
89 : * (6) Call [GetRequestResult] request result to prepare the parameters of the
90 : * IPC. Because the formats of the error result for different task are the
91 : * same, FileSystemTaskChildBase can handle the error message without
92 : * interfering.
93 : * Each task only needs to implement its specific success result preparation
94 : * function -[GetSuccessRequestResult].
95 : * Child/Parent:
96 : * (7) The process receives IPC and calls [SetRequestResult] to get the
97 : * task result. Each task needs to implement its specific success result
98 : * parsing function [SetSuccessRequestResult] to get the success result.
99 : * (8) Call [HandlerCallback] to send the task result to the content page.
100 : */
101 : class FileSystemTaskChildBase : public PFileSystemRequestChild
102 : , public nsIIPCBackgroundChildCreateCallback
103 : {
104 : public:
105 : NS_DECL_ISUPPORTS
106 : NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
107 :
108 : /*
109 : * Start the task. It will dispatch all the information to the parent process,
110 : * PBackground thread. This method must be called from the owning thread.
111 : */
112 : void
113 : Start();
114 :
115 : /*
116 : * The error codes are defined in xpcom/base/ErrorList.h and their
117 : * corresponding error name and message are defined in dom/base/domerr.msg.
118 : */
119 : void
120 : SetError(const nsresult& aErrorCode);
121 :
122 : FileSystemBase*
123 : GetFileSystem() const;
124 :
125 : /*
126 : * After the task is completed, this function will be called to pass the task
127 : * result to the content page. This method is called in the owning thread.
128 : * Override this function to handle the call back to the content page.
129 : */
130 : virtual void
131 : HandlerCallback() = 0;
132 :
133 : bool
134 0 : HasError() const { return NS_FAILED(mErrorValue); }
135 :
136 : protected:
137 : /*
138 : * To create a task to handle the page content request.
139 : */
140 : FileSystemTaskChildBase(nsIGlobalObject* aGlobalObject,
141 : FileSystemBase* aFileSystem);
142 :
143 : virtual
144 : ~FileSystemTaskChildBase();
145 :
146 : /*
147 : * Wrap the task parameter to FileSystemParams for sending it through IPC.
148 : * It will be called when we need to forward a task from the child process to
149 : * the parent process. This method runs in the owning thread.
150 : * @param filesystem The string representation of the file system.
151 : */
152 : virtual FileSystemParams
153 : GetRequestParams(const nsString& aSerializedDOMPath,
154 : ErrorResult& aRv) const = 0;
155 :
156 : /*
157 : * Unwrap the IPC message to get the task success result.
158 : * It will be called when the task is completed successfully and an IPC
159 : * message is received in the child process and we want to get the task
160 : * success result. This method runs in the owning thread.
161 : */
162 : virtual void
163 : SetSuccessRequestResult(const FileSystemResponseValue& aValue,
164 : ErrorResult& aRv) = 0;
165 :
166 : // Overrides PFileSystemRequestChild
167 : virtual mozilla::ipc::IPCResult
168 : Recv__delete__(const FileSystemResponseValue& value) override;
169 :
170 : nsresult mErrorValue;
171 : RefPtr<FileSystemBase> mFileSystem;
172 : nsCOMPtr<nsIGlobalObject> mGlobalObject;
173 :
174 : private:
175 :
176 : /*
177 : * Unwrap the IPC message to get the task result.
178 : * It will be called when the task is completed and an IPC message is received
179 : * in the content process and we want to get the task result. This runs on the
180 : * owning thread.
181 : */
182 : void
183 : SetRequestResult(const FileSystemResponseValue& aValue);
184 : };
185 :
186 : // This class is the 'alter ego' of FileSystemTaskChildBase in the PBackground
187 : // world.
188 : class FileSystemTaskParentBase : public Runnable
189 : {
190 : public:
191 : FileSystemTaskParentBase()
192 : : Runnable("FileSystemTaskParentBase")
193 : {}
194 :
195 : /*
196 : * Start the task. This must be called from the PBackground thread only.
197 : */
198 : void
199 : Start();
200 :
201 : /*
202 : * The error codes are defined in xpcom/base/ErrorList.h and their
203 : * corresponding error name and message are defined in dom/base/domerr.msg.
204 : */
205 : void
206 : SetError(const nsresult& aErrorCode);
207 :
208 : /*
209 : * The function to perform task operation. It will be run on the I/O
210 : * thread of the parent process.
211 : * Overrides this function to define the task operation for individual task.
212 : */
213 : virtual nsresult
214 : IOWork() = 0;
215 :
216 : /*
217 : * Wrap the task success result to FileSystemResponseValue for sending it
218 : * through IPC. This method runs in the PBackground thread.
219 : * It will be called when the task is completed successfully and we need to
220 : * send the task success result back to the child process.
221 : */
222 : virtual FileSystemResponseValue
223 : GetSuccessRequestResult(ErrorResult& aRv) const = 0;
224 :
225 : /*
226 : * After finishing the task operation, handle the task result.
227 : * If it is an IPC task, send back the IPC result. It runs on the PBackground
228 : * thread.
229 : */
230 : void
231 : HandleResult();
232 :
233 : bool
234 0 : HasError() const { return NS_FAILED(mErrorValue); }
235 :
236 : NS_IMETHOD
237 : Run() override;
238 :
239 : virtual nsresult
240 : GetTargetPath(nsAString& aPath) const = 0;
241 :
242 : private:
243 : /*
244 : * Wrap the task result to FileSystemResponseValue for sending it through IPC.
245 : * It will be called when the task is completed and we need to
246 : * send the task result back to the content. This runs on the PBackground
247 : * thread.
248 : */
249 : FileSystemResponseValue
250 : GetRequestResult() const;
251 :
252 : protected:
253 : /*
254 : * To create a parent process task delivered from the child process through
255 : * IPC.
256 : */
257 : FileSystemTaskParentBase(FileSystemBase* aFileSystem,
258 : const FileSystemParams& aParam,
259 : FileSystemRequestParent* aParent);
260 :
261 : virtual
262 : ~FileSystemTaskParentBase();
263 :
264 : nsresult mErrorValue;
265 : RefPtr<FileSystemBase> mFileSystem;
266 : RefPtr<FileSystemRequestParent> mRequestParent;
267 : nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
268 : };
269 :
270 : } // namespace dom
271 : } // namespace mozilla
272 :
273 : #endif // mozilla_dom_FileSystemTaskBase_h
|