1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/filesystem/FileSystemTaskBase.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,244 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_dom_FileSystemTaskBase_h 1.11 +#define mozilla_dom_FileSystemTaskBase_h 1.12 + 1.13 +#include "mozilla/ErrorResult.h" 1.14 +#include "mozilla/dom/FileSystemRequestParent.h" 1.15 +#include "mozilla/dom/PFileSystemRequestChild.h" 1.16 +#include "mozilla/dom/ipc/Blob.h" 1.17 + 1.18 +class nsIDOMFile; 1.19 + 1.20 +namespace mozilla { 1.21 +namespace dom { 1.22 + 1.23 +class FileSystemBase; 1.24 +class FileSystemParams; 1.25 +class Promise; 1.26 + 1.27 +/* 1.28 + * The base class to implement a Task class. 1.29 + * The task is used to handle the OOP (out of process) operations. 1.30 + * The file system operations can only be performed in the parent process. When 1.31 + * performing such a parent-process-only operation, a task will delivered the 1.32 + * operation to the parent process if needed. 1.33 + * 1.34 + * The following diagram illustrates the how a API call from the content page 1.35 + * starts a task and gets call back results. 1.36 + * 1.37 + * The left block is the call sequence inside the child process, while the 1.38 + * right block is the call sequence inside the parent process. 1.39 + * 1.40 + * There are two types of API call. One is from the content page of the child 1.41 + * process and we mark the steps as (1) to (8). The other is from the content 1.42 + * page of the parent process and we mark the steps as (1') to (4'). 1.43 + * 1.44 + * Page Page 1.45 + * | | 1.46 + * | (1) | (1') 1.47 + * ______|________________ | _____________________|_____________ 1.48 + * | | | | | | | 1.49 + * | | Task in | | | Task in | | 1.50 + * | | Child Process | | | Parent Process | | 1.51 + * | V | IPC | V | 1.52 + * [new FileSystemTaskBase()] | | [new FileSystemTaskBase()] | 1.53 + * | | | | | | | 1.54 + * | | (2) | | | (2') | 1.55 + * | V | (3) | | | 1.56 + * | [GetRequestParams]------------->[new FileSystemTaskBase(...)] | 1.57 + * | | | | | | 1.58 + * | | | | | (4) | | 1.59 + * | | | | | V | 1.60 + * | | | | -----------> [Work] | 1.61 + * | | IPC | | | 1.62 + * | | | | (5) | (3') | 1.63 + * | | | | V | 1.64 + * | | | | --------[HandleResult] | 1.65 + * | | | | | | | 1.66 + * | | | | (6) | | 1.67 + * | | (7) | V | | 1.68 + * | [SetRequestResult]<-------------[GetRequestResult] | | 1.69 + * | | | | | (4') | 1.70 + * | | (8) | | | | | 1.71 + * | V | | | V | 1.72 + * |[HandlerCallback] | IPC | [HandlerCallback] | 1.73 + * |_______|_______________| | |_________________________|_________| 1.74 + * | | | 1.75 + * V V 1.76 + * Page Page 1.77 + * 1.78 + * 1. From child process page 1.79 + * Child: 1.80 + * (1) Call FileSystem API from content page with JS. Create a task and run. 1.81 + * The base constructor [FileSystemTaskBase()] of the task should be called. 1.82 + * (2) Forward the task to the parent process through the IPC and call 1.83 + * [GetRequestParams] to prepare the parameters of the IPC. 1.84 + * Parent: 1.85 + * (3) The parent process receives IPC and handle it in 1.86 + * FileystemRequestParent. 1.87 + * Get the IPC parameters and create a task to run the IPC task. The base 1.88 + * constructor [FileSystemTaskBase(aParam, aParent)] of the task should be 1.89 + * called to set the task as an IPC task. 1.90 + * (4) The task operation will be performed in the member function of [Work]. 1.91 + * A worker thread will be created to run that function. If error occurs 1.92 + * during the operation, call [SetError] to record the error and then abort. 1.93 + * (5) After finishing the task operation, call [HandleResult] to send the 1.94 + * result back to the child process though the IPC. 1.95 + * (6) Call [GetRequestResult] request result to prepare the parameters of the 1.96 + * IPC. Because the formats of the error result for different task are the 1.97 + * same, FileSystemTaskBase can handle the error message without interfering. 1.98 + * Each task only needs to implement its specific success result preparation 1.99 + * function -[GetSuccessRequestResult]. 1.100 + * Child: 1.101 + * (7) The child process receives IPC and calls [SetRequestResult] to get the 1.102 + * task result. Each task needs to implement its specific success result 1.103 + * parsing function [SetSuccessRequestResult] to get the success result. 1.104 + * (8) Call [HandlerCallback] to send the task result to the content page. 1.105 + * 2. From parent process page 1.106 + * We don't need to send the task parameters and result to other process. So 1.107 + * there are less steps, but their functions are the same. The correspondence 1.108 + * between the two types of steps is: 1.109 + * (1') = (1), 1.110 + * (2') = (4), 1.111 + * (3') = (5), 1.112 + * (4') = (8). 1.113 + */ 1.114 +class FileSystemTaskBase 1.115 + : public nsRunnable 1.116 + , public PFileSystemRequestChild 1.117 +{ 1.118 +public: 1.119 + /* 1.120 + * Start the task. If the task is running the child process, it will be 1.121 + * forwarded to parent process by IPC, or else, creates a worker thread to 1.122 + * do the task work. 1.123 + */ 1.124 + void 1.125 + Start(); 1.126 + 1.127 + /* 1.128 + * The error codes are defined in xpcom/base/ErrorList.h and their 1.129 + * corresponding error name and message are defined in dom/base/domerr.msg. 1.130 + */ 1.131 + void 1.132 + SetError(const nsresult& aErrorCode); 1.133 + 1.134 + FileSystemBase* 1.135 + GetFileSystem() const; 1.136 + 1.137 + /* 1.138 + * Get the type of permission access required to perform this task. 1.139 + */ 1.140 + virtual void 1.141 + GetPermissionAccessType(nsCString& aAccess) const = 0; 1.142 + 1.143 + NS_DECL_NSIRUNNABLE 1.144 +protected: 1.145 + /* 1.146 + * To create a task to handle the page content request. 1.147 + */ 1.148 + FileSystemTaskBase(FileSystemBase* aFileSystem); 1.149 + 1.150 + /* 1.151 + * To create a parent process task delivered from the child process through 1.152 + * IPC. 1.153 + */ 1.154 + FileSystemTaskBase(FileSystemBase* aFileSystem, 1.155 + const FileSystemParams& aParam, 1.156 + FileSystemRequestParent* aParent); 1.157 + 1.158 + virtual 1.159 + ~FileSystemTaskBase(); 1.160 + 1.161 + /* 1.162 + * The function to perform task operation. It will be run on the worker 1.163 + * thread of the parent process. 1.164 + * Overrides this function to define the task operation for individual task. 1.165 + */ 1.166 + virtual nsresult 1.167 + Work() = 0; 1.168 + 1.169 + /* 1.170 + * After the task is completed, this function will be called to pass the task 1.171 + * result to the content page. 1.172 + * Override this function to handle the call back to the content page. 1.173 + */ 1.174 + virtual void 1.175 + HandlerCallback() = 0; 1.176 + 1.177 + /* 1.178 + * Wrap the task parameter to FileSystemParams for sending it through IPC. 1.179 + * It will be called when we need to forward a task from the child process to 1.180 + * the prarent process. 1.181 + * @param filesystem The string representation of the file system. 1.182 + */ 1.183 + virtual FileSystemParams 1.184 + GetRequestParams(const nsString& aFileSystem) const = 0; 1.185 + 1.186 + /* 1.187 + * Wrap the task success result to FileSystemResponseValue for sending it 1.188 + * through IPC. 1.189 + * It will be called when the task is completed successfully and we need to 1.190 + * send the task success result back to the child process. 1.191 + */ 1.192 + virtual FileSystemResponseValue 1.193 + GetSuccessRequestResult() const = 0; 1.194 + 1.195 + /* 1.196 + * Unwrap the IPC message to get the task success result. 1.197 + * It will be called when the task is completed successfully and an IPC 1.198 + * message is received in the child process and we want to get the task 1.199 + * success result. 1.200 + */ 1.201 + virtual void 1.202 + SetSuccessRequestResult(const FileSystemResponseValue& aValue) = 0; 1.203 + 1.204 + bool 1.205 + HasError() const { return mErrorValue != NS_OK; } 1.206 + 1.207 + // Overrides PFileSystemRequestChild 1.208 + virtual bool 1.209 + Recv__delete__(const FileSystemResponseValue& value) MOZ_OVERRIDE; 1.210 + 1.211 + BlobParent* 1.212 + GetBlobParent(nsIDOMFile* aFile) const; 1.213 + 1.214 + nsresult mErrorValue; 1.215 + 1.216 + nsRefPtr<FileSystemBase> mFileSystem; 1.217 + nsRefPtr<FileSystemRequestParent> mRequestParent; 1.218 +private: 1.219 + /* 1.220 + * After finishing the task operation, handle the task result. 1.221 + * If it is an IPC task, send back the IPC result. Or else, send the result 1.222 + * to the content page. 1.223 + */ 1.224 + void 1.225 + HandleResult(); 1.226 + 1.227 + /* 1.228 + * Wrap the task result to FileSystemResponseValue for sending it through IPC. 1.229 + * It will be called when the task is completed and we need to 1.230 + * send the task result back to the child process. 1.231 + */ 1.232 + FileSystemResponseValue 1.233 + GetRequestResult() const; 1.234 + 1.235 + /* 1.236 + * Unwrap the IPC message to get the task result. 1.237 + * It will be called when the task is completed and an IPC message is received 1.238 + * in the child process and we want to get the task result. 1.239 + */ 1.240 + void 1.241 + SetRequestResult(const FileSystemResponseValue& aValue); 1.242 +}; 1.243 + 1.244 +} // namespace dom 1.245 +} // namespace mozilla 1.246 + 1.247 +#endif // mozilla_dom_FileSystemTaskBase_h