|
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/. */ |
|
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 "mozilla/dom/ipc/Blob.h" |
|
14 |
|
15 class nsIDOMFile; |
|
16 |
|
17 namespace mozilla { |
|
18 namespace dom { |
|
19 |
|
20 class FileSystemBase; |
|
21 class FileSystemParams; |
|
22 class Promise; |
|
23 |
|
24 /* |
|
25 * The base class to implement a Task class. |
|
26 * The task is used to handle the OOP (out of process) operations. |
|
27 * The file system operations can only be performed in the parent process. When |
|
28 * performing such a parent-process-only operation, a task will delivered the |
|
29 * operation to the parent process if needed. |
|
30 * |
|
31 * The following diagram illustrates the how a API call from the content page |
|
32 * starts a task and gets call back results. |
|
33 * |
|
34 * The left block is the call sequence inside the child process, while the |
|
35 * right block is the call sequence inside the parent process. |
|
36 * |
|
37 * There are two types of API call. One is from the content page of the child |
|
38 * process and we mark the steps as (1) to (8). The other is from the content |
|
39 * page of the parent process and we mark the steps as (1') to (4'). |
|
40 * |
|
41 * Page Page |
|
42 * | | |
|
43 * | (1) | (1') |
|
44 * ______|________________ | _____________________|_____________ |
|
45 * | | | | | | | |
|
46 * | | Task in | | | Task in | | |
|
47 * | | Child Process | | | Parent Process | | |
|
48 * | V | IPC | V | |
|
49 * [new FileSystemTaskBase()] | | [new FileSystemTaskBase()] | |
|
50 * | | | | | | | |
|
51 * | | (2) | | | (2') | |
|
52 * | V | (3) | | | |
|
53 * | [GetRequestParams]------------->[new FileSystemTaskBase(...)] | |
|
54 * | | | | | | |
|
55 * | | | | | (4) | | |
|
56 * | | | | | V | |
|
57 * | | | | -----------> [Work] | |
|
58 * | | IPC | | | |
|
59 * | | | | (5) | (3') | |
|
60 * | | | | V | |
|
61 * | | | | --------[HandleResult] | |
|
62 * | | | | | | | |
|
63 * | | | | (6) | | |
|
64 * | | (7) | V | | |
|
65 * | [SetRequestResult]<-------------[GetRequestResult] | | |
|
66 * | | | | | (4') | |
|
67 * | | (8) | | | | | |
|
68 * | V | | | V | |
|
69 * |[HandlerCallback] | IPC | [HandlerCallback] | |
|
70 * |_______|_______________| | |_________________________|_________| |
|
71 * | | | |
|
72 * V V |
|
73 * Page Page |
|
74 * |
|
75 * 1. From child process page |
|
76 * Child: |
|
77 * (1) Call FileSystem API from content page with JS. Create a task and run. |
|
78 * The base constructor [FileSystemTaskBase()] of the task should be called. |
|
79 * (2) Forward the task to the parent process through the IPC and call |
|
80 * [GetRequestParams] to prepare the parameters of the IPC. |
|
81 * Parent: |
|
82 * (3) The parent process receives IPC and handle it in |
|
83 * FileystemRequestParent. |
|
84 * Get the IPC parameters and create a task to run the IPC task. The base |
|
85 * constructor [FileSystemTaskBase(aParam, aParent)] of the task should be |
|
86 * called to set the task as an IPC task. |
|
87 * (4) The task operation will be performed in the member function of [Work]. |
|
88 * A worker thread will be created to run that function. If error occurs |
|
89 * during the operation, call [SetError] to record the error and then abort. |
|
90 * (5) After finishing the task operation, call [HandleResult] to send the |
|
91 * result back to the child process though the IPC. |
|
92 * (6) Call [GetRequestResult] request result to prepare the parameters of the |
|
93 * IPC. Because the formats of the error result for different task are the |
|
94 * same, FileSystemTaskBase can handle the error message without interfering. |
|
95 * Each task only needs to implement its specific success result preparation |
|
96 * function -[GetSuccessRequestResult]. |
|
97 * Child: |
|
98 * (7) The child process receives IPC and calls [SetRequestResult] to get the |
|
99 * task result. Each task needs to implement its specific success result |
|
100 * parsing function [SetSuccessRequestResult] to get the success result. |
|
101 * (8) Call [HandlerCallback] to send the task result to the content page. |
|
102 * 2. From parent process page |
|
103 * We don't need to send the task parameters and result to other process. So |
|
104 * there are less steps, but their functions are the same. The correspondence |
|
105 * between the two types of steps is: |
|
106 * (1') = (1), |
|
107 * (2') = (4), |
|
108 * (3') = (5), |
|
109 * (4') = (8). |
|
110 */ |
|
111 class FileSystemTaskBase |
|
112 : public nsRunnable |
|
113 , public PFileSystemRequestChild |
|
114 { |
|
115 public: |
|
116 /* |
|
117 * Start the task. If the task is running the child process, it will be |
|
118 * forwarded to parent process by IPC, or else, creates a worker thread to |
|
119 * do the task work. |
|
120 */ |
|
121 void |
|
122 Start(); |
|
123 |
|
124 /* |
|
125 * The error codes are defined in xpcom/base/ErrorList.h and their |
|
126 * corresponding error name and message are defined in dom/base/domerr.msg. |
|
127 */ |
|
128 void |
|
129 SetError(const nsresult& aErrorCode); |
|
130 |
|
131 FileSystemBase* |
|
132 GetFileSystem() const; |
|
133 |
|
134 /* |
|
135 * Get the type of permission access required to perform this task. |
|
136 */ |
|
137 virtual void |
|
138 GetPermissionAccessType(nsCString& aAccess) const = 0; |
|
139 |
|
140 NS_DECL_NSIRUNNABLE |
|
141 protected: |
|
142 /* |
|
143 * To create a task to handle the page content request. |
|
144 */ |
|
145 FileSystemTaskBase(FileSystemBase* aFileSystem); |
|
146 |
|
147 /* |
|
148 * To create a parent process task delivered from the child process through |
|
149 * IPC. |
|
150 */ |
|
151 FileSystemTaskBase(FileSystemBase* aFileSystem, |
|
152 const FileSystemParams& aParam, |
|
153 FileSystemRequestParent* aParent); |
|
154 |
|
155 virtual |
|
156 ~FileSystemTaskBase(); |
|
157 |
|
158 /* |
|
159 * The function to perform task operation. It will be run on the worker |
|
160 * thread of the parent process. |
|
161 * Overrides this function to define the task operation for individual task. |
|
162 */ |
|
163 virtual nsresult |
|
164 Work() = 0; |
|
165 |
|
166 /* |
|
167 * After the task is completed, this function will be called to pass the task |
|
168 * result to the content page. |
|
169 * Override this function to handle the call back to the content page. |
|
170 */ |
|
171 virtual void |
|
172 HandlerCallback() = 0; |
|
173 |
|
174 /* |
|
175 * Wrap the task parameter to FileSystemParams for sending it through IPC. |
|
176 * It will be called when we need to forward a task from the child process to |
|
177 * the prarent process. |
|
178 * @param filesystem The string representation of the file system. |
|
179 */ |
|
180 virtual FileSystemParams |
|
181 GetRequestParams(const nsString& aFileSystem) const = 0; |
|
182 |
|
183 /* |
|
184 * Wrap the task success result to FileSystemResponseValue for sending it |
|
185 * through IPC. |
|
186 * It will be called when the task is completed successfully and we need to |
|
187 * send the task success result back to the child process. |
|
188 */ |
|
189 virtual FileSystemResponseValue |
|
190 GetSuccessRequestResult() const = 0; |
|
191 |
|
192 /* |
|
193 * Unwrap the IPC message to get the task success result. |
|
194 * It will be called when the task is completed successfully and an IPC |
|
195 * message is received in the child process and we want to get the task |
|
196 * success result. |
|
197 */ |
|
198 virtual void |
|
199 SetSuccessRequestResult(const FileSystemResponseValue& aValue) = 0; |
|
200 |
|
201 bool |
|
202 HasError() const { return mErrorValue != NS_OK; } |
|
203 |
|
204 // Overrides PFileSystemRequestChild |
|
205 virtual bool |
|
206 Recv__delete__(const FileSystemResponseValue& value) MOZ_OVERRIDE; |
|
207 |
|
208 BlobParent* |
|
209 GetBlobParent(nsIDOMFile* aFile) const; |
|
210 |
|
211 nsresult mErrorValue; |
|
212 |
|
213 nsRefPtr<FileSystemBase> mFileSystem; |
|
214 nsRefPtr<FileSystemRequestParent> mRequestParent; |
|
215 private: |
|
216 /* |
|
217 * After finishing the task operation, handle the task result. |
|
218 * If it is an IPC task, send back the IPC result. Or else, send the result |
|
219 * to the content page. |
|
220 */ |
|
221 void |
|
222 HandleResult(); |
|
223 |
|
224 /* |
|
225 * Wrap the task result to FileSystemResponseValue for sending it through IPC. |
|
226 * It will be called when the task is completed and we need to |
|
227 * send the task result back to the child process. |
|
228 */ |
|
229 FileSystemResponseValue |
|
230 GetRequestResult() const; |
|
231 |
|
232 /* |
|
233 * Unwrap the IPC message to get the task result. |
|
234 * It will be called when the task is completed and an IPC message is received |
|
235 * in the child process and we want to get the task result. |
|
236 */ |
|
237 void |
|
238 SetRequestResult(const FileSystemResponseValue& aValue); |
|
239 }; |
|
240 |
|
241 } // namespace dom |
|
242 } // namespace mozilla |
|
243 |
|
244 #endif // mozilla_dom_FileSystemTaskBase_h |