copy_or_move_hook_delegate.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright 2022 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. #ifndef STORAGE_BROWSER_FILE_SYSTEM_COPY_OR_MOVE_HOOK_DELEGATE_H_
  5. #define STORAGE_BROWSER_FILE_SYSTEM_COPY_OR_MOVE_HOOK_DELEGATE_H_
  6. #include "base/callback_forward.h"
  7. #include "base/component_export.h"
  8. #include "base/files/file.h"
  9. #include "base/memory/weak_ptr.h"
  10. #include "base/sequence_checker.h"
  11. namespace storage {
  12. class FileSystemURL;
  13. // A delegate to handle different hooks of the CopyOrMove operation.
  14. // Its At* functions take a callback that is called when the function
  15. // finishes, potentially notifying of any errors during the execution of
  16. // the function.
  17. // The Notify* functions do not take a callback and can asynchronously notify of
  18. // any progress or errors.
  19. // Used for progress updates, etc. in FileSystemOperation::Copy() and Move().
  20. //
  21. // Note that Move() has both a same-filesystem (1) and a cross-filesystem (2)
  22. // implementation.
  23. // 1) Requires metadata updates. Depending on the underlying implementation:
  24. // - we either only update the metadata of (or in other words, rename) the
  25. // moving directory
  26. // - or the directories are recursively copied + deleted, while the files are
  27. // moved by having their metadata updated.
  28. // 2) Degrades into copy + delete: each entry is copied and deleted
  29. // recursively.
  30. //
  31. // OnBeginProcessFile, resp. OnBeginProcessDirectory is called at the start of
  32. // each copy or move operation for a file, resp. a directory. The `source_url`
  33. // and the `destination_url` are the URLs of the source and the destination
  34. // entries. Note that for the root directory, OnBeginProcessFile is called
  35. // instead of OnBeginProcessDirectory. This resembles the call order of the
  36. // RecursiveOperationDelegate.
  37. //
  38. // OnProgress is called periodically during file transfer (not called for
  39. // same-filesystem move and directory copy/move).
  40. // The `source_url` and the `destination_url` are the URLs of the source and
  41. // the destination entries. `size` is the number of cumulative copied bytes
  42. // for the currently copied file. Both at beginning and ending of file
  43. // transfer, PROGRESS event should be called. At beginning, `size` should be
  44. // 0. At ending, `size` should be the size of the file.
  45. //
  46. // NotifyError is called for any occurring error.
  47. // The `source_url` and the `destination_url` are the URLs of the source and
  48. // the destination entries. `error` is the base::File::Error that was noticed.
  49. // NotifyError is also called if an OnBeginProcessFile or
  50. // OnBeginProcessDirectory function passes an error to their respective
  51. // callbacks.
  52. //
  53. // OnEndCopy is called for each destination entry that has been successfully
  54. // copied (for both file and directory). The `source_url` and the
  55. // `destination_url` are the URLs of the source and the destination entries.
  56. //
  57. // OnEndMove is called for each entry that has been successfully moved (for
  58. // both file and directory), in the case of a same-filesystem move. The
  59. // `source_url` and the `destination_url` are the URLs of the source and the
  60. // destination entries.
  61. //
  62. // OnEndRemoveSource, applies in the Move() case only, and is called for
  63. // each source entry that has been successfully removed from its source location
  64. // (for both file and directory). The `source_url` is the URL of the source
  65. // entry.
  66. //
  67. // When moving files, the expected events are as follows.
  68. // Copy: OnBeginProcessFile -> OnProgress -> ... -> OnProgress ->
  69. // OnEndCopy. Move (same-filesystem): OnBeginProcessFile -> OnEndMove.
  70. // Move (cross-filesystem): OnBeginProcessFile -> OnProgress -> ... ->
  71. // OnProgress -> OnEndCopy -> OnEndRemoveSource.
  72. //
  73. // Here is an example callback sequence of for a copy or a cross-filesystem
  74. // move. Suppose there are a/b/c.txt (100 bytes) and a/b/d.txt (200 bytes),
  75. // and trying to transfer a to x recursively, then the progress update
  76. // sequence will be (Note that for the root directory, OnBeginProcessFile is
  77. // called instead of OnBeginProcessDirectory):
  78. //
  79. // OnBeginProcessFile a x/a (starting create "a" directory in x/).
  80. // OnEndCopy a x/a (creating "a" directory in x/ is finished).
  81. //
  82. // OnBeginProcessDirectory a/b x/a/b (starting create "b" directory in x/a).
  83. // OnEndCopy a/b x/a/b (creating "b" directory in x/a/ is finished).
  84. //
  85. // OnBeginProcessFile a/b/c.txt x/a/b/c.txt (starting to transfer "c.txt" in
  86. // x/a/b/).
  87. // OnProgress a/b/c.txt x/a/b/c.txt 0 (The first OnProgress's `size`
  88. // should be 0).
  89. // OnProgress a/b/c.txt x/a/b/c.txt 10
  90. // :
  91. // OnProgress a/b/c.txt x/a/b/c.txt 90
  92. // OnProgress a/b/c.txt x/a/b/c.txt 100 (The last OnProgress's `size`
  93. // should be the size of the file).
  94. // OnEndCopy a/b/c.txt x/a/b/c.txt (transferring "c.txt" is finished).
  95. // OnEndRemoveSource a/b/c.txt ("copy + delete" move case).
  96. //
  97. // OnBeginProcessFile a/b/d.txt x/a/b/d.txt (starting to transfer "d.txt" in
  98. // x/a/b).
  99. // OnProgress a/b/d.txt x/a/b/d.txt 0 (The first OnProgress's
  100. // `size` should be 0).
  101. // OnProgress a/b/d.txt x/a/b/d.txt 10
  102. // :
  103. // OnProgress a/b/d.txt x/a/b/d.txt 190
  104. // OnProgress a/b/d.txt x/a/b/d.txt 200 (The last OnProgress's `size`
  105. // should be the size of the file).
  106. // OnEndCopy a/b/d.txt x/a/b/d.txt (transferring "d.txt" is finished).
  107. // OnEndRemoveSource a/b/d.txt ("copy + delete" move case).
  108. //
  109. // OnEndRemoveSource a/b ("copy + delete" move case).
  110. //
  111. // OnEndRemoveSource a ("copy + delete" move case).
  112. //
  113. // Note that event sequence of a/b/c.txt and a/b/d.txt can be interlaced,
  114. // because they can be done in parallel. Also OnProgress events are
  115. // optional, so they may not appear. All the progress callback invocations
  116. // should be done before StatusCallback given to the Copy is called. Especially
  117. // if an error is found before the first progress callback invocation, the
  118. // progress callback may NOT be invoked for the copy.
  119. //
  120. class COMPONENT_EXPORT(STORAGE_BROWSER) CopyOrMoveHookDelegate
  121. : public base::SupportsWeakPtr<CopyOrMoveHookDelegate> {
  122. public:
  123. using StatusCallback = base::OnceCallback<void(base::File::Error result)>;
  124. CopyOrMoveHookDelegate();
  125. virtual ~CopyOrMoveHookDelegate() = default;
  126. virtual void OnBeginProcessFile(const FileSystemURL& source_url,
  127. const FileSystemURL& destination_url,
  128. StatusCallback callback);
  129. virtual void OnBeginProcessDirectory(const FileSystemURL& source_url,
  130. const FileSystemURL& destination_url,
  131. StatusCallback callback);
  132. virtual void OnProgress(const FileSystemURL& source_url,
  133. const FileSystemURL& destination_url,
  134. int64_t size);
  135. virtual void OnError(const FileSystemURL& source_url,
  136. const FileSystemURL& destination_url,
  137. base::File::Error error);
  138. virtual void OnEndCopy(const FileSystemURL& source_url,
  139. const FileSystemURL& destination_url);
  140. virtual void OnEndMove(const FileSystemURL& source_url,
  141. const FileSystemURL& destination_url);
  142. virtual void OnEndRemoveSource(const FileSystemURL& source_url);
  143. protected:
  144. SEQUENCE_CHECKER(sequence_checker_);
  145. };
  146. } // namespace storage
  147. #endif // STORAGE_BROWSER_FILE_SYSTEM_COPY_OR_MOVE_HOOK_DELEGATE_H_