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_IMPL_H_
6#define STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_IMPL_H_
7
8#include <vector>
9
10#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/weak_ptr.h"
13#include "storage/browser/fileapi/file_system_operation.h"
14#include "storage/browser/fileapi/file_system_operation_context.h"
15#include "storage/browser/fileapi/file_system_url.h"
16#include "storage/browser/fileapi/file_writer_delegate.h"
17#include "storage/browser/storage_browser_export.h"
18#include "storage/common/blob/scoped_file.h"
19#include "storage/common/quota/quota_types.h"
20
21namespace storage {
22
23class AsyncFileUtil;
24class FileSystemContext;
25class RecursiveOperationDelegate;
26
27// The default implementation of FileSystemOperation for file systems.
28class STORAGE_EXPORT FileSystemOperationImpl
29    : public NON_EXPORTED_BASE(FileSystemOperation) {
30 public:
31  virtual ~FileSystemOperationImpl();
32
33  // FileSystemOperation overrides.
34  virtual void CreateFile(const FileSystemURL& url,
35                          bool exclusive,
36                          const StatusCallback& callback) OVERRIDE;
37  virtual void CreateDirectory(const FileSystemURL& url,
38                               bool exclusive,
39                               bool recursive,
40                               const StatusCallback& callback) OVERRIDE;
41  virtual void Copy(const FileSystemURL& src_url,
42                    const FileSystemURL& dest_url,
43                    CopyOrMoveOption option,
44                    const CopyProgressCallback& progress_callback,
45                    const StatusCallback& callback) OVERRIDE;
46  virtual void Move(const FileSystemURL& src_url,
47                    const FileSystemURL& dest_url,
48                    CopyOrMoveOption option,
49                    const StatusCallback& callback) OVERRIDE;
50  virtual void DirectoryExists(const FileSystemURL& url,
51                               const StatusCallback& callback) OVERRIDE;
52  virtual void FileExists(const FileSystemURL& url,
53                          const StatusCallback& callback) OVERRIDE;
54  virtual void GetMetadata(const FileSystemURL& url,
55                           const GetMetadataCallback& callback) OVERRIDE;
56  virtual void ReadDirectory(const FileSystemURL& url,
57                             const ReadDirectoryCallback& callback) OVERRIDE;
58  virtual void Remove(const FileSystemURL& url, bool recursive,
59                      const StatusCallback& callback) OVERRIDE;
60  virtual void Write(const FileSystemURL& url,
61                     scoped_ptr<FileWriterDelegate> writer_delegate,
62                     scoped_ptr<net::URLRequest> blob_request,
63                     const WriteCallback& callback) OVERRIDE;
64  virtual void Truncate(const FileSystemURL& url, int64 length,
65                        const StatusCallback& callback) OVERRIDE;
66  virtual void TouchFile(const FileSystemURL& url,
67                         const base::Time& last_access_time,
68                         const base::Time& last_modified_time,
69                         const StatusCallback& callback) OVERRIDE;
70  virtual void OpenFile(const FileSystemURL& url,
71                        int file_flags,
72                        const OpenFileCallback& callback) OVERRIDE;
73  virtual void Cancel(const StatusCallback& cancel_callback) OVERRIDE;
74  virtual void CreateSnapshotFile(
75      const FileSystemURL& path,
76      const SnapshotFileCallback& callback) OVERRIDE;
77  virtual void CopyInForeignFile(const base::FilePath& src_local_disk_path,
78                                 const FileSystemURL& dest_url,
79                                 const StatusCallback& callback) OVERRIDE;
80  virtual void RemoveFile(const FileSystemURL& url,
81                          const StatusCallback& callback) OVERRIDE;
82  virtual void RemoveDirectory(const FileSystemURL& url,
83                               const StatusCallback& callback) OVERRIDE;
84  virtual void CopyFileLocal(const FileSystemURL& src_url,
85                             const FileSystemURL& dest_url,
86                             CopyOrMoveOption option,
87                             const CopyFileProgressCallback& progress_callback,
88                             const StatusCallback& callback) OVERRIDE;
89  virtual void MoveFileLocal(const FileSystemURL& src_url,
90                             const FileSystemURL& dest_url,
91                             CopyOrMoveOption option,
92                             const StatusCallback& callback) OVERRIDE;
93  virtual base::File::Error SyncGetPlatformPath(
94      const FileSystemURL& url,
95      base::FilePath* platform_path) OVERRIDE;
96
97  FileSystemContext* file_system_context() const {
98    return file_system_context_.get();
99  }
100
101 private:
102  friend class FileSystemOperation;
103
104  FileSystemOperationImpl(
105      const FileSystemURL& url,
106      FileSystemContext* file_system_context,
107      scoped_ptr<FileSystemOperationContext> operation_context);
108
109  // Queries the quota and usage and then runs the given |task|.
110  // If an error occurs during the quota query it runs |error_callback| instead.
111  void GetUsageAndQuotaThenRunTask(
112      const FileSystemURL& url,
113      const base::Closure& task,
114      const base::Closure& error_callback);
115
116  // Called after the quota info is obtained from the quota manager
117  // (which is triggered by GetUsageAndQuotaThenRunTask).
118  // Sets the quota info in the operation_context_ and then runs the given
119  // |task| if the returned quota status is successful, otherwise runs
120  // |error_callback|.
121  void DidGetUsageAndQuotaAndRunTask(const base::Closure& task,
122                                     const base::Closure& error_callback,
123                                     storage::QuotaStatusCode status,
124                                     int64 usage,
125                                     int64 quota);
126
127  // The 'body' methods that perform the actual work (i.e. posting the
128  // file task on proxy_) after the quota check.
129  void DoCreateFile(const FileSystemURL& url,
130                    const StatusCallback& callback, bool exclusive);
131  void DoCreateDirectory(const FileSystemURL& url,
132                         const StatusCallback& callback,
133                         bool exclusive,
134                         bool recursive);
135  void DoCopyFileLocal(const FileSystemURL& src,
136                       const FileSystemURL& dest,
137                       CopyOrMoveOption option,
138                       const CopyFileProgressCallback& progress_callback,
139                       const StatusCallback& callback);
140  void DoMoveFileLocal(const FileSystemURL& src,
141                       const FileSystemURL& dest,
142                       CopyOrMoveOption option,
143                       const StatusCallback& callback);
144  void DoCopyInForeignFile(const base::FilePath& src_local_disk_file_path,
145                           const FileSystemURL& dest,
146                           const StatusCallback& callback);
147  void DoTruncate(const FileSystemURL& url,
148                  const StatusCallback& callback, int64 length);
149  void DoOpenFile(const FileSystemURL& url,
150                  const OpenFileCallback& callback, int file_flags);
151
152  // Callback for CreateFile for |exclusive|=true cases.
153  void DidEnsureFileExistsExclusive(const StatusCallback& callback,
154                                    base::File::Error rv,
155                                    bool created);
156
157  // Callback for CreateFile for |exclusive|=false cases.
158  void DidEnsureFileExistsNonExclusive(const StatusCallback& callback,
159                                       base::File::Error rv,
160                                       bool created);
161
162  void DidFinishOperation(const StatusCallback& callback,
163                          base::File::Error rv);
164  void DidDirectoryExists(const StatusCallback& callback,
165                          base::File::Error rv,
166                          const base::File::Info& file_info);
167  void DidFileExists(const StatusCallback& callback,
168                     base::File::Error rv,
169                     const base::File::Info& file_info);
170  void DidDeleteRecursively(const FileSystemURL& url,
171                            const StatusCallback& callback,
172                            base::File::Error rv);
173  void DidWrite(const FileSystemURL& url,
174                const WriteCallback& callback,
175                base::File::Error rv,
176                int64 bytes,
177                FileWriterDelegate::WriteProgressStatus write_status);
178  void DidOpenFile(const OpenFileCallback& callback,
179                   base::File file,
180                   const base::Closure& on_close_callback);
181
182  // Used only for internal assertions.
183  // Returns false if there's another inflight pending operation.
184  bool SetPendingOperationType(OperationType type);
185
186  scoped_refptr<FileSystemContext> file_system_context_;
187
188  scoped_ptr<FileSystemOperationContext> operation_context_;
189  AsyncFileUtil* async_file_util_;  // Not owned.
190
191  scoped_ptr<FileWriterDelegate> file_writer_delegate_;
192  scoped_ptr<RecursiveOperationDelegate> recursive_operation_delegate_;
193
194  StatusCallback cancel_callback_;
195
196  // A flag to make sure we call operation only once per instance.
197  OperationType pending_operation_;
198
199  base::WeakPtrFactory<FileSystemOperationImpl> weak_factory_;
200
201  DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImpl);
202};
203
204}  // namespace storage
205
206#endif  // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_IMPL_H_
207