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 #ifndef mozilla_dom_FileSystemTaskBase_h
8 #define mozilla_dom_FileSystemTaskBase_h
10 #include "mozilla/ErrorResult.h"
11 #include "mozilla/dom/FileSystemRequestParent.h"
12 #include "mozilla/dom/PFileSystemRequestChild.h"
13 #include "mozilla/dom/ipc/Blob.h"
15 class nsIDOMFile;
17 namespace mozilla {
18 namespace dom {
20 class FileSystemBase;
21 class FileSystemParams;
22 class Promise;
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();
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);
131 FileSystemBase*
132 GetFileSystem() const;
134 /*
135 * Get the type of permission access required to perform this task.
136 */
137 virtual void
138 GetPermissionAccessType(nsCString& aAccess) const = 0;
140 NS_DECL_NSIRUNNABLE
141 protected:
142 /*
143 * To create a task to handle the page content request.
144 */
145 FileSystemTaskBase(FileSystemBase* aFileSystem);
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);
155 virtual
156 ~FileSystemTaskBase();
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;
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;
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;
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;
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;
201 bool
202 HasError() const { return mErrorValue != NS_OK; }
204 // Overrides PFileSystemRequestChild
205 virtual bool
206 Recv__delete__(const FileSystemResponseValue& value) MOZ_OVERRIDE;
208 BlobParent*
209 GetBlobParent(nsIDOMFile* aFile) const;
211 nsresult mErrorValue;
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();
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;
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 };
241 } // namespace dom
242 } // namespace mozilla
244 #endif // mozilla_dom_FileSystemTaskBase_h