Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / storage / browser / fileapi / file_system_operation_runner.h
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_
6 #define STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_
7
8 #include <map>
9 #include <set>
10 #include <vector>
11
12 #include "base/basictypes.h"
13 #include "base/id_map.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "storage/browser/blob/blob_data_handle.h"
17 #include "storage/browser/fileapi/file_system_operation.h"
18 #include "storage/browser/fileapi/file_system_url.h"
19 #include "storage/browser/storage_browser_export.h"
20
21 namespace net {
22 class URLRequestContext;
23 }
24
25 namespace storage {
26
27 class FileSystemURL;
28 class FileSystemContext;
29
30 // A central interface for running FileSystem API operations.
31 // All operation methods take callback and returns OperationID, which is
32 // an integer value which can be used for cancelling an operation.
33 // All operation methods return kErrorOperationID if running (posting) an
34 // operation fails, in addition to dispatching the callback with an error
35 // code (therefore in most cases the caller does not need to check the
36 // returned operation ID).
37 class STORAGE_EXPORT FileSystemOperationRunner
38     : public base::SupportsWeakPtr<FileSystemOperationRunner> {
39  public:
40   typedef FileSystemOperation::GetMetadataCallback GetMetadataCallback;
41   typedef FileSystemOperation::ReadDirectoryCallback ReadDirectoryCallback;
42   typedef FileSystemOperation::SnapshotFileCallback SnapshotFileCallback;
43   typedef FileSystemOperation::StatusCallback StatusCallback;
44   typedef FileSystemOperation::WriteCallback WriteCallback;
45   typedef FileSystemOperation::OpenFileCallback OpenFileCallback;
46   typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback;
47   typedef FileSystemOperation::CopyFileProgressCallback
48       CopyFileProgressCallback;
49   typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption;
50
51   typedef int OperationID;
52
53   virtual ~FileSystemOperationRunner();
54
55   // Cancels all inflight operations.
56   void Shutdown();
57
58   // Creates a file at |url|. If |exclusive| is true, an error is raised
59   // in case a file is already present at the URL.
60   OperationID CreateFile(const FileSystemURL& url,
61                          bool exclusive,
62                          const StatusCallback& callback);
63
64   OperationID CreateDirectory(const FileSystemURL& url,
65                               bool exclusive,
66                               bool recursive,
67                               const StatusCallback& callback);
68
69   // Copies a file or directory from |src_url| to |dest_url|. If
70   // |src_url| is a directory, the contents of |src_url| are copied to
71   // |dest_url| recursively. A new file or directory is created at
72   // |dest_url| as needed.
73   // For |option| and |progress_callback|, see file_system_operation.h for
74   // details.
75   OperationID Copy(const FileSystemURL& src_url,
76                    const FileSystemURL& dest_url,
77                    CopyOrMoveOption option,
78                    const CopyProgressCallback& progress_callback,
79                    const StatusCallback& callback);
80
81   // Moves a file or directory from |src_url| to |dest_url|. A new file
82   // or directory is created at |dest_url| as needed.
83   // For |option|, see file_system_operation.h for details.
84   OperationID Move(const FileSystemURL& src_url,
85                    const FileSystemURL& dest_url,
86                    CopyOrMoveOption option,
87                    const StatusCallback& callback);
88
89   // Checks if a directory is present at |url|.
90   OperationID DirectoryExists(const FileSystemURL& url,
91                               const StatusCallback& callback);
92
93   // Checks if a file is present at |url|.
94   OperationID FileExists(const FileSystemURL& url,
95                          const StatusCallback& callback);
96
97   // Gets the metadata of a file or directory at |url|.
98   OperationID GetMetadata(const FileSystemURL& url,
99                           const GetMetadataCallback& callback);
100
101   // Reads contents of a directory at |url|.
102   OperationID ReadDirectory(const FileSystemURL& url,
103                             const ReadDirectoryCallback& callback);
104
105   // Removes a file or directory at |url|. If |recursive| is true, remove
106   // all files and directories under the directory at |url| recursively.
107   OperationID Remove(const FileSystemURL& url, bool recursive,
108                      const StatusCallback& callback);
109
110   // Writes contents of |blob_url| to |url| at |offset|.
111   // |url_request_context| is used to read contents in |blob|.
112   OperationID Write(const net::URLRequestContext* url_request_context,
113                     const FileSystemURL& url,
114                     scoped_ptr<storage::BlobDataHandle> blob,
115                     int64 offset,
116                     const WriteCallback& callback);
117
118   // Truncates a file at |url| to |length|. If |length| is larger than
119   // the original file size, the file will be extended, and the extended
120   // part is filled with null bytes.
121   OperationID Truncate(const FileSystemURL& url, int64 length,
122                        const StatusCallback& callback);
123
124   // Tries to cancel the operation |id| [we support cancelling write or
125   // truncate only]. Reports failure for the current operation, then reports
126   // success for the cancel operation itself via the |callback|.
127   void Cancel(OperationID id, const StatusCallback& callback);
128
129   // Modifies timestamps of a file or directory at |url| with
130   // |last_access_time| and |last_modified_time|. The function DOES NOT
131   // create a file unlike 'touch' command on Linux.
132   //
133   // This function is used only by Pepper as of writing.
134   OperationID TouchFile(const FileSystemURL& url,
135                         const base::Time& last_access_time,
136                         const base::Time& last_modified_time,
137                         const StatusCallback& callback);
138
139   // Opens a file at |url| with |file_flags|, where flags are OR'ed
140   // values of base::PlatformFileFlags.
141   //
142   // |peer_handle| is the process handle of a pepper plugin process, which
143   // is necessary for underlying IPC calls with Pepper plugins.
144   //
145   // This function is used only by Pepper as of writing.
146   OperationID OpenFile(const FileSystemURL& url,
147                        int file_flags,
148                        const OpenFileCallback& callback);
149
150   // Creates a local snapshot file for a given |url| and returns the
151   // metadata and platform url of the snapshot file via |callback|.
152   // In local filesystem cases the implementation may simply return
153   // the metadata of the file itself (as well as GetMetadata does),
154   // while in remote filesystem case the backend may want to download the file
155   // into a temporary snapshot file and return the metadata of the
156   // temporary file.  Or if the implementaiton already has the local cache
157   // data for |url| it can simply return the url to the cache.
158   OperationID CreateSnapshotFile(const FileSystemURL& url,
159                                  const SnapshotFileCallback& callback);
160
161   // Copies in a single file from a different filesystem.
162   //
163   // This returns:
164   // - File::FILE_ERROR_NOT_FOUND if |src_file_path|
165   //   or the parent directory of |dest_url| does not exist.
166   // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
167   //   is not a file.
168   // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
169   //   its parent path is a file.
170   //
171   OperationID CopyInForeignFile(const base::FilePath& src_local_disk_path,
172                                 const FileSystemURL& dest_url,
173                                 const StatusCallback& callback);
174
175   // Removes a single file.
176   //
177   // This returns:
178   // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
179   // - File::FILE_ERROR_NOT_A_FILE if |url| is not a file.
180   //
181   OperationID RemoveFile(const FileSystemURL& url,
182                          const StatusCallback& callback);
183
184   // Removes a single empty directory.
185   //
186   // This returns:
187   // - File::FILE_ERROR_NOT_FOUND if |url| does not exist.
188   // - File::FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory.
189   // - File::FILE_ERROR_NOT_EMPTY if |url| is not empty.
190   //
191   OperationID RemoveDirectory(const FileSystemURL& url,
192                               const StatusCallback& callback);
193
194   // Copies a file from |src_url| to |dest_url|.
195   // This must be called for files that belong to the same filesystem
196   // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
197   // For |option| and |progress_callback|, see file_system_operation.h for
198   // details.
199   //
200   // This returns:
201   // - File::FILE_ERROR_NOT_FOUND if |src_url|
202   //   or the parent directory of |dest_url| does not exist.
203   // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
204   // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
205   //   is not a file.
206   // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
207   //   its parent path is a file.
208   //
209   OperationID CopyFileLocal(const FileSystemURL& src_url,
210                             const FileSystemURL& dest_url,
211                             CopyOrMoveOption option,
212                             const CopyFileProgressCallback& progress_callback,
213                             const StatusCallback& callback);
214
215   // Moves a local file from |src_url| to |dest_url|.
216   // This must be called for files that belong to the same filesystem
217   // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
218   // For |option|, see file_system_operation.h for details.
219   //
220   // This returns:
221   // - File::FILE_ERROR_NOT_FOUND if |src_url|
222   //   or the parent directory of |dest_url| does not exist.
223   // - File::FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
224   // - File::FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
225   //   is not a file.
226   // - File::FILE_ERROR_FAILED if |dest_url| does not exist and
227   //   its parent path is a file.
228   //
229   OperationID MoveFileLocal(const FileSystemURL& src_url,
230                             const FileSystemURL& dest_url,
231                             CopyOrMoveOption option,
232                             const StatusCallback& callback);
233
234   // This is called only by pepper plugin as of writing to synchronously get
235   // the underlying platform path to upload a file in the sandboxed filesystem
236   // (e.g. TEMPORARY or PERSISTENT).
237   base::File::Error SyncGetPlatformPath(const FileSystemURL& url,
238                                         base::FilePath* platform_path);
239
240  private:
241   class BeginOperationScoper;
242
243   struct OperationHandle {
244     OperationID id;
245     base::WeakPtr<BeginOperationScoper> scope;
246
247     OperationHandle();
248     ~OperationHandle();
249   };
250
251   friend class FileSystemContext;
252   explicit FileSystemOperationRunner(FileSystemContext* file_system_context);
253
254   void DidFinish(const OperationHandle& handle,
255                  const StatusCallback& callback,
256                  base::File::Error rv);
257   void DidGetMetadata(const OperationHandle& handle,
258                       const GetMetadataCallback& callback,
259                       base::File::Error rv,
260                       const base::File::Info& file_info);
261   void DidReadDirectory(const OperationHandle& handle,
262                         const ReadDirectoryCallback& callback,
263                         base::File::Error rv,
264                         const std::vector<DirectoryEntry>& entries,
265                         bool has_more);
266   void DidWrite(const OperationHandle& handle,
267                 const WriteCallback& callback,
268                 base::File::Error rv,
269                 int64 bytes,
270                 bool complete);
271   void DidOpenFile(
272       const OperationHandle& handle,
273       const OpenFileCallback& callback,
274       base::File file,
275       const base::Closure& on_close_callback);
276   void DidCreateSnapshot(
277       const OperationHandle& handle,
278       const SnapshotFileCallback& callback,
279       base::File::Error rv,
280       const base::File::Info& file_info,
281       const base::FilePath& platform_path,
282       const scoped_refptr<storage::ShareableFileReference>& file_ref);
283
284   void OnCopyProgress(
285       const OperationHandle& handle,
286       const CopyProgressCallback& callback,
287       FileSystemOperation::CopyProgressType type,
288       const FileSystemURL& source_url,
289       const FileSystemURL& dest_url,
290       int64 size);
291
292   void PrepareForWrite(OperationID id, const FileSystemURL& url);
293   void PrepareForRead(OperationID id, const FileSystemURL& url);
294
295   // These must be called at the beginning and end of any async operations.
296   OperationHandle BeginOperation(FileSystemOperation* operation,
297                                  base::WeakPtr<BeginOperationScoper> scope);
298   void FinishOperation(OperationID id);
299
300   // Not owned; file_system_context owns this.
301   FileSystemContext* file_system_context_;
302
303   // IDMap<FileSystemOperation, IDMapOwnPointer> operations_;
304   IDMap<FileSystemOperation, IDMapOwnPointer> operations_;
305
306   // We keep track of the file to be modified by each operation so that
307   // we can notify observers when we're done.
308   typedef std::map<OperationID, FileSystemURLSet> OperationToURLSet;
309   OperationToURLSet write_target_urls_;
310
311   // Operations that are finished but not yet fire their callbacks.
312   std::set<OperationID> finished_operations_;
313
314   // Callbacks for stray cancels whose target operation is already finished.
315   std::map<OperationID, StatusCallback> stray_cancel_callbacks_;
316
317   DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunner);
318 };
319
320 }  // namespace storage
321
322 #endif  // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_RUNNER_H_