Home | History | Annotate | Download | only in fileapi
      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 WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_IMPL_H_
      6 #define WEBKIT_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 "webkit/browser/fileapi/file_system_operation.h"
     14 #include "webkit/browser/fileapi/file_system_operation_context.h"
     15 #include "webkit/browser/fileapi/file_system_url.h"
     16 #include "webkit/browser/fileapi/file_writer_delegate.h"
     17 #include "webkit/browser/webkit_storage_browser_export.h"
     18 #include "webkit/common/blob/scoped_file.h"
     19 #include "webkit/common/quota/quota_types.h"
     20 
     21 namespace fileapi {
     22 
     23 class AsyncFileUtil;
     24 class FileSystemContext;
     25 class RecursiveOperationDelegate;
     26 
     27 // The default implementation of FileSystemOperation for file systems.
     28 class WEBKIT_STORAGE_BROWSER_EXPORT FileSystemOperationImpl
     29     : public NON_EXPORTED_BASE(FileSystemOperation),
     30       public base::SupportsWeakPtr<FileSystemOperationImpl> {
     31  public:
     32   // NOTE: This constructor should not be called outside FileSystemBackends;
     33   // instead please consider using
     34   // file_system_context->CreateFileSystemOperation() to instantiate
     35   // an appropriate FileSystemOperation.
     36   FileSystemOperationImpl(
     37       const FileSystemURL& url,
     38       FileSystemContext* file_system_context,
     39       scoped_ptr<FileSystemOperationContext> operation_context);
     40 
     41   virtual ~FileSystemOperationImpl();
     42 
     43   // FileSystemOperation overrides.
     44   virtual void CreateFile(const FileSystemURL& url,
     45                           bool exclusive,
     46                           const StatusCallback& callback) OVERRIDE;
     47   virtual void CreateDirectory(const FileSystemURL& url,
     48                                bool exclusive,
     49                                bool recursive,
     50                                const StatusCallback& callback) OVERRIDE;
     51   virtual void Copy(const FileSystemURL& src_url,
     52                     const FileSystemURL& dest_url,
     53                     const StatusCallback& callback) OVERRIDE;
     54   virtual void Move(const FileSystemURL& src_url,
     55                     const FileSystemURL& dest_url,
     56                     const StatusCallback& callback) OVERRIDE;
     57   virtual void DirectoryExists(const FileSystemURL& url,
     58                                const StatusCallback& callback) OVERRIDE;
     59   virtual void FileExists(const FileSystemURL& url,
     60                           const StatusCallback& callback) OVERRIDE;
     61   virtual void GetMetadata(const FileSystemURL& url,
     62                            const GetMetadataCallback& callback) OVERRIDE;
     63   virtual void ReadDirectory(const FileSystemURL& url,
     64                              const ReadDirectoryCallback& callback) OVERRIDE;
     65   virtual void Remove(const FileSystemURL& url, bool recursive,
     66                       const StatusCallback& callback) OVERRIDE;
     67   virtual void Write(const FileSystemURL& url,
     68                      scoped_ptr<FileWriterDelegate> writer_delegate,
     69                      scoped_ptr<net::URLRequest> blob_request,
     70                      const WriteCallback& callback) OVERRIDE;
     71   virtual void Truncate(const FileSystemURL& url, int64 length,
     72                         const StatusCallback& callback) OVERRIDE;
     73   virtual void TouchFile(const FileSystemURL& url,
     74                          const base::Time& last_access_time,
     75                          const base::Time& last_modified_time,
     76                          const StatusCallback& callback) OVERRIDE;
     77   virtual void OpenFile(const FileSystemURL& url,
     78                         int file_flags,
     79                         base::ProcessHandle peer_handle,
     80                         const OpenFileCallback& callback) OVERRIDE;
     81   virtual void Cancel(const StatusCallback& cancel_callback) OVERRIDE;
     82   virtual FileSystemOperationImpl* AsFileSystemOperationImpl() OVERRIDE;
     83   virtual void CreateSnapshotFile(
     84       const FileSystemURL& path,
     85       const SnapshotFileCallback& callback) OVERRIDE;
     86 
     87   // Copies in a single file from a different filesystem.
     88   //
     89   // This returns:
     90   // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_file_path|
     91   //   or the parent directory of |dest_url| does not exist.
     92   // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
     93   //   is not a file.
     94   // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and
     95   //   its parent path is a file.
     96   //
     97   virtual void CopyInForeignFile(const base::FilePath& src_local_disk_path,
     98                                  const FileSystemURL& dest_url,
     99                                  const StatusCallback& callback);
    100 
    101   // Removes a single file.
    102   //
    103   // This returns:
    104   // - PLATFORM_FILE_ERROR_NOT_FOUND if |url| does not exist.
    105   // - PLATFORM_FILE_ERROR_NOT_A_FILE if |url| is not a file.
    106   //
    107   void RemoveFile(const FileSystemURL& url,
    108                   const StatusCallback& callback);
    109 
    110   // Removes a single empty directory.
    111   //
    112   // This returns:
    113   // - PLATFORM_FILE_ERROR_NOT_FOUND if |url| does not exist.
    114   // - PLATFORM_FILE_ERROR_NOT_A_DIRECTORY if |url| is not a directory.
    115   // - PLATFORM_FILE_ERROR_NOT_EMPTY if |url| is not empty.
    116   //
    117   void RemoveDirectory(const FileSystemURL& url,
    118                        const StatusCallback& callback);
    119 
    120   // Copies a file from |src_url| to |dest_url|.
    121   // This must be called for files that belong to the same filesystem
    122   // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
    123   //
    124   // This returns:
    125   // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_url|
    126   //   or the parent directory of |dest_url| does not exist.
    127   // - PLATFORM_FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
    128   // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
    129   //   is not a file.
    130   // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and
    131   //   its parent path is a file.
    132   //
    133   void CopyFileLocal(const FileSystemURL& src_url,
    134                      const FileSystemURL& dest_url,
    135                      const StatusCallback& callback);
    136 
    137   // Moves a local file from |src_url| to |dest_url|.
    138   // This must be called for files that belong to the same filesystem
    139   // (i.e. type() and origin() of the |src_url| and |dest_url| must match).
    140   //
    141   // This returns:
    142   // - PLATFORM_FILE_ERROR_NOT_FOUND if |src_url|
    143   //   or the parent directory of |dest_url| does not exist.
    144   // - PLATFORM_FILE_ERROR_NOT_A_FILE if |src_url| exists but is not a file.
    145   // - PLATFORM_FILE_ERROR_INVALID_OPERATION if |dest_url| exists and
    146   //   is not a file.
    147   // - PLATFORM_FILE_ERROR_FAILED if |dest_url| does not exist and
    148   //   its parent path is a file.
    149   //
    150   void MoveFileLocal(const FileSystemURL& src_url,
    151                      const FileSystemURL& dest_url,
    152                      const StatusCallback& callback);
    153 
    154   // Synchronously gets the platform path for the given |url|.
    155   // This may fail if |file_system_context| returns NULL on GetFileUtil().
    156   // In such a case, base::PLATFORM_FILE_ERROR_INVALID_OPERATION will be
    157   // returned.
    158   base::PlatformFileError SyncGetPlatformPath(const FileSystemURL& url,
    159                                               base::FilePath* platform_path);
    160 
    161   FileSystemContext* file_system_context() const {
    162     return file_system_context_.get();
    163   }
    164 
    165  protected:
    166   // Queries the quota and usage and then runs the given |task|.
    167   // If an error occurs during the quota query it runs |error_callback| instead.
    168   void GetUsageAndQuotaThenRunTask(
    169       const FileSystemURL& url,
    170       const base::Closure& task,
    171       const base::Closure& error_callback);
    172 
    173   // Called after the quota info is obtained from the quota manager
    174   // (which is triggered by GetUsageAndQuotaThenRunTask).
    175   // Sets the quota info in the operation_context_ and then runs the given
    176   // |task| if the returned quota status is successful, otherwise runs
    177   // |error_callback|.
    178   void DidGetUsageAndQuotaAndRunTask(
    179       const base::Closure& task,
    180       const base::Closure& error_callback,
    181       quota::QuotaStatusCode status,
    182       int64 usage, int64 quota);
    183 
    184   // The 'body' methods that perform the actual work (i.e. posting the
    185   // file task on proxy_) after the quota check.
    186   void DoCreateFile(const FileSystemURL& url,
    187                     const StatusCallback& callback, bool exclusive);
    188   void DoCreateDirectory(const FileSystemURL& url,
    189                          const StatusCallback& callback,
    190                          bool exclusive,
    191                          bool recursive);
    192   void DoCopyFileLocal(const FileSystemURL& src,
    193                        const FileSystemURL& dest,
    194                        const StatusCallback& callback);
    195   void DoMoveFileLocal(const FileSystemURL& src,
    196                        const FileSystemURL& dest,
    197                        const StatusCallback& callback);
    198   void DoCopyInForeignFile(const base::FilePath& src_local_disk_file_path,
    199                            const FileSystemURL& dest,
    200                            const StatusCallback& callback);
    201   void DoTruncate(const FileSystemURL& url,
    202                   const StatusCallback& callback, int64 length);
    203   void DoOpenFile(const FileSystemURL& url,
    204                   const OpenFileCallback& callback, int file_flags);
    205 
    206   // Callback for CreateFile for |exclusive|=true cases.
    207   void DidEnsureFileExistsExclusive(const StatusCallback& callback,
    208                                     base::PlatformFileError rv,
    209                                     bool created);
    210 
    211   // Callback for CreateFile for |exclusive|=false cases.
    212   void DidEnsureFileExistsNonExclusive(const StatusCallback& callback,
    213                                        base::PlatformFileError rv,
    214                                        bool created);
    215 
    216   void DidFinishOperation(const StatusCallback& callback,
    217                           base::PlatformFileError rv);
    218   void DidDirectoryExists(const StatusCallback& callback,
    219                           base::PlatformFileError rv,
    220                           const base::PlatformFileInfo& file_info);
    221   void DidFileExists(const StatusCallback& callback,
    222                      base::PlatformFileError rv,
    223                      const base::PlatformFileInfo& file_info);
    224   void DidDeleteRecursively(const FileSystemURL& url,
    225                             const StatusCallback& callback,
    226                             base::PlatformFileError rv);
    227   void DidWrite(const FileSystemURL& url,
    228                 const WriteCallback& callback,
    229                 base::PlatformFileError rv,
    230                 int64 bytes,
    231                 FileWriterDelegate::WriteProgressStatus write_status);
    232   void DidOpenFile(const OpenFileCallback& callback,
    233                    base::PlatformFileError rv,
    234                    base::PassPlatformFile file,
    235                    const base::Closure& on_close_callback);
    236 
    237   // Used only for internal assertions.
    238   // Returns false if there's another inflight pending operation.
    239   bool SetPendingOperationType(OperationType type);
    240 
    241   scoped_refptr<FileSystemContext> file_system_context_;
    242 
    243   scoped_ptr<FileSystemOperationContext> operation_context_;
    244   AsyncFileUtil* async_file_util_;  // Not owned.
    245 
    246   scoped_ptr<FileWriterDelegate> file_writer_delegate_;
    247   scoped_ptr<RecursiveOperationDelegate> recursive_operation_delegate_;
    248 
    249   StatusCallback cancel_callback_;
    250 
    251   // Used only by OpenFile, in order to clone the file handle back to the
    252   // requesting process.
    253   base::ProcessHandle peer_handle_;
    254 
    255   // A flag to make sure we call operation only once per instance.
    256   OperationType pending_operation_;
    257 
    258   DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImpl);
    259 };
    260 
    261 }  // namespace fileapi
    262 
    263 #endif  // WEBKIT_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_IMPL_H_
    264