12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#ifndef STORAGE_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define STORAGE_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <set>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stack>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/time/time.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/recursive_operation_delegate.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace net {
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class DrainableIOBuffer;
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class IOBufferWithSize;
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class FileStreamReader;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ShareableFileReference;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class CopyOrMoveFileValidator;
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class FileStreamWriter;
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A delegate class for recursive copy or move operations.
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CopyOrMoveOperationDelegate
33ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : public RecursiveOperationDelegate {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  class CopyOrMoveImpl;
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback;
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption;
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum OperationType {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OPERATION_COPY,
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OPERATION_MOVE
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Helper to copy a file by reader and writer streams.
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Export for testing.
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  class STORAGE_EXPORT StreamCopyHelper {
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)   public:
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    StreamCopyHelper(
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        scoped_ptr<storage::FileStreamReader> reader,
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        scoped_ptr<FileStreamWriter> writer,
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        bool need_flush,
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        int buffer_size,
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        const FileSystemOperation::CopyFileProgressCallback&
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            file_progress_callback,
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        const base::TimeDelta& min_progress_callback_invocation_span);
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ~StreamCopyHelper();
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    void Run(const StatusCallback& callback);
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Requests cancelling. After the cancelling is done, |callback| passed to
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Run will be called.
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    void Cancel();
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)   private:
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Reads the content from the |reader_|.
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    void Read(const StatusCallback& callback);
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    void DidRead(const StatusCallback& callback, int result);
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Writes the content in |buffer| to |writer_|.
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    void Write(const StatusCallback& callback,
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)               scoped_refptr<net::DrainableIOBuffer> buffer);
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    void DidWrite(const StatusCallback& callback,
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                  scoped_refptr<net::DrainableIOBuffer> buffer, int result);
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Flushes the written content in |writer_|.
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    void Flush(const StatusCallback& callback, bool is_eof);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    void DidFlush(const StatusCallback& callback, bool is_eof, int result);
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileStreamReader> reader_;
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    scoped_ptr<FileStreamWriter> writer_;
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const bool need_flush_;
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    FileSystemOperation::CopyFileProgressCallback file_progress_callback_;
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    scoped_refptr<net::IOBufferWithSize> io_buffer_;
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int64 num_copied_bytes_;
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 previous_flush_offset_;
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    base::Time last_progress_callback_invocation_time_;
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    base::TimeDelta min_progress_callback_invocation_span_;
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool cancel_requested_;
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    base::WeakPtrFactory<StreamCopyHelper> weak_factory_;
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(StreamCopyHelper);
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  };
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CopyOrMoveOperationDelegate(
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FileSystemContext* file_system_context,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const FileSystemURL& src_root,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const FileSystemURL& dest_root,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OperationType operation_type,
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      CopyOrMoveOption option,
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const CopyProgressCallback& progress_callback,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const StatusCallback& callback);
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~CopyOrMoveOperationDelegate();
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // RecursiveOperationDelegate overrides:
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Run() OVERRIDE;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void RunRecursively() OVERRIDE;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ProcessFile(const FileSystemURL& url,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const StatusCallback& callback) OVERRIDE;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ProcessDirectory(const FileSystemURL& url,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const StatusCallback& callback) OVERRIDE;
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void PostProcessDirectory(const FileSystemURL& url,
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                    const StatusCallback& callback) OVERRIDE;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) protected:
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnCancel() OVERRIDE;
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void DidCopyOrMoveFile(const FileSystemURL& src_url,
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                         const FileSystemURL& dest_url,
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                         const StatusCallback& callback,
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                         CopyOrMoveImpl* impl,
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         base::File::Error error);
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void DidTryRemoveDestRoot(const StatusCallback& callback,
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            base::File::Error error);
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void ProcessDirectoryInternal(const FileSystemURL& src_url,
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                const FileSystemURL& dest_url,
127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                const StatusCallback& callback);
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void DidCreateDirectory(const FileSystemURL& src_url,
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                          const FileSystemURL& dest_url,
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          const StatusCallback& callback,
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          base::File::Error error);
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void PostProcessDirectoryAfterGetMetadata(
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const FileSystemURL& src_url,
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const StatusCallback& callback,
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::File::Error error,
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::File::Info& file_info);
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void PostProcessDirectoryAfterTouchFile(const FileSystemURL& src_url,
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                          const StatusCallback& callback,
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          base::File::Error error);
140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void DidRemoveSourceForMove(const StatusCallback& callback,
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              base::File::Error error);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void OnCopyFileProgress(const FileSystemURL& src_url, int64 size);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL CreateDestURL(const FileSystemURL& src_url) const;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src_root_;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest_root_;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool same_file_system_;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OperationType operation_type_;
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CopyOrMoveOption option_;
151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CopyProgressCallback progress_callback_;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StatusCallback callback_;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::set<CopyOrMoveImpl*> running_copy_set_;
155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  base::WeakPtrFactory<CopyOrMoveOperationDelegate> weak_factory_;
156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOperationDelegate);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif  // STORAGE_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_
163