1// Copyright (c) 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_COPY_OR_MOVE_OPERATION_DELEGATE_H_
6#define STORAGE_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_
7
8#include <set>
9#include <stack>
10
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/time/time.h"
14#include "storage/browser/fileapi/recursive_operation_delegate.h"
15
16namespace net {
17class DrainableIOBuffer;
18class IOBufferWithSize;
19}
20
21namespace storage {
22class FileStreamReader;
23class ShareableFileReference;
24}
25
26namespace storage {
27
28class CopyOrMoveFileValidator;
29class FileStreamWriter;
30
31// A delegate class for recursive copy or move operations.
32class CopyOrMoveOperationDelegate
33    : public RecursiveOperationDelegate {
34 public:
35  class CopyOrMoveImpl;
36  typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback;
37  typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption;
38
39  enum OperationType {
40    OPERATION_COPY,
41    OPERATION_MOVE
42  };
43
44  // Helper to copy a file by reader and writer streams.
45  // Export for testing.
46  class STORAGE_EXPORT StreamCopyHelper {
47   public:
48    StreamCopyHelper(
49        scoped_ptr<storage::FileStreamReader> reader,
50        scoped_ptr<FileStreamWriter> writer,
51        bool need_flush,
52        int buffer_size,
53        const FileSystemOperation::CopyFileProgressCallback&
54            file_progress_callback,
55        const base::TimeDelta& min_progress_callback_invocation_span);
56    ~StreamCopyHelper();
57
58    void Run(const StatusCallback& callback);
59
60    // Requests cancelling. After the cancelling is done, |callback| passed to
61    // Run will be called.
62    void Cancel();
63
64   private:
65    // Reads the content from the |reader_|.
66    void Read(const StatusCallback& callback);
67    void DidRead(const StatusCallback& callback, int result);
68
69    // Writes the content in |buffer| to |writer_|.
70    void Write(const StatusCallback& callback,
71               scoped_refptr<net::DrainableIOBuffer> buffer);
72    void DidWrite(const StatusCallback& callback,
73                  scoped_refptr<net::DrainableIOBuffer> buffer, int result);
74
75    // Flushes the written content in |writer_|.
76    void Flush(const StatusCallback& callback, bool is_eof);
77    void DidFlush(const StatusCallback& callback, bool is_eof, int result);
78
79    scoped_ptr<storage::FileStreamReader> reader_;
80    scoped_ptr<FileStreamWriter> writer_;
81    const bool need_flush_;
82    FileSystemOperation::CopyFileProgressCallback file_progress_callback_;
83    scoped_refptr<net::IOBufferWithSize> io_buffer_;
84    int64 num_copied_bytes_;
85    int64 previous_flush_offset_;
86    base::Time last_progress_callback_invocation_time_;
87    base::TimeDelta min_progress_callback_invocation_span_;
88    bool cancel_requested_;
89    base::WeakPtrFactory<StreamCopyHelper> weak_factory_;
90    DISALLOW_COPY_AND_ASSIGN(StreamCopyHelper);
91  };
92
93  CopyOrMoveOperationDelegate(
94      FileSystemContext* file_system_context,
95      const FileSystemURL& src_root,
96      const FileSystemURL& dest_root,
97      OperationType operation_type,
98      CopyOrMoveOption option,
99      const CopyProgressCallback& progress_callback,
100      const StatusCallback& callback);
101  virtual ~CopyOrMoveOperationDelegate();
102
103  // RecursiveOperationDelegate overrides:
104  virtual void Run() OVERRIDE;
105  virtual void RunRecursively() OVERRIDE;
106  virtual void ProcessFile(const FileSystemURL& url,
107                           const StatusCallback& callback) OVERRIDE;
108  virtual void ProcessDirectory(const FileSystemURL& url,
109                                const StatusCallback& callback) OVERRIDE;
110  virtual void PostProcessDirectory(const FileSystemURL& url,
111                                    const StatusCallback& callback) OVERRIDE;
112
113
114 protected:
115  virtual void OnCancel() OVERRIDE;
116
117 private:
118  void DidCopyOrMoveFile(const FileSystemURL& src_url,
119                         const FileSystemURL& dest_url,
120                         const StatusCallback& callback,
121                         CopyOrMoveImpl* impl,
122                         base::File::Error error);
123  void DidTryRemoveDestRoot(const StatusCallback& callback,
124                            base::File::Error error);
125  void ProcessDirectoryInternal(const FileSystemURL& src_url,
126                                const FileSystemURL& dest_url,
127                                const StatusCallback& callback);
128  void DidCreateDirectory(const FileSystemURL& src_url,
129                          const FileSystemURL& dest_url,
130                          const StatusCallback& callback,
131                          base::File::Error error);
132  void PostProcessDirectoryAfterGetMetadata(
133      const FileSystemURL& src_url,
134      const StatusCallback& callback,
135      base::File::Error error,
136      const base::File::Info& file_info);
137  void PostProcessDirectoryAfterTouchFile(const FileSystemURL& src_url,
138                                          const StatusCallback& callback,
139                                          base::File::Error error);
140  void DidRemoveSourceForMove(const StatusCallback& callback,
141                              base::File::Error error);
142
143  void OnCopyFileProgress(const FileSystemURL& src_url, int64 size);
144  FileSystemURL CreateDestURL(const FileSystemURL& src_url) const;
145
146  FileSystemURL src_root_;
147  FileSystemURL dest_root_;
148  bool same_file_system_;
149  OperationType operation_type_;
150  CopyOrMoveOption option_;
151  CopyProgressCallback progress_callback_;
152  StatusCallback callback_;
153
154  std::set<CopyOrMoveImpl*> running_copy_set_;
155  base::WeakPtrFactory<CopyOrMoveOperationDelegate> weak_factory_;
156
157  DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOperationDelegate);
158};
159
160}  // namespace storage
161
162#endif  // STORAGE_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_
163