OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/browser/fileapi/copy_or_move_operation_delegate.h" | 5 #include "webkit/browser/fileapi/copy_or_move_operation_delegate.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "webkit/browser/fileapi/copy_or_move_file_validator.h" | 9 #include "webkit/browser/fileapi/copy_or_move_file_validator.h" |
10 #include "webkit/browser/fileapi/file_system_context.h" | 10 #include "webkit/browser/fileapi/file_system_context.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 error != base::PLATFORM_FILE_ERROR_NOT_FOUND) { | 103 error != base::PLATFORM_FILE_ERROR_NOT_FOUND) { |
104 callback_.Run(error); | 104 callback_.Run(error); |
105 return; | 105 return; |
106 } | 106 } |
107 | 107 |
108 // Start to process the source directory recursively. | 108 // Start to process the source directory recursively. |
109 // TODO(kinuko): This could be too expensive for same_file_system_==true | 109 // TODO(kinuko): This could be too expensive for same_file_system_==true |
110 // and operation==MOVE case, probably we can just rename the root directory. | 110 // and operation==MOVE case, probably we can just rename the root directory. |
111 // http://crbug.com/172187 | 111 // http://crbug.com/172187 |
112 StartRecursiveOperation( | 112 StartRecursiveOperation( |
113 src_root_, base::Bind(&CopyOrMoveOperationDelegate::DidFinishCopy, | 113 src_root_, base::Bind(&CopyOrMoveOperationDelegate::DidFinishCopyDir, |
114 AsWeakPtr(), src_root_, callback_)); | 114 AsWeakPtr(), src_root_, |
| 115 callback_)); |
115 } | 116 } |
116 | 117 |
117 void CopyOrMoveOperationDelegate::CopyOrMoveFile(const URLPair& url_pair, | 118 void CopyOrMoveOperationDelegate::CopyOrMoveFile( |
118 const StatusCallback& callback) { | 119 const URLPair& url_pair, |
| 120 const StatusCallback& callback) { |
119 // Same filesystem case. | 121 // Same filesystem case. |
120 if (same_file_system_) { | 122 if (same_file_system_) { |
121 if (operation_type_ == OPERATION_MOVE) { | 123 if (operation_type_ == OPERATION_MOVE) { |
122 operation_runner()->MoveFileLocal(url_pair.src, url_pair.dest, callback); | 124 operation_runner()->MoveFileLocal(url_pair.src, url_pair.dest, callback); |
123 } else { | 125 } else { |
124 operation_runner()->CopyFileLocal(url_pair.src, url_pair.dest, callback); | 126 operation_runner()->CopyFileLocal(url_pair.src, url_pair.dest, callback); |
125 } | 127 } |
126 return; | 128 return; |
127 } | 129 } |
128 | 130 |
129 // Cross filesystem case. | 131 // Cross filesystem case. |
130 // Perform CreateSnapshotFile, CopyInForeignFile and then calls | 132 // Perform CreateSnapshotFile, CopyInForeignFile and then calls |
131 // copy_callback which removes the source file if operation_type == MOVE. | 133 // copy_callback which removes the source file if operation_type == MOVE. |
132 StatusCallback copy_callback = | 134 StatusCallback copy_callback = |
133 base::Bind(&CopyOrMoveOperationDelegate::DidFinishCopy, AsWeakPtr(), | 135 base::Bind(&CopyOrMoveOperationDelegate::DidFinishCopy, AsWeakPtr(), |
134 url_pair.src, callback); | 136 url_pair, callback); |
135 operation_runner()->CreateSnapshotFile( | 137 operation_runner()->CreateSnapshotFile( |
136 url_pair.src, | 138 url_pair.src, |
137 base::Bind(&CopyOrMoveOperationDelegate::DidCreateSnapshot, AsWeakPtr(), | 139 base::Bind(&CopyOrMoveOperationDelegate::DidCreateSnapshot, AsWeakPtr(), |
138 url_pair, copy_callback)); | 140 url_pair, copy_callback)); |
139 } | 141 } |
140 | 142 |
141 void CopyOrMoveOperationDelegate::DidCreateSnapshot( | 143 void CopyOrMoveOperationDelegate::DidCreateSnapshot( |
142 const URLPair& url_pair, | 144 const URLPair& url_pair, |
143 const StatusCallback& callback, | 145 const StatusCallback& callback, |
144 base::PlatformFileError error, | 146 base::PlatformFileError error, |
(...skipping 17 matching lines...) Expand all Loading... |
162 callback.Run(error); | 164 callback.Run(error); |
163 return; | 165 return; |
164 } | 166 } |
165 if (!factory) { | 167 if (!factory) { |
166 DidValidateFile(url_pair.dest, callback, file_info, platform_path, error); | 168 DidValidateFile(url_pair.dest, callback, file_info, platform_path, error); |
167 return; | 169 return; |
168 } | 170 } |
169 | 171 |
170 validator_.reset( | 172 validator_.reset( |
171 factory->CreateCopyOrMoveFileValidator(url_pair.src, platform_path)); | 173 factory->CreateCopyOrMoveFileValidator(url_pair.src, platform_path)); |
172 validator_->StartValidation( | 174 validator_->StartPreWriteValidation( |
173 base::Bind(&CopyOrMoveOperationDelegate::DidValidateFile, AsWeakPtr(), | 175 base::Bind(&CopyOrMoveOperationDelegate::DidValidateFile, AsWeakPtr(), |
174 url_pair.dest, callback, file_info, platform_path)); | 176 url_pair.dest, callback, file_info, platform_path)); |
175 } | 177 } |
176 | 178 |
177 void CopyOrMoveOperationDelegate::DidValidateFile( | 179 void CopyOrMoveOperationDelegate::DidValidateFile( |
178 const FileSystemURL& dest, | 180 const FileSystemURL& dest, |
179 const StatusCallback& callback, | 181 const StatusCallback& callback, |
180 const base::PlatformFileInfo& file_info, | 182 const base::PlatformFileInfo& file_info, |
181 const base::FilePath& platform_path, | 183 const base::FilePath& platform_path, |
182 base::PlatformFileError error) { | 184 base::PlatformFileError error) { |
183 if (error != base::PLATFORM_FILE_OK) { | 185 if (error != base::PLATFORM_FILE_OK) { |
184 callback.Run(error); | 186 callback.Run(error); |
185 return; | 187 return; |
186 } | 188 } |
187 | 189 |
188 operation_runner()->CopyInForeignFile(platform_path, dest, callback); | 190 operation_runner()->CopyInForeignFile(platform_path, dest, callback); |
189 } | 191 } |
190 | 192 |
191 void CopyOrMoveOperationDelegate::DidFinishCopy( | 193 void CopyOrMoveOperationDelegate::DidFinishCopyDir( |
192 const FileSystemURL& src, | 194 const FileSystemURL& src, |
193 const StatusCallback& callback, | 195 const StatusCallback& callback, |
194 base::PlatformFileError error) { | 196 base::PlatformFileError error) { |
195 if (error != base::PLATFORM_FILE_OK || | 197 if (error != base::PLATFORM_FILE_OK || |
196 operation_type_ == OPERATION_COPY) { | 198 operation_type_ == OPERATION_COPY) { |
197 callback.Run(error); | 199 callback.Run(error); |
198 return; | 200 return; |
199 } | 201 } |
200 | 202 |
201 DCHECK_EQ(OPERATION_MOVE, operation_type_); | 203 DCHECK_EQ(operation_type_, OPERATION_MOVE); |
202 | 204 |
203 // Remove the source for finalizing move operation. | 205 // Remove the source for finalizing move operation. |
204 operation_runner()->Remove( | 206 operation_runner()->Remove( |
205 src, true /* recursive */, | 207 src, true /* recursive */, |
206 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, | 208 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, |
207 AsWeakPtr(), callback)); | 209 AsWeakPtr(), callback)); |
208 } | 210 } |
209 | 211 |
| 212 void CopyOrMoveOperationDelegate::DidFinishCopy( |
| 213 const URLPair& url_pair, |
| 214 const StatusCallback& callback, |
| 215 base::PlatformFileError error) { |
| 216 if (error != base::PLATFORM_FILE_OK) { |
| 217 callback.Run(error); |
| 218 return; |
| 219 } |
| 220 |
| 221 // |validator_| is NULL in the same-filesystem case or when the destination |
| 222 // filesystem does not do validation. |
| 223 if (!validator_.get()) { |
| 224 scoped_refptr<webkit_blob::ShareableFileReference> file_ref; |
| 225 DidPostWriteValidation(url_pair, callback, file_ref, |
| 226 base::PLATFORM_FILE_OK); |
| 227 return; |
| 228 } |
| 229 |
| 230 DCHECK(!same_file_system_); |
| 231 operation_runner()->CreateSnapshotFile( |
| 232 url_pair.dest, |
| 233 base::Bind(&CopyOrMoveOperationDelegate::DoPostWriteValidation, |
| 234 AsWeakPtr(), url_pair, callback)); |
| 235 } |
| 236 |
| 237 void CopyOrMoveOperationDelegate::DoPostWriteValidation( |
| 238 const URLPair& url_pair, |
| 239 const StatusCallback& callback, |
| 240 base::PlatformFileError error, |
| 241 const base::PlatformFileInfo& file_info, |
| 242 const base::FilePath& platform_path, |
| 243 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { |
| 244 if (error != base::PLATFORM_FILE_OK) { |
| 245 operation_runner()->Remove( |
| 246 url_pair.dest, true, |
| 247 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveDestForError, |
| 248 AsWeakPtr(), error, callback)); |
| 249 return; |
| 250 } |
| 251 |
| 252 DCHECK(validator_.get()); |
| 253 // Note: file_ref passed here to keep the file alive until after |
| 254 // the StartPostWriteValidation operation finishes. |
| 255 validator_->StartPostWriteValidation( |
| 256 platform_path, |
| 257 base::Bind(&CopyOrMoveOperationDelegate::DidPostWriteValidation, |
| 258 AsWeakPtr(), url_pair, callback, file_ref)); |
| 259 } |
| 260 |
| 261 // |file_ref| is unused; it is passed here to make sure the reference is |
| 262 // alive until after post-write validation is complete. |
| 263 void CopyOrMoveOperationDelegate::DidPostWriteValidation( |
| 264 const URLPair& url_pair, |
| 265 const StatusCallback& callback, |
| 266 const scoped_refptr<webkit_blob::ShareableFileReference>& /*file_ref*/, |
| 267 base::PlatformFileError error) { |
| 268 if (error != base::PLATFORM_FILE_OK) { |
| 269 operation_runner()->Remove( |
| 270 url_pair.dest, true, |
| 271 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveDestForError, |
| 272 AsWeakPtr(), error, callback)); |
| 273 return; |
| 274 } |
| 275 |
| 276 if (operation_type_ == OPERATION_COPY) { |
| 277 callback.Run(error); |
| 278 return; |
| 279 } |
| 280 |
| 281 DCHECK_EQ(OPERATION_MOVE, operation_type_); |
| 282 |
| 283 // Remove the source for finalizing move operation. |
| 284 operation_runner()->Remove( |
| 285 url_pair.src, true /* recursive */, |
| 286 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, |
| 287 AsWeakPtr(), callback)); |
| 288 } |
| 289 |
210 void CopyOrMoveOperationDelegate::DidRemoveSourceForMove( | 290 void CopyOrMoveOperationDelegate::DidRemoveSourceForMove( |
211 const StatusCallback& callback, | 291 const StatusCallback& callback, |
212 base::PlatformFileError error) { | 292 base::PlatformFileError error) { |
213 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) | 293 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) |
214 error = base::PLATFORM_FILE_OK; | 294 error = base::PLATFORM_FILE_OK; |
215 callback.Run(error); | 295 callback.Run(error); |
216 } | 296 } |
217 | 297 |
218 FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL( | 298 FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL( |
219 const FileSystemURL& src_url) const { | 299 const FileSystemURL& src_url) const { |
220 DCHECK_EQ(src_root_.type(), src_url.type()); | 300 DCHECK_EQ(src_root_.type(), src_url.type()); |
221 DCHECK_EQ(src_root_.origin(), src_url.origin()); | 301 DCHECK_EQ(src_root_.origin(), src_url.origin()); |
222 | 302 |
223 base::FilePath relative = dest_root_.virtual_path(); | 303 base::FilePath relative = dest_root_.virtual_path(); |
224 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), | 304 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), |
225 &relative); | 305 &relative); |
226 return file_system_context()->CreateCrackedFileSystemURL( | 306 return file_system_context()->CreateCrackedFileSystemURL( |
227 dest_root_.origin(), | 307 dest_root_.origin(), |
228 dest_root_.mount_type(), | 308 dest_root_.mount_type(), |
229 relative); | 309 relative); |
230 } | 310 } |
231 | 311 |
| 312 void CopyOrMoveOperationDelegate::DidRemoveDestForError( |
| 313 base::PlatformFileError prior_error, |
| 314 const StatusCallback& callback, |
| 315 base::PlatformFileError error) { |
| 316 if (error != base::PLATFORM_FILE_OK) { |
| 317 VLOG(1) << "Error removing destination file after validation error: " |
| 318 << error; |
| 319 } |
| 320 callback.Run(prior_error); |
| 321 } |
| 322 |
232 } // namespace fileapi | 323 } // namespace fileapi |
OLD | NEW |