summaryrefslogtreecommitdiffstats
path: root/storage/browser/fileapi/copy_or_move_operation_delegate.h
blob: 81731179665b8c2b2bf6be49819215c58755bd52 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef STORAGE_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_
#define STORAGE_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_

#include <set>
#include <stack>

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "storage/browser/fileapi/recursive_operation_delegate.h"

namespace net {
class DrainableIOBuffer;
class IOBufferWithSize;
}

namespace storage {
class FileStreamReader;
class ShareableFileReference;
}

namespace storage {

class CopyOrMoveFileValidator;
class FileStreamWriter;

// A delegate class for recursive copy or move operations.
class CopyOrMoveOperationDelegate
    : public RecursiveOperationDelegate {
 public:
  class CopyOrMoveImpl;
  typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback;
  typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption;

  enum OperationType {
    OPERATION_COPY,
    OPERATION_MOVE
  };

  // Helper to copy a file by reader and writer streams.
  // Export for testing.
  class STORAGE_EXPORT StreamCopyHelper {
   public:
    StreamCopyHelper(
        scoped_ptr<storage::FileStreamReader> reader,
        scoped_ptr<FileStreamWriter> writer,
        bool need_flush,
        int buffer_size,
        const FileSystemOperation::CopyFileProgressCallback&
            file_progress_callback,
        const base::TimeDelta& min_progress_callback_invocation_span);
    ~StreamCopyHelper();

    void Run(const StatusCallback& callback);

    // Requests cancelling. After the cancelling is done, |callback| passed to
    // Run will be called.
    void Cancel();

   private:
    // Reads the content from the |reader_|.
    void Read(const StatusCallback& callback);
    void DidRead(const StatusCallback& callback, int result);

    // Writes the content in |buffer| to |writer_|.
    void Write(const StatusCallback& callback,
               scoped_refptr<net::DrainableIOBuffer> buffer);
    void DidWrite(const StatusCallback& callback,
                  scoped_refptr<net::DrainableIOBuffer> buffer, int result);

    // Flushes the written content in |writer_|.
    void Flush(const StatusCallback& callback, bool is_eof);
    void DidFlush(const StatusCallback& callback, bool is_eof, int result);

    scoped_ptr<storage::FileStreamReader> reader_;
    scoped_ptr<FileStreamWriter> writer_;
    const bool need_flush_;
    FileSystemOperation::CopyFileProgressCallback file_progress_callback_;
    scoped_refptr<net::IOBufferWithSize> io_buffer_;
    int64 num_copied_bytes_;
    int64 previous_flush_offset_;
    base::Time last_progress_callback_invocation_time_;
    base::TimeDelta min_progress_callback_invocation_span_;
    bool cancel_requested_;
    base::WeakPtrFactory<StreamCopyHelper> weak_factory_;
    DISALLOW_COPY_AND_ASSIGN(StreamCopyHelper);
  };

  CopyOrMoveOperationDelegate(
      FileSystemContext* file_system_context,
      const FileSystemURL& src_root,
      const FileSystemURL& dest_root,
      OperationType operation_type,
      CopyOrMoveOption option,
      const CopyProgressCallback& progress_callback,
      const StatusCallback& callback);
  virtual ~CopyOrMoveOperationDelegate();

  // RecursiveOperationDelegate overrides:
  virtual void Run() override;
  virtual void RunRecursively() override;
  virtual void ProcessFile(const FileSystemURL& url,
                           const StatusCallback& callback) override;
  virtual void ProcessDirectory(const FileSystemURL& url,
                                const StatusCallback& callback) override;
  virtual void PostProcessDirectory(const FileSystemURL& url,
                                    const StatusCallback& callback) override;


 protected:
  virtual void OnCancel() override;

 private:
  void DidCopyOrMoveFile(const FileSystemURL& src_url,
                         const FileSystemURL& dest_url,
                         const StatusCallback& callback,
                         CopyOrMoveImpl* impl,
                         base::File::Error error);
  void DidTryRemoveDestRoot(const StatusCallback& callback,
                            base::File::Error error);
  void ProcessDirectoryInternal(const FileSystemURL& src_url,
                                const FileSystemURL& dest_url,
                                const StatusCallback& callback);
  void DidCreateDirectory(const FileSystemURL& src_url,
                          const FileSystemURL& dest_url,
                          const StatusCallback& callback,
                          base::File::Error error);
  void PostProcessDirectoryAfterGetMetadata(
      const FileSystemURL& src_url,
      const StatusCallback& callback,
      base::File::Error error,
      const base::File::Info& file_info);
  void PostProcessDirectoryAfterTouchFile(const FileSystemURL& src_url,
                                          const StatusCallback& callback,
                                          base::File::Error error);
  void DidRemoveSourceForMove(const StatusCallback& callback,
                              base::File::Error error);

  void OnCopyFileProgress(const FileSystemURL& src_url, int64 size);
  FileSystemURL CreateDestURL(const FileSystemURL& src_url) const;

  FileSystemURL src_root_;
  FileSystemURL dest_root_;
  bool same_file_system_;
  OperationType operation_type_;
  CopyOrMoveOption option_;
  CopyProgressCallback progress_callback_;
  StatusCallback callback_;

  std::set<CopyOrMoveImpl*> running_copy_set_;
  base::WeakPtrFactory<CopyOrMoveOperationDelegate> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOperationDelegate);
};

}  // namespace storage

#endif  // STORAGE_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_