diff -r 000000000000 -r 6474c204b198 dom/filesystem/FileSystemTaskBase.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dom/filesystem/FileSystemTaskBase.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,244 @@ +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_FileSystemTaskBase_h +#define mozilla_dom_FileSystemTaskBase_h + +#include "mozilla/ErrorResult.h" +#include "mozilla/dom/FileSystemRequestParent.h" +#include "mozilla/dom/PFileSystemRequestChild.h" +#include "mozilla/dom/ipc/Blob.h" + +class nsIDOMFile; + +namespace mozilla { +namespace dom { + +class FileSystemBase; +class FileSystemParams; +class Promise; + +/* + * The base class to implement a Task class. + * The task is used to handle the OOP (out of process) operations. + * The file system operations can only be performed in the parent process. When + * performing such a parent-process-only operation, a task will delivered the + * operation to the parent process if needed. + * + * The following diagram illustrates the how a API call from the content page + * starts a task and gets call back results. + * + * The left block is the call sequence inside the child process, while the + * right block is the call sequence inside the parent process. + * + * There are two types of API call. One is from the content page of the child + * process and we mark the steps as (1) to (8). The other is from the content + * page of the parent process and we mark the steps as (1') to (4'). + * + * Page Page + * | | + * | (1) | (1') + * ______|________________ | _____________________|_____________ + * | | | | | | | + * | | Task in | | | Task in | | + * | | Child Process | | | Parent Process | | + * | V | IPC | V | + * [new FileSystemTaskBase()] | | [new FileSystemTaskBase()] | + * | | | | | | | + * | | (2) | | | (2') | + * | V | (3) | | | + * | [GetRequestParams]------------->[new FileSystemTaskBase(...)] | + * | | | | | | + * | | | | | (4) | | + * | | | | | V | + * | | | | -----------> [Work] | + * | | IPC | | | + * | | | | (5) | (3') | + * | | | | V | + * | | | | --------[HandleResult] | + * | | | | | | | + * | | | | (6) | | + * | | (7) | V | | + * | [SetRequestResult]<-------------[GetRequestResult] | | + * | | | | | (4') | + * | | (8) | | | | | + * | V | | | V | + * |[HandlerCallback] | IPC | [HandlerCallback] | + * |_______|_______________| | |_________________________|_________| + * | | | + * V V + * Page Page + * + * 1. From child process page + * Child: + * (1) Call FileSystem API from content page with JS. Create a task and run. + * The base constructor [FileSystemTaskBase()] of the task should be called. + * (2) Forward the task to the parent process through the IPC and call + * [GetRequestParams] to prepare the parameters of the IPC. + * Parent: + * (3) The parent process receives IPC and handle it in + * FileystemRequestParent. + * Get the IPC parameters and create a task to run the IPC task. The base + * constructor [FileSystemTaskBase(aParam, aParent)] of the task should be + * called to set the task as an IPC task. + * (4) The task operation will be performed in the member function of [Work]. + * A worker thread will be created to run that function. If error occurs + * during the operation, call [SetError] to record the error and then abort. + * (5) After finishing the task operation, call [HandleResult] to send the + * result back to the child process though the IPC. + * (6) Call [GetRequestResult] request result to prepare the parameters of the + * IPC. Because the formats of the error result for different task are the + * same, FileSystemTaskBase can handle the error message without interfering. + * Each task only needs to implement its specific success result preparation + * function -[GetSuccessRequestResult]. + * Child: + * (7) The child process receives IPC and calls [SetRequestResult] to get the + * task result. Each task needs to implement its specific success result + * parsing function [SetSuccessRequestResult] to get the success result. + * (8) Call [HandlerCallback] to send the task result to the content page. + * 2. From parent process page + * We don't need to send the task parameters and result to other process. So + * there are less steps, but their functions are the same. The correspondence + * between the two types of steps is: + * (1') = (1), + * (2') = (4), + * (3') = (5), + * (4') = (8). + */ +class FileSystemTaskBase + : public nsRunnable + , public PFileSystemRequestChild +{ +public: + /* + * Start the task. If the task is running the child process, it will be + * forwarded to parent process by IPC, or else, creates a worker thread to + * do the task work. + */ + void + Start(); + + /* + * The error codes are defined in xpcom/base/ErrorList.h and their + * corresponding error name and message are defined in dom/base/domerr.msg. + */ + void + SetError(const nsresult& aErrorCode); + + FileSystemBase* + GetFileSystem() const; + + /* + * Get the type of permission access required to perform this task. + */ + virtual void + GetPermissionAccessType(nsCString& aAccess) const = 0; + + NS_DECL_NSIRUNNABLE +protected: + /* + * To create a task to handle the page content request. + */ + FileSystemTaskBase(FileSystemBase* aFileSystem); + + /* + * To create a parent process task delivered from the child process through + * IPC. + */ + FileSystemTaskBase(FileSystemBase* aFileSystem, + const FileSystemParams& aParam, + FileSystemRequestParent* aParent); + + virtual + ~FileSystemTaskBase(); + + /* + * The function to perform task operation. It will be run on the worker + * thread of the parent process. + * Overrides this function to define the task operation for individual task. + */ + virtual nsresult + Work() = 0; + + /* + * After the task is completed, this function will be called to pass the task + * result to the content page. + * Override this function to handle the call back to the content page. + */ + virtual void + HandlerCallback() = 0; + + /* + * Wrap the task parameter to FileSystemParams for sending it through IPC. + * It will be called when we need to forward a task from the child process to + * the prarent process. + * @param filesystem The string representation of the file system. + */ + virtual FileSystemParams + GetRequestParams(const nsString& aFileSystem) const = 0; + + /* + * Wrap the task success result to FileSystemResponseValue for sending it + * through IPC. + * It will be called when the task is completed successfully and we need to + * send the task success result back to the child process. + */ + virtual FileSystemResponseValue + GetSuccessRequestResult() const = 0; + + /* + * Unwrap the IPC message to get the task success result. + * It will be called when the task is completed successfully and an IPC + * message is received in the child process and we want to get the task + * success result. + */ + virtual void + SetSuccessRequestResult(const FileSystemResponseValue& aValue) = 0; + + bool + HasError() const { return mErrorValue != NS_OK; } + + // Overrides PFileSystemRequestChild + virtual bool + Recv__delete__(const FileSystemResponseValue& value) MOZ_OVERRIDE; + + BlobParent* + GetBlobParent(nsIDOMFile* aFile) const; + + nsresult mErrorValue; + + nsRefPtr mFileSystem; + nsRefPtr mRequestParent; +private: + /* + * After finishing the task operation, handle the task result. + * If it is an IPC task, send back the IPC result. Or else, send the result + * to the content page. + */ + void + HandleResult(); + + /* + * Wrap the task result to FileSystemResponseValue for sending it through IPC. + * It will be called when the task is completed and we need to + * send the task result back to the child process. + */ + FileSystemResponseValue + GetRequestResult() const; + + /* + * Unwrap the IPC message to get the task result. + * It will be called when the task is completed and an IPC message is received + * in the child process and we want to get the task result. + */ + void + SetRequestResult(const FileSystemResponseValue& aValue); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_FileSystemTaskBase_h