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 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_
    323