Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Side by Side Diff: webkit/fileapi/cross_operation_delegate.cc

Issue 15535006: Move browser-specific FileAPI code from webkit/fileapi to webkit/browser/fileapi (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/fileapi/cross_operation_delegate.h ('k') | webkit/fileapi/file_system_context.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "webkit/fileapi/cross_operation_delegate.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "webkit/blob/shareable_file_reference.h"
10 #include "webkit/fileapi/copy_or_move_file_validator.h"
11 #include "webkit/fileapi/file_system_context.h"
12 #include "webkit/fileapi/file_system_operation_context.h"
13 #include "webkit/fileapi/file_system_url.h"
14 #include "webkit/fileapi/file_system_util.h"
15 #include "webkit/fileapi/local_file_system_operation.h"
16
17 namespace fileapi {
18
19 CrossOperationDelegate::CrossOperationDelegate(
20 FileSystemContext* file_system_context,
21 scoped_ptr<LocalFileSystemOperation> src_root_operation,
22 LocalFileSystemOperation* dest_root_operation,
23 const FileSystemURL& src_root,
24 const FileSystemURL& dest_root,
25 OperationType operation_type,
26 const StatusCallback& callback)
27 : RecursiveOperationDelegate(file_system_context, dest_root_operation),
28 src_root_(src_root),
29 dest_root_(dest_root),
30 operation_type_(operation_type),
31 callback_(callback),
32 src_root_operation_(src_root_operation.Pass()) {
33 same_file_system_ = AreSameFileSystem(src_root_, dest_root_);
34 }
35
36 CrossOperationDelegate::~CrossOperationDelegate() {
37 }
38
39 void CrossOperationDelegate::Run() {
40 // Not supported; this should never be called.
41 NOTREACHED();
42 }
43
44 void CrossOperationDelegate::RunRecursively() {
45 // Perform light-weight checks first.
46
47 // It is an error to try to copy/move an entry into its child.
48 if (same_file_system_ && src_root_.path().IsParent(dest_root_.path())) {
49 callback_.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
50 return;
51 }
52
53 // It is an error to copy/move an entry into the same path.
54 if (same_file_system_ && src_root_.path() == dest_root_.path()) {
55 callback_.Run(base::PLATFORM_FILE_ERROR_EXISTS);
56 return;
57 }
58
59 // First try to copy/move it as a file.
60 CopyOrMoveFile(URLPair(src_root_, dest_root_),
61 base::Bind(&CrossOperationDelegate::DidTryCopyOrMoveFile,
62 AsWeakPtr()));
63 }
64
65 void CrossOperationDelegate::ProcessFile(const FileSystemURL& src_url,
66 const StatusCallback& callback) {
67 CopyOrMoveFile(URLPair(src_url, CreateDestURL(src_url)), callback);
68 }
69
70 void CrossOperationDelegate::ProcessDirectory(const FileSystemURL& src_url,
71 const StatusCallback& callback) {
72 FileSystemURL dest_url = CreateDestURL(src_url);
73
74 // If operation_type == Move we may need to record directories and
75 // restore directory timestamps in the end, though it may have
76 // negative performance impact.
77 // See http://crbug.com/171284 for more details.
78 NewDestOperation()->CreateDirectory(
79 dest_url, false /* exclusive */, false /* recursive */, callback);
80 }
81
82 void CrossOperationDelegate::DidTryCopyOrMoveFile(
83 base::PlatformFileError error) {
84 if (error == base::PLATFORM_FILE_OK ||
85 error != base::PLATFORM_FILE_ERROR_NOT_A_FILE) {
86 callback_.Run(error);
87 return;
88 }
89
90 // The src_root_ looks to be a directory.
91 // Try removing the dest_root_ to see if it exists and/or it is an
92 // empty directory.
93 NewDestOperation()->RemoveDirectory(
94 dest_root_, base::Bind(&CrossOperationDelegate::DidTryRemoveDestRoot,
95 AsWeakPtr()));
96 }
97
98 void CrossOperationDelegate::DidTryRemoveDestRoot(
99 base::PlatformFileError error) {
100 if (error == base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY) {
101 callback_.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
102 return;
103 }
104 if (error != base::PLATFORM_FILE_OK &&
105 error != base::PLATFORM_FILE_ERROR_NOT_FOUND) {
106 callback_.Run(error);
107 return;
108 }
109
110 // Start to process the source directory recursively.
111 // TODO(kinuko): This could be too expensive for same_file_system_==true
112 // and operation==MOVE case, probably we can just rename the root directory.
113 // http://crbug.com/172187
114 StartRecursiveOperation(
115 src_root_, base::Bind(&CrossOperationDelegate::DidFinishCopy,
116 AsWeakPtr(), src_root_, callback_));
117 }
118
119 void CrossOperationDelegate::CopyOrMoveFile(const URLPair& url_pair,
120 const StatusCallback& callback) {
121 // Same filesystem case.
122 if (same_file_system_) {
123 if (operation_type_ == OPERATION_MOVE) {
124 NewSourceOperation()->MoveFileLocal(url_pair.src, url_pair.dest,
125 callback);
126 } else {
127 NewSourceOperation()->CopyFileLocal(url_pair.src, url_pair.dest,
128 callback);
129 }
130 return;
131 }
132
133 // Cross filesystem case.
134 // Perform CreateSnapshotFile, CopyInForeignFile and then calls
135 // copy_callback which removes the source file if operation_type == MOVE.
136 StatusCallback copy_callback =
137 base::Bind(&CrossOperationDelegate::DidFinishCopy, AsWeakPtr(),
138 url_pair.src, callback);
139 NewSourceOperation()->CreateSnapshotFile(
140 url_pair.src,
141 base::Bind(&CrossOperationDelegate::DidCreateSnapshot, AsWeakPtr(),
142 url_pair, copy_callback));
143 }
144
145 void CrossOperationDelegate::DidCreateSnapshot(
146 const URLPair& url_pair,
147 const StatusCallback& callback,
148 base::PlatformFileError error,
149 const base::PlatformFileInfo& file_info,
150 const base::FilePath& platform_path,
151 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
152 if (error != base::PLATFORM_FILE_OK) {
153 callback.Run(error);
154 return;
155 }
156 current_file_ref_ = file_ref;
157
158 // For now we assume CreateSnapshotFile always return a valid local file path.
159 // TODO(kinuko): Otherwise create a FileStreamReader to perform a copy/move.
160 DCHECK(!platform_path.empty());
161
162 CopyOrMoveFileValidatorFactory* factory =
163 file_system_context()->GetCopyOrMoveFileValidatorFactory(
164 dest_root_.type(), &error);
165 if (error != base::PLATFORM_FILE_OK) {
166 callback.Run(error);
167 return;
168 }
169 if (!factory) {
170 DidValidateFile(url_pair.dest, callback, file_info, platform_path, error);
171 return;
172 }
173
174 validator_.reset(
175 factory->CreateCopyOrMoveFileValidator(url_pair.src, platform_path));
176 validator_->StartValidation(
177 base::Bind(&CrossOperationDelegate::DidValidateFile, AsWeakPtr(),
178 url_pair.dest, callback, file_info, platform_path));
179 }
180
181 void CrossOperationDelegate::DidValidateFile(
182 const FileSystemURL& dest,
183 const StatusCallback& callback,
184 const base::PlatformFileInfo& file_info,
185 const base::FilePath& platform_path,
186 base::PlatformFileError error) {
187 if (error != base::PLATFORM_FILE_OK) {
188 callback.Run(error);
189 return;
190 }
191
192 NewDestOperation()->CopyInForeignFile(platform_path, dest, callback);
193 }
194
195 void CrossOperationDelegate::DidFinishCopy(
196 const FileSystemURL& src,
197 const StatusCallback& callback,
198 base::PlatformFileError error) {
199 if (error != base::PLATFORM_FILE_OK ||
200 operation_type_ == OPERATION_COPY) {
201 callback.Run(error);
202 return;
203 }
204
205 DCHECK_EQ(OPERATION_MOVE, operation_type_);
206
207 // Remove the source for finalizing move operation.
208 NewSourceOperation()->Remove(
209 src, true /* recursive */,
210 base::Bind(&CrossOperationDelegate::DidRemoveSourceForMove,
211 AsWeakPtr(), callback));
212 }
213
214 void CrossOperationDelegate::DidRemoveSourceForMove(
215 const StatusCallback& callback,
216 base::PlatformFileError error) {
217 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
218 error = base::PLATFORM_FILE_OK;
219 callback.Run(error);
220 }
221
222 FileSystemURL CrossOperationDelegate::CreateDestURL(
223 const FileSystemURL& src_url) const {
224 DCHECK_EQ(src_root_.type(), src_url.type());
225 DCHECK_EQ(src_root_.origin(), src_url.origin());
226
227 base::FilePath relative = dest_root_.virtual_path();
228 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(),
229 &relative);
230 return file_system_context()->CreateCrackedFileSystemURL(
231 dest_root_.origin(),
232 dest_root_.mount_type(),
233 relative);
234 }
235
236 LocalFileSystemOperation* CrossOperationDelegate::NewDestOperation() {
237 return NewNestedOperation();
238 }
239
240 LocalFileSystemOperation* CrossOperationDelegate::NewSourceOperation() {
241 if (same_file_system_)
242 return NewDestOperation();
243 return src_root_operation_->CreateNestedOperation();
244 }
245
246 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/cross_operation_delegate.h ('k') | webkit/fileapi/file_system_context.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698