File: copy_or_move_hook_delegate.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (167 lines) | stat: -rw-r--r-- 8,006 bytes parent folder | download | duplicates (9)
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
163
164
165
166
167
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef STORAGE_BROWSER_FILE_SYSTEM_COPY_OR_MOVE_HOOK_DELEGATE_H_
#define STORAGE_BROWSER_FILE_SYSTEM_COPY_OR_MOVE_HOOK_DELEGATE_H_

#include "base/component_export.h"
#include "base/files/file.h"
#include "base/functional/callback_forward.h"
#include "base/sequence_checker.h"

namespace storage {
class FileSystemURL;

// A delegate to handle different hooks of the CopyOrMove operation.
// Its OnBegin* functions take a callback that should be called when the
// function finishes, potentially notifying of any errors during the execution
// of the function. Similarly, OnError takes a callback that is called when a
// error happens and might be used to skip the error and continue the operation.
//
// The other functions do not take a callback and can asynchronously notify of
// any progress. They are used for progress updates, etc. in
// FileSystemOperation::Copy() and Move().
//
// Note that Move() has both a same-filesystem (1) and a cross-filesystem (2)
// implementation.
// 1) Requires metadata updates. Depending on the underlying implementation:
// - we either only update the metadata of (or in other words, rename) the
// moving directory
// - or the directories are recursively copied + deleted, while the files are
// moved by having their metadata updated.
// 2) Degrades into copy + delete: each entry is copied and deleted
// recursively.
//
// When transferring files, the expected events are as follows:
// Copy: OnBeginProcessFile -> OnProgress -> ... -> OnProgress ->
//   OnEndCopy.
// Move (same-filesystem): OnBeginProcessFile -> OnEndMove.
// Move (cross-filesystem): OnBeginProcessFile -> OnProgress -> ... ->
//   OnProgress -> OnEndCopy -> OnEndRemoveSource.
//
// Here is an example callback sequence of for a copy or a cross-filesystem
// move. Suppose there are a/b/c.txt (100 bytes) and a/b/d.txt (200 bytes),
// and trying to transfer a/ to x/ recursively, then the progress update
// sequence will be (Note that for the root directory, OnBeginProcessFile is
// called instead of OnBeginProcessDirectory):
//
// OnBeginProcessFile a x/a (starting create "a" directory in x/).
// OnEndCopy a x/a (creating "a" directory in x/ is finished).
//
// OnBeginProcessDirectory a/b x/a/b (starting create "b" directory in x/a).
// OnEndCopy a/b x/a/b (creating "b" directory in x/a/ is finished).
//
// OnBeginProcessFile a/b/c.txt x/a/b/c.txt (starting to transfer "c.txt" in
//                                           x/a/b/).
// OnProgress a/b/c.txt x/a/b/c.txt 0 (The first OnProgress's `size`
//                                         should be 0).
// OnProgress a/b/c.txt x/a/b/c.txt 10
//    :
// OnProgress a/b/c.txt x/a/b/c.txt 90
// OnProgress a/b/c.txt x/a/b/c.txt 100 (The last OnProgress's `size`
//                                           should be the size of the file).
// OnEndCopy a/b/c.txt x/a/b/c.txt (transferring "c.txt" is finished).
// OnEndRemoveSource a/b/c.txt ("copy + delete" move case).
//
// OnBeginProcessFile a/b/d.txt x/a/b/d.txt (starting to transfer "d.txt" in
//                                           x/a/b).
// OnProgress a/b/d.txt x/a/b/d.txt 0 (The first OnProgress's
//                                         `size` should be 0).
// OnProgress a/b/d.txt x/a/b/d.txt 10
//    :
// OnProgress a/b/d.txt x/a/b/d.txt 190
// OnProgress a/b/d.txt x/a/b/d.txt 200 (The last OnProgress's `size`
//                                           should be the size of the file).
// OnEndCopy a/b/d.txt x/a/b/d.txt (transferring "d.txt" is finished).
// OnEndRemoveSource a/b/d.txt ("copy + delete" move case).
//
// OnEndRemoveSource a/b ("copy + delete" move case).
//
// OnEndRemoveSource a ("copy + delete" move case).
//
// Note that event sequence of a/b/c.txt and a/b/d.txt can be interlaced,
// because they can be done in parallel. Also OnProgress events are
// optional, so they may not appear. All the progress callback invocations
// should be done before StatusCallback given to the Copy is called. Especially
// if an error is found before the first progress callback invocation, the
// progress callback may NOT be invoked for the copy.
//
class COMPONENT_EXPORT(STORAGE_BROWSER) CopyOrMoveHookDelegate {
 public:
  enum class ErrorAction { kDefault, kSkip };
  using StatusCallback = base::OnceCallback<void(base::File::Error result)>;
  using ErrorCallback = base::OnceCallback<void(ErrorAction)>;

  explicit CopyOrMoveHookDelegate(bool is_composite = false);

  virtual ~CopyOrMoveHookDelegate();

  // OnBeginProcessFile, resp. OnBeginProcessDirectory is called at the start of
  // each copy or move operation for a file, resp. a directory. Note that for
  // the root directory, OnBeginProcessFile is called instead of
  // OnBeginProcessDirectory. This resembles the call order of the
  // RecursiveOperationDelegate.
  virtual void OnBeginProcessFile(const FileSystemURL& source_url,
                                  const FileSystemURL& destination_url,
                                  StatusCallback callback);
  virtual void OnBeginProcessDirectory(const FileSystemURL& source_url,
                                       const FileSystemURL& destination_url,
                                       StatusCallback callback);

  // OnProgress is called periodically during file transfer (not called for
  // same-filesystem move and directory copy/move).
  // `size` is the number of cumulative copied bytes for the currently copied
  // file. Both at beginning and ending of file transfer, PROGRESS event should
  // be called. At beginning, `size` should be 0. At ending, `size` should be
  // the size of the file.
  virtual void OnProgress(const FileSystemURL& source_url,
                          const FileSystemURL& destination_url,
                          int64_t size);

  // OnError is called for any occurring error.
  // `error` is the base::File::Error that was noticed.
  // `callback` might be used to skip/suppress the error (when invoked with
  // kSkip), otherwise should be just called with kDefault.
  // Note that:
  //  * OnError is also called if an OnBeginProcessFile or
  //  OnBeginProcessDirectory function passes an error to their respective
  //  callbacks.
  //  * The operation is paused until the `callback` gets called.
  //  * Using kSkip will continue the operation even if it was run with
  //  ERROR_BEHAVIOR_ABORT, which makes possible to make abort/skip
  //  decision per every error encountered.
  virtual void OnError(const FileSystemURL& source_url,
                       const FileSystemURL& destination_url,
                       base::File::Error error,
                       ErrorCallback callback);

  // OnEndCopy is called for each destination entry that has been successfully
  // copied (for both file and directory). As mentioned before, it is also
  // called for a cross-filesystem move.
  virtual void OnEndCopy(const FileSystemURL& source_url,
                         const FileSystemURL& destination_url);

  // OnEndMove is called for each entry that has been successfully moved (for
  // both file and directory), in the case of a same-filesystem move.
  virtual void OnEndMove(const FileSystemURL& source_url,
                         const FileSystemURL& destination_url);

  // OnEndRemoveSource, applies in the Move() case only, and is called for
  // each source entry that has been successfully removed from its source
  // location (for both file and directory).
  virtual void OnEndRemoveSource(const FileSystemURL& source_url);

 protected:
  friend class CopyOrMoveHookDelegateCompositeTest;
  friend class CopyOrMoveHookDelegateComposite;

  SEQUENCE_CHECKER(sequence_checker_);

  // Indicates if this is an instance of CopyOrMoveHookDelegateComposite.
  const bool is_composite_ = false;
};

}  // namespace storage

#endif  // STORAGE_BROWSER_FILE_SYSTEM_COPY_OR_MOVE_HOOK_DELEGATE_H_