OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/local_file_system_operation.h" | 5 #include "webkit/browser/fileapi/local_file_system_operation.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 } | 38 } |
39 | 39 |
40 LocalFileSystemOperation::LocalFileSystemOperation( | 40 LocalFileSystemOperation::LocalFileSystemOperation( |
41 const FileSystemURL& url, | 41 const FileSystemURL& url, |
42 FileSystemContext* file_system_context, | 42 FileSystemContext* file_system_context, |
43 scoped_ptr<FileSystemOperationContext> operation_context) | 43 scoped_ptr<FileSystemOperationContext> operation_context) |
44 : file_system_context_(file_system_context), | 44 : file_system_context_(file_system_context), |
45 operation_context_(operation_context.Pass()), | 45 operation_context_(operation_context.Pass()), |
46 async_file_util_(NULL), | 46 async_file_util_(NULL), |
47 peer_handle_(base::kNullProcessHandle), | 47 peer_handle_(base::kNullProcessHandle), |
48 pending_operation_(kOperationNone), | 48 pending_operation_(kOperationNone) { |
49 weak_factory_(this) { | |
50 DCHECK(operation_context_.get()); | 49 DCHECK(operation_context_.get()); |
51 operation_context_->DetachUserDataThread(); | 50 operation_context_->DetachUserDataThread(); |
52 async_file_util_ = file_system_context_->GetAsyncFileUtil(url.type()); | 51 async_file_util_ = file_system_context_->GetAsyncFileUtil(url.type()); |
53 DCHECK(async_file_util_); | 52 DCHECK(async_file_util_); |
54 } | 53 } |
55 | 54 |
56 LocalFileSystemOperation::~LocalFileSystemOperation() { | 55 LocalFileSystemOperation::~LocalFileSystemOperation() { |
57 } | 56 } |
58 | 57 |
59 void LocalFileSystemOperation::CreateFile(const FileSystemURL& url, | 58 void LocalFileSystemOperation::CreateFile(const FileSystemURL& url, |
60 bool exclusive, | 59 bool exclusive, |
61 const StatusCallback& callback) { | 60 const StatusCallback& callback) { |
62 DCHECK(SetPendingOperationType(kOperationCreateFile)); | 61 DCHECK(SetPendingOperationType(kOperationCreateFile)); |
63 GetUsageAndQuotaThenRunTask( | 62 GetUsageAndQuotaThenRunTask( |
64 url, | 63 url, |
65 base::Bind(&LocalFileSystemOperation::DoCreateFile, | 64 base::Bind(&LocalFileSystemOperation::DoCreateFile, |
66 base::Unretained(this), url, callback, exclusive), | 65 AsWeakPtr(), url, callback, exclusive), |
67 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); | 66 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); |
68 } | 67 } |
69 | 68 |
70 void LocalFileSystemOperation::CreateDirectory(const FileSystemURL& url, | 69 void LocalFileSystemOperation::CreateDirectory(const FileSystemURL& url, |
71 bool exclusive, | 70 bool exclusive, |
72 bool recursive, | 71 bool recursive, |
73 const StatusCallback& callback) { | 72 const StatusCallback& callback) { |
74 DCHECK(SetPendingOperationType(kOperationCreateDirectory)); | 73 DCHECK(SetPendingOperationType(kOperationCreateDirectory)); |
75 GetUsageAndQuotaThenRunTask( | 74 GetUsageAndQuotaThenRunTask( |
76 url, | 75 url, |
77 base::Bind(&LocalFileSystemOperation::DoCreateDirectory, | 76 base::Bind(&LocalFileSystemOperation::DoCreateDirectory, |
78 base::Unretained(this), url, callback, exclusive, recursive), | 77 AsWeakPtr(), url, callback, exclusive, recursive), |
79 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); | 78 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); |
80 } | 79 } |
81 | 80 |
82 void LocalFileSystemOperation::Copy(const FileSystemURL& src_url, | 81 void LocalFileSystemOperation::Copy(const FileSystemURL& src_url, |
83 const FileSystemURL& dest_url, | 82 const FileSystemURL& dest_url, |
84 const StatusCallback& callback) { | 83 const StatusCallback& callback) { |
85 DCHECK(SetPendingOperationType(kOperationCopy)); | 84 DCHECK(SetPendingOperationType(kOperationCopy)); |
86 DCHECK(!recursive_operation_delegate_); | 85 DCHECK(!recursive_operation_delegate_); |
87 recursive_operation_delegate_.reset( | 86 recursive_operation_delegate_.reset( |
88 new CopyOrMoveOperationDelegate( | 87 new CopyOrMoveOperationDelegate( |
89 file_system_context(), | 88 file_system_context(), |
90 src_url, dest_url, | 89 src_url, dest_url, |
91 CopyOrMoveOperationDelegate::OPERATION_COPY, | 90 CopyOrMoveOperationDelegate::OPERATION_COPY, |
92 base::Bind(&LocalFileSystemOperation::DidFinishDelegatedOperation, | 91 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
93 base::Unretained(this), callback))); | 92 AsWeakPtr(), callback))); |
94 recursive_operation_delegate_->RunRecursively(); | 93 recursive_operation_delegate_->RunRecursively(); |
95 } | 94 } |
96 | 95 |
97 void LocalFileSystemOperation::Move(const FileSystemURL& src_url, | 96 void LocalFileSystemOperation::Move(const FileSystemURL& src_url, |
98 const FileSystemURL& dest_url, | 97 const FileSystemURL& dest_url, |
99 const StatusCallback& callback) { | 98 const StatusCallback& callback) { |
100 DCHECK(SetPendingOperationType(kOperationMove)); | 99 DCHECK(SetPendingOperationType(kOperationMove)); |
101 DCHECK(!recursive_operation_delegate_); | 100 DCHECK(!recursive_operation_delegate_); |
102 recursive_operation_delegate_.reset( | 101 recursive_operation_delegate_.reset( |
103 new CopyOrMoveOperationDelegate( | 102 new CopyOrMoveOperationDelegate( |
104 file_system_context(), | 103 file_system_context(), |
105 src_url, dest_url, | 104 src_url, dest_url, |
106 CopyOrMoveOperationDelegate::OPERATION_MOVE, | 105 CopyOrMoveOperationDelegate::OPERATION_MOVE, |
107 base::Bind(&LocalFileSystemOperation::DidFinishDelegatedOperation, | 106 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
108 base::Unretained(this), callback))); | 107 AsWeakPtr(), callback))); |
109 recursive_operation_delegate_->RunRecursively(); | 108 recursive_operation_delegate_->RunRecursively(); |
110 } | 109 } |
111 | 110 |
112 void LocalFileSystemOperation::DirectoryExists(const FileSystemURL& url, | 111 void LocalFileSystemOperation::DirectoryExists(const FileSystemURL& url, |
113 const StatusCallback& callback) { | 112 const StatusCallback& callback) { |
114 DCHECK(SetPendingOperationType(kOperationDirectoryExists)); | 113 DCHECK(SetPendingOperationType(kOperationDirectoryExists)); |
115 async_file_util_->GetFileInfo( | 114 async_file_util_->GetFileInfo( |
116 operation_context(), url, | 115 operation_context_.Pass(), url, |
117 base::Bind(&LocalFileSystemOperation::DidDirectoryExists, | 116 base::Bind(&LocalFileSystemOperation::DidDirectoryExists, |
118 base::Owned(this), callback)); | 117 AsWeakPtr(), callback)); |
119 } | 118 } |
120 | 119 |
121 void LocalFileSystemOperation::FileExists(const FileSystemURL& url, | 120 void LocalFileSystemOperation::FileExists(const FileSystemURL& url, |
122 const StatusCallback& callback) { | 121 const StatusCallback& callback) { |
123 DCHECK(SetPendingOperationType(kOperationFileExists)); | 122 DCHECK(SetPendingOperationType(kOperationFileExists)); |
124 async_file_util_->GetFileInfo( | 123 async_file_util_->GetFileInfo( |
125 operation_context(), url, | 124 operation_context_.Pass(), url, |
126 base::Bind(&LocalFileSystemOperation::DidFileExists, | 125 base::Bind(&LocalFileSystemOperation::DidFileExists, |
127 base::Owned(this), callback)); | 126 AsWeakPtr(), callback)); |
128 } | 127 } |
129 | 128 |
130 void LocalFileSystemOperation::GetMetadata( | 129 void LocalFileSystemOperation::GetMetadata( |
131 const FileSystemURL& url, const GetMetadataCallback& callback) { | 130 const FileSystemURL& url, const GetMetadataCallback& callback) { |
132 DCHECK(SetPendingOperationType(kOperationGetMetadata)); | 131 DCHECK(SetPendingOperationType(kOperationGetMetadata)); |
133 async_file_util_->GetFileInfo( | 132 async_file_util_->GetFileInfo(operation_context_.Pass(), url, callback); |
134 operation_context(), url, | |
135 base::Bind(&LocalFileSystemOperation::DidGetMetadata, | |
136 base::Owned(this), callback)); | |
137 } | 133 } |
138 | 134 |
139 void LocalFileSystemOperation::ReadDirectory( | 135 void LocalFileSystemOperation::ReadDirectory( |
140 const FileSystemURL& url, const ReadDirectoryCallback& callback) { | 136 const FileSystemURL& url, const ReadDirectoryCallback& callback) { |
141 DCHECK(SetPendingOperationType(kOperationReadDirectory)); | 137 DCHECK(SetPendingOperationType(kOperationReadDirectory)); |
142 async_file_util_->ReadDirectory( | 138 async_file_util_->ReadDirectory( |
143 operation_context(), url, | 139 operation_context_.Pass(), url, callback); |
144 base::Bind(&LocalFileSystemOperation::DidReadDirectory, | |
145 base::Owned(this), callback)); | |
146 } | 140 } |
147 | 141 |
148 void LocalFileSystemOperation::Remove(const FileSystemURL& url, | 142 void LocalFileSystemOperation::Remove(const FileSystemURL& url, |
149 bool recursive, | 143 bool recursive, |
150 const StatusCallback& callback) { | 144 const StatusCallback& callback) { |
151 DCHECK(SetPendingOperationType(kOperationRemove)); | 145 DCHECK(SetPendingOperationType(kOperationRemove)); |
152 DCHECK(!recursive_operation_delegate_); | 146 DCHECK(!recursive_operation_delegate_); |
153 recursive_operation_delegate_.reset( | 147 recursive_operation_delegate_.reset( |
154 new RemoveOperationDelegate( | 148 new RemoveOperationDelegate( |
155 file_system_context(), url, | 149 file_system_context(), url, |
156 base::Bind(&LocalFileSystemOperation::DidFinishDelegatedOperation, | 150 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
157 base::Unretained(this), callback))); | 151 AsWeakPtr(), callback))); |
158 if (recursive) | 152 if (recursive) |
159 recursive_operation_delegate_->RunRecursively(); | 153 recursive_operation_delegate_->RunRecursively(); |
160 else | 154 else |
161 recursive_operation_delegate_->Run(); | 155 recursive_operation_delegate_->Run(); |
162 } | 156 } |
163 | 157 |
164 void LocalFileSystemOperation::Write( | 158 void LocalFileSystemOperation::Write( |
165 const net::URLRequestContext* url_request_context, | 159 const net::URLRequestContext* url_request_context, |
166 const FileSystemURL& url, | 160 const FileSystemURL& url, |
167 const GURL& blob_url, | 161 const GURL& blob_url, |
168 int64 offset, | 162 int64 offset, |
169 const WriteCallback& callback) { | 163 const WriteCallback& callback) { |
170 GetWriteClosure(url_request_context, url, blob_url, offset, callback).Run(); | 164 GetWriteClosure(url_request_context, url, blob_url, offset, callback).Run(); |
171 } | 165 } |
172 | 166 |
173 void LocalFileSystemOperation::Truncate(const FileSystemURL& url, int64 length, | 167 void LocalFileSystemOperation::Truncate(const FileSystemURL& url, int64 length, |
174 const StatusCallback& callback) { | 168 const StatusCallback& callback) { |
175 DCHECK(SetPendingOperationType(kOperationTruncate)); | 169 DCHECK(SetPendingOperationType(kOperationTruncate)); |
176 GetUsageAndQuotaThenRunTask( | 170 GetUsageAndQuotaThenRunTask( |
177 url, | 171 url, |
178 base::Bind(&LocalFileSystemOperation::DoTruncate, | 172 base::Bind(&LocalFileSystemOperation::DoTruncate, |
179 base::Unretained(this), url, callback, length), | 173 AsWeakPtr(), url, callback, length), |
180 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); | 174 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); |
181 } | 175 } |
182 | 176 |
183 void LocalFileSystemOperation::TouchFile(const FileSystemURL& url, | 177 void LocalFileSystemOperation::TouchFile(const FileSystemURL& url, |
184 const base::Time& last_access_time, | 178 const base::Time& last_access_time, |
185 const base::Time& last_modified_time, | 179 const base::Time& last_modified_time, |
186 const StatusCallback& callback) { | 180 const StatusCallback& callback) { |
187 DCHECK(SetPendingOperationType(kOperationTouchFile)); | 181 DCHECK(SetPendingOperationType(kOperationTouchFile)); |
188 async_file_util_->Touch( | 182 async_file_util_->Touch( |
189 operation_context(), url, | 183 operation_context_.Pass(), url, |
190 last_access_time, last_modified_time, | 184 last_access_time, last_modified_time, |
191 base::Bind(&LocalFileSystemOperation::DidTouchFile, | 185 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
192 base::Owned(this), callback)); | 186 AsWeakPtr(), callback)); |
193 } | 187 } |
194 | 188 |
195 void LocalFileSystemOperation::OpenFile(const FileSystemURL& url, | 189 void LocalFileSystemOperation::OpenFile(const FileSystemURL& url, |
196 int file_flags, | 190 int file_flags, |
197 base::ProcessHandle peer_handle, | 191 base::ProcessHandle peer_handle, |
198 const OpenFileCallback& callback) { | 192 const OpenFileCallback& callback) { |
199 DCHECK(SetPendingOperationType(kOperationOpenFile)); | 193 DCHECK(SetPendingOperationType(kOperationOpenFile)); |
200 scoped_ptr<LocalFileSystemOperation> deleter(this); | |
201 | |
202 peer_handle_ = peer_handle; | 194 peer_handle_ = peer_handle; |
203 | 195 |
204 if (file_flags & ( | 196 if (file_flags & ( |
205 (base::PLATFORM_FILE_ENUMERATE | base::PLATFORM_FILE_TEMPORARY | | 197 (base::PLATFORM_FILE_ENUMERATE | base::PLATFORM_FILE_TEMPORARY | |
206 base::PLATFORM_FILE_HIDDEN))) { | 198 base::PLATFORM_FILE_HIDDEN))) { |
207 callback.Run(base::PLATFORM_FILE_ERROR_FAILED, | 199 callback.Run(base::PLATFORM_FILE_ERROR_FAILED, |
208 base::kInvalidPlatformFileValue, | 200 base::kInvalidPlatformFileValue, |
209 base::Closure(), | 201 base::Closure(), |
210 base::kNullProcessHandle); | 202 base::kNullProcessHandle); |
211 return; | 203 return; |
212 } | 204 } |
213 GetUsageAndQuotaThenRunTask( | 205 GetUsageAndQuotaThenRunTask( |
214 url, | 206 url, |
215 base::Bind(&LocalFileSystemOperation::DoOpenFile, | 207 base::Bind(&LocalFileSystemOperation::DoOpenFile, |
216 base::Unretained(deleter.release()), | 208 AsWeakPtr(), |
217 url, callback, file_flags), | 209 url, callback, file_flags), |
218 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, | 210 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED, |
219 base::kInvalidPlatformFileValue, | 211 base::kInvalidPlatformFileValue, |
220 base::Closure(), | 212 base::Closure(), |
221 base::kNullProcessHandle)); | 213 base::kNullProcessHandle)); |
222 } | 214 } |
223 | 215 |
224 // We can only get here on a write or truncate that's not yet completed. | 216 // We can only get here on a write or truncate that's not yet completed. |
225 // We don't support cancelling any other operation at this time. | 217 // We don't support cancelling any other operation at this time. |
226 void LocalFileSystemOperation::Cancel(const StatusCallback& cancel_callback) { | 218 void LocalFileSystemOperation::Cancel(const StatusCallback& cancel_callback) { |
227 if (file_writer_delegate_) { | 219 DCHECK(cancel_callback_.is_null()); |
| 220 cancel_callback_ = cancel_callback; |
| 221 |
| 222 if (file_writer_delegate_.get()) { |
228 DCHECK_EQ(kOperationWrite, pending_operation_); | 223 DCHECK_EQ(kOperationWrite, pending_operation_); |
229 | 224 // This will call DidWrite() with ABORT status code. |
230 // Writes are done without proxying through FileUtilProxy after the initial | 225 file_writer_delegate_->Cancel(); |
231 // opening of the PlatformFile. All state changes are done on this thread, | |
232 // so we're guaranteed to be able to shut down atomically. | |
233 const bool delete_now = file_writer_delegate_->Cancel(); | |
234 | |
235 if (!write_callback_.is_null()) { | |
236 // Notify the failure status to the ongoing operation's callback. | |
237 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, false); | |
238 } | |
239 cancel_callback.Run(base::PLATFORM_FILE_OK); | |
240 write_callback_.Reset(); | |
241 | |
242 if (delete_now) { | |
243 delete this; | |
244 return; | |
245 } | |
246 } else { | 226 } else { |
| 227 // For truncate we have no way to cancel the inflight operation (for now). |
| 228 // Let it just run and dispatch cancel callback later. |
247 DCHECK_EQ(kOperationTruncate, pending_operation_); | 229 DCHECK_EQ(kOperationTruncate, pending_operation_); |
248 // We're cancelling a truncate operation, but we can't actually stop it | |
249 // since it's been proxied to another thread. We need to save the | |
250 // cancel_callback so that when the truncate returns, it can see that it's | |
251 // been cancelled, report it, and report that the cancel has succeeded. | |
252 DCHECK(cancel_callback_.is_null()); | |
253 cancel_callback_ = cancel_callback; | |
254 } | 230 } |
255 } | 231 } |
256 | 232 |
257 LocalFileSystemOperation* | 233 LocalFileSystemOperation* |
258 LocalFileSystemOperation::AsLocalFileSystemOperation() { | 234 LocalFileSystemOperation::AsLocalFileSystemOperation() { |
259 return this; | 235 return this; |
260 } | 236 } |
261 | 237 |
262 void LocalFileSystemOperation::SyncGetPlatformPath(const FileSystemURL& url, | 238 void LocalFileSystemOperation::SyncGetPlatformPath( |
263 base::FilePath* platform_path
) { | 239 const FileSystemURL& url, |
| 240 base::FilePath* platform_path) { |
264 DCHECK(SetPendingOperationType(kOperationGetLocalPath)); | 241 DCHECK(SetPendingOperationType(kOperationGetLocalPath)); |
265 FileSystemFileUtil* file_util = file_system_context()->GetFileUtil( | 242 FileSystemFileUtil* file_util = file_system_context()->GetFileUtil( |
266 url.type()); | 243 url.type()); |
267 DCHECK(file_util); | 244 DCHECK(file_util); |
268 file_util->GetLocalFilePath(operation_context(), url, platform_path); | 245 file_util->GetLocalFilePath(operation_context_.get(), url, platform_path); |
269 | |
270 delete this; | |
271 } | 246 } |
272 | 247 |
273 void LocalFileSystemOperation::CreateSnapshotFile( | 248 void LocalFileSystemOperation::CreateSnapshotFile( |
274 const FileSystemURL& url, | 249 const FileSystemURL& url, |
275 const SnapshotFileCallback& callback) { | 250 const SnapshotFileCallback& callback) { |
276 DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile)); | 251 DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile)); |
277 async_file_util_->CreateSnapshotFile( | 252 async_file_util_->CreateSnapshotFile( |
278 operation_context(), url, | 253 operation_context_.Pass(), url, callback); |
279 base::Bind(&LocalFileSystemOperation::DidCreateSnapshotFile, | |
280 base::Owned(this), callback)); | |
281 } | 254 } |
282 | 255 |
283 void LocalFileSystemOperation::CopyInForeignFile( | 256 void LocalFileSystemOperation::CopyInForeignFile( |
284 const base::FilePath& src_local_disk_file_path, | 257 const base::FilePath& src_local_disk_file_path, |
285 const FileSystemURL& dest_url, | 258 const FileSystemURL& dest_url, |
286 const StatusCallback& callback) { | 259 const StatusCallback& callback) { |
287 DCHECK(SetPendingOperationType(kOperationCopyInForeignFile)); | 260 DCHECK(SetPendingOperationType(kOperationCopyInForeignFile)); |
288 GetUsageAndQuotaThenRunTask( | 261 GetUsageAndQuotaThenRunTask( |
289 dest_url, | 262 dest_url, |
290 base::Bind(&LocalFileSystemOperation::DoCopyInForeignFile, | 263 base::Bind(&LocalFileSystemOperation::DoCopyInForeignFile, |
291 base::Unretained(this), src_local_disk_file_path, dest_url, | 264 AsWeakPtr(), src_local_disk_file_path, dest_url, |
292 callback), | 265 callback), |
293 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); | 266 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); |
294 } | 267 } |
295 | 268 |
296 void LocalFileSystemOperation::RemoveFile( | 269 void LocalFileSystemOperation::RemoveFile( |
297 const FileSystemURL& url, | 270 const FileSystemURL& url, |
298 const StatusCallback& callback) { | 271 const StatusCallback& callback) { |
299 DCHECK(SetPendingOperationType(kOperationRemove)); | 272 DCHECK(SetPendingOperationType(kOperationRemove)); |
300 async_file_util_->DeleteFile( | 273 async_file_util_->DeleteFile( |
301 operation_context(), url, | 274 operation_context_.Pass(), url, |
302 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 275 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
303 base::Owned(this), callback)); | 276 AsWeakPtr(), callback)); |
304 } | 277 } |
305 | 278 |
306 void LocalFileSystemOperation::RemoveDirectory( | 279 void LocalFileSystemOperation::RemoveDirectory( |
307 const FileSystemURL& url, | 280 const FileSystemURL& url, |
308 const StatusCallback& callback) { | 281 const StatusCallback& callback) { |
309 DCHECK(SetPendingOperationType(kOperationRemove)); | 282 DCHECK(SetPendingOperationType(kOperationRemove)); |
310 async_file_util_->DeleteDirectory( | 283 async_file_util_->DeleteDirectory( |
311 operation_context(), url, | 284 operation_context_.Pass(), url, |
312 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 285 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
313 base::Owned(this), callback)); | 286 AsWeakPtr(), callback)); |
314 } | 287 } |
315 | 288 |
316 void LocalFileSystemOperation::CopyFileLocal( | 289 void LocalFileSystemOperation::CopyFileLocal( |
317 const FileSystemURL& src_url, | 290 const FileSystemURL& src_url, |
318 const FileSystemURL& dest_url, | 291 const FileSystemURL& dest_url, |
319 const StatusCallback& callback) { | 292 const StatusCallback& callback) { |
320 DCHECK(SetPendingOperationType(kOperationCopy)); | 293 DCHECK(SetPendingOperationType(kOperationCopy)); |
321 DCHECK(src_url.IsInSameFileSystem(dest_url)); | 294 DCHECK(src_url.IsInSameFileSystem(dest_url)); |
322 GetUsageAndQuotaThenRunTask( | 295 GetUsageAndQuotaThenRunTask( |
323 dest_url, | 296 dest_url, |
324 base::Bind(&LocalFileSystemOperation::DoCopyFileLocal, | 297 base::Bind(&LocalFileSystemOperation::DoCopyFileLocal, |
325 base::Unretained(this), src_url, dest_url, callback), | 298 AsWeakPtr(), src_url, dest_url, callback), |
326 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); | 299 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); |
327 } | 300 } |
328 | 301 |
329 void LocalFileSystemOperation::MoveFileLocal( | 302 void LocalFileSystemOperation::MoveFileLocal( |
330 const FileSystemURL& src_url, | 303 const FileSystemURL& src_url, |
331 const FileSystemURL& dest_url, | 304 const FileSystemURL& dest_url, |
332 const StatusCallback& callback) { | 305 const StatusCallback& callback) { |
333 DCHECK(SetPendingOperationType(kOperationMove)); | 306 DCHECK(SetPendingOperationType(kOperationMove)); |
334 DCHECK(src_url.IsInSameFileSystem(dest_url)); | 307 DCHECK(src_url.IsInSameFileSystem(dest_url)); |
335 GetUsageAndQuotaThenRunTask( | 308 GetUsageAndQuotaThenRunTask( |
336 dest_url, | 309 dest_url, |
337 base::Bind(&LocalFileSystemOperation::DoMoveFileLocal, | 310 base::Bind(&LocalFileSystemOperation::DoMoveFileLocal, |
338 base::Unretained(this), src_url, dest_url, callback), | 311 AsWeakPtr(), src_url, dest_url, callback), |
339 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); | 312 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); |
340 } | 313 } |
341 | 314 |
342 void LocalFileSystemOperation::GetUsageAndQuotaThenRunTask( | 315 void LocalFileSystemOperation::GetUsageAndQuotaThenRunTask( |
343 const FileSystemURL& url, | 316 const FileSystemURL& url, |
344 const base::Closure& task, | 317 const base::Closure& task, |
345 const base::Closure& error_callback) { | 318 const base::Closure& error_callback) { |
346 quota::QuotaManagerProxy* quota_manager_proxy = | 319 quota::QuotaManagerProxy* quota_manager_proxy = |
347 file_system_context()->quota_manager_proxy(); | 320 file_system_context()->quota_manager_proxy(); |
348 if (!quota_manager_proxy || | 321 if (!quota_manager_proxy || |
349 !file_system_context()->GetQuotaUtil(url.type())) { | 322 !file_system_context()->GetQuotaUtil(url.type())) { |
350 // If we don't have the quota manager or the requested filesystem type | 323 // If we don't have the quota manager or the requested filesystem type |
351 // does not support quota, we should be able to let it go. | 324 // does not support quota, we should be able to let it go. |
352 operation_context()->set_allowed_bytes_growth(kint64max); | 325 operation_context_->set_allowed_bytes_growth(kint64max); |
353 task.Run(); | 326 task.Run(); |
354 return; | 327 return; |
355 } | 328 } |
356 | 329 |
357 DCHECK(quota_manager_proxy); | 330 DCHECK(quota_manager_proxy); |
358 DCHECK(quota_manager_proxy->quota_manager()); | 331 DCHECK(quota_manager_proxy->quota_manager()); |
359 quota_manager_proxy->quota_manager()->GetUsageAndQuota( | 332 quota_manager_proxy->quota_manager()->GetUsageAndQuota( |
360 url.origin(), | 333 url.origin(), |
361 FileSystemTypeToQuotaStorageType(url.type()), | 334 FileSystemTypeToQuotaStorageType(url.type()), |
362 base::Bind(&LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask, | 335 base::Bind(&LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask, |
363 weak_factory_.GetWeakPtr(), task, error_callback)); | 336 AsWeakPtr(), task, error_callback)); |
364 } | 337 } |
365 | 338 |
366 void LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask( | 339 void LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask( |
367 const base::Closure& task, | 340 const base::Closure& task, |
368 const base::Closure& error_callback, | 341 const base::Closure& error_callback, |
369 quota::QuotaStatusCode status, | 342 quota::QuotaStatusCode status, |
370 int64 usage, int64 quota) { | 343 int64 usage, int64 quota) { |
371 if (status != quota::kQuotaStatusOk) { | 344 if (status != quota::kQuotaStatusOk) { |
372 LOG(WARNING) << "Got unexpected quota error : " << status; | 345 LOG(WARNING) << "Got unexpected quota error : " << status; |
373 error_callback.Run(); | 346 error_callback.Run(); |
374 return; | 347 return; |
375 } | 348 } |
376 | 349 |
377 operation_context()->set_allowed_bytes_growth(quota - usage); | 350 operation_context_->set_allowed_bytes_growth(quota - usage); |
378 task.Run(); | 351 task.Run(); |
379 } | 352 } |
380 | 353 |
381 base::Closure LocalFileSystemOperation::GetWriteClosure( | 354 base::Closure LocalFileSystemOperation::GetWriteClosure( |
382 const net::URLRequestContext* url_request_context, | 355 const net::URLRequestContext* url_request_context, |
383 const FileSystemURL& url, | 356 const FileSystemURL& url, |
384 const GURL& blob_url, | 357 const GURL& blob_url, |
385 int64 offset, | 358 int64 offset, |
386 const WriteCallback& callback) { | 359 const WriteCallback& callback) { |
387 DCHECK(SetPendingOperationType(kOperationWrite)); | 360 DCHECK(SetPendingOperationType(kOperationWrite)); |
388 scoped_ptr<FileStreamWriter> writer( | 361 scoped_ptr<FileStreamWriter> writer( |
389 file_system_context()->CreateFileStreamWriter(url, offset)); | 362 file_system_context()->CreateFileStreamWriter(url, offset)); |
390 | 363 |
391 if (!writer) { | 364 if (!writer) { |
392 // Write is not supported. | 365 // Write is not supported. |
393 return base::Bind(&LocalFileSystemOperation::DidFailWrite, | 366 return base::Bind(&LocalFileSystemOperation::DidFailWrite, |
394 base::Owned(this), callback, | 367 AsWeakPtr(), callback, |
395 base::PLATFORM_FILE_ERROR_SECURITY); | 368 base::PLATFORM_FILE_ERROR_SECURITY); |
396 } | 369 } |
397 | 370 |
398 DCHECK(blob_url.is_valid()); | 371 DCHECK(blob_url.is_valid()); |
399 file_writer_delegate_.reset(new FileWriterDelegate( | 372 file_writer_delegate_.reset(new FileWriterDelegate( |
400 base::Bind(&LocalFileSystemOperation::DidWrite, | 373 base::Bind(&LocalFileSystemOperation::DidWrite, AsWeakPtr(), |
401 weak_factory_.GetWeakPtr(), url), | 374 url, callback), |
402 writer.Pass())); | 375 writer.Pass())); |
403 | 376 |
404 write_callback_ = callback; | |
405 scoped_ptr<net::URLRequest> blob_request(url_request_context->CreateRequest( | 377 scoped_ptr<net::URLRequest> blob_request(url_request_context->CreateRequest( |
406 blob_url, file_writer_delegate_.get())); | 378 blob_url, file_writer_delegate_.get())); |
407 | 379 |
408 return base::Bind(&FileWriterDelegate::Start, | 380 return base::Bind(&FileWriterDelegate::Start, |
409 base::Unretained(file_writer_delegate_.get()), | 381 base::Unretained(file_writer_delegate_.get()), |
410 base::Passed(&blob_request)); | 382 base::Passed(&blob_request)); |
411 } | 383 } |
412 | 384 |
413 void LocalFileSystemOperation::DidFailWrite( | 385 void LocalFileSystemOperation::DidFailWrite( |
414 const WriteCallback& callback, | 386 const WriteCallback& callback, |
415 base::PlatformFileError result) { | 387 base::PlatformFileError result) { |
416 callback.Run(result, 0, false); | 388 callback.Run(result, 0, false); |
417 } | 389 } |
418 | 390 |
419 void LocalFileSystemOperation::DoCreateFile( | 391 void LocalFileSystemOperation::DoCreateFile( |
420 const FileSystemURL& url, | 392 const FileSystemURL& url, |
421 const StatusCallback& callback, | 393 const StatusCallback& callback, |
422 bool exclusive) { | 394 bool exclusive) { |
423 async_file_util_->EnsureFileExists( | 395 async_file_util_->EnsureFileExists( |
424 operation_context(), url, | 396 operation_context_.Pass(), url, |
425 base::Bind( | 397 base::Bind( |
426 exclusive ? | 398 exclusive ? |
427 &LocalFileSystemOperation::DidEnsureFileExistsExclusive : | 399 &LocalFileSystemOperation::DidEnsureFileExistsExclusive : |
428 &LocalFileSystemOperation::DidEnsureFileExistsNonExclusive, | 400 &LocalFileSystemOperation::DidEnsureFileExistsNonExclusive, |
429 base::Owned(this), callback)); | 401 AsWeakPtr(), callback)); |
430 } | 402 } |
431 | 403 |
432 void LocalFileSystemOperation::DoCreateDirectory( | 404 void LocalFileSystemOperation::DoCreateDirectory( |
433 const FileSystemURL& url, | 405 const FileSystemURL& url, |
434 const StatusCallback& callback, | 406 const StatusCallback& callback, |
435 bool exclusive, bool recursive) { | 407 bool exclusive, bool recursive) { |
436 async_file_util_->CreateDirectory( | 408 async_file_util_->CreateDirectory( |
437 operation_context(), | 409 operation_context_.Pass(), |
438 url, exclusive, recursive, | 410 url, exclusive, recursive, |
439 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 411 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
440 base::Owned(this), callback)); | 412 AsWeakPtr(), callback)); |
441 } | 413 } |
442 | 414 |
443 void LocalFileSystemOperation::DoCopyFileLocal( | 415 void LocalFileSystemOperation::DoCopyFileLocal( |
444 const FileSystemURL& src_url, | 416 const FileSystemURL& src_url, |
445 const FileSystemURL& dest_url, | 417 const FileSystemURL& dest_url, |
446 const StatusCallback& callback) { | 418 const StatusCallback& callback) { |
447 async_file_util_->CopyFileLocal( | 419 async_file_util_->CopyFileLocal( |
448 operation_context(), src_url, dest_url, | 420 operation_context_.Pass(), src_url, dest_url, |
449 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 421 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
450 base::Owned(this), callback)); | 422 AsWeakPtr(), callback)); |
451 } | 423 } |
452 | 424 |
453 void LocalFileSystemOperation::DoMoveFileLocal( | 425 void LocalFileSystemOperation::DoMoveFileLocal( |
454 const FileSystemURL& src_url, | 426 const FileSystemURL& src_url, |
455 const FileSystemURL& dest_url, | 427 const FileSystemURL& dest_url, |
456 const StatusCallback& callback) { | 428 const StatusCallback& callback) { |
457 async_file_util_->MoveFileLocal( | 429 async_file_util_->MoveFileLocal( |
458 operation_context(), src_url, dest_url, | 430 operation_context_.Pass(), src_url, dest_url, |
459 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 431 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
460 base::Owned(this), callback)); | 432 AsWeakPtr(), callback)); |
461 } | 433 } |
462 | 434 |
463 void LocalFileSystemOperation::DoCopyInForeignFile( | 435 void LocalFileSystemOperation::DoCopyInForeignFile( |
464 const base::FilePath& src_local_disk_file_path, | 436 const base::FilePath& src_local_disk_file_path, |
465 const FileSystemURL& dest_url, | 437 const FileSystemURL& dest_url, |
466 const StatusCallback& callback) { | 438 const StatusCallback& callback) { |
467 async_file_util_->CopyInForeignFile( | 439 async_file_util_->CopyInForeignFile( |
468 operation_context(), | 440 operation_context_.Pass(), |
469 src_local_disk_file_path, dest_url, | 441 src_local_disk_file_path, dest_url, |
470 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 442 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
471 base::Owned(this), callback)); | 443 AsWeakPtr(), callback)); |
472 } | 444 } |
473 | 445 |
474 void LocalFileSystemOperation::DoTruncate(const FileSystemURL& url, | 446 void LocalFileSystemOperation::DoTruncate(const FileSystemURL& url, |
475 const StatusCallback& callback, | 447 const StatusCallback& callback, |
476 int64 length) { | 448 int64 length) { |
477 async_file_util_->Truncate( | 449 async_file_util_->Truncate( |
478 operation_context(), url, length, | 450 operation_context_.Pass(), url, length, |
479 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 451 base::Bind(&LocalFileSystemOperation::DidFinishOperation, |
480 base::Owned(this), callback)); | 452 AsWeakPtr(), callback)); |
481 } | 453 } |
482 | 454 |
483 void LocalFileSystemOperation::DoOpenFile(const FileSystemURL& url, | 455 void LocalFileSystemOperation::DoOpenFile(const FileSystemURL& url, |
484 const OpenFileCallback& callback, | 456 const OpenFileCallback& callback, |
485 int file_flags) { | 457 int file_flags) { |
486 async_file_util_->CreateOrOpen( | 458 async_file_util_->CreateOrOpen( |
487 operation_context(), url, file_flags, | 459 operation_context_.Pass(), url, file_flags, |
488 base::Bind(&LocalFileSystemOperation::DidOpenFile, | 460 base::Bind(&LocalFileSystemOperation::DidOpenFile, |
489 base::Owned(this), callback)); | 461 AsWeakPtr(), callback)); |
490 } | 462 } |
491 | 463 |
492 void LocalFileSystemOperation::DidEnsureFileExistsExclusive( | 464 void LocalFileSystemOperation::DidEnsureFileExistsExclusive( |
493 const StatusCallback& callback, | 465 const StatusCallback& callback, |
494 base::PlatformFileError rv, bool created) { | 466 base::PlatformFileError rv, bool created) { |
495 if (rv == base::PLATFORM_FILE_OK && !created) { | 467 if (rv == base::PLATFORM_FILE_OK && !created) { |
496 callback.Run(base::PLATFORM_FILE_ERROR_EXISTS); | 468 callback.Run(base::PLATFORM_FILE_ERROR_EXISTS); |
497 } else { | 469 } else { |
498 DidFinishFileOperation(callback, rv); | 470 DidFinishOperation(callback, rv); |
499 } | 471 } |
500 } | 472 } |
501 | 473 |
502 void LocalFileSystemOperation::DidEnsureFileExistsNonExclusive( | 474 void LocalFileSystemOperation::DidEnsureFileExistsNonExclusive( |
503 const StatusCallback& callback, | 475 const StatusCallback& callback, |
504 base::PlatformFileError rv, bool /* created */) { | 476 base::PlatformFileError rv, bool /* created */) { |
505 DidFinishFileOperation(callback, rv); | 477 DidFinishOperation(callback, rv); |
506 } | 478 } |
507 | 479 |
508 void LocalFileSystemOperation::DidFinishFileOperation( | 480 void LocalFileSystemOperation::DidFinishOperation( |
509 const StatusCallback& callback, | 481 const StatusCallback& callback, |
510 base::PlatformFileError rv) { | 482 base::PlatformFileError rv) { |
511 if (!cancel_callback_.is_null()) { | 483 if (!cancel_callback_.is_null()) { |
512 DCHECK_EQ(kOperationTruncate, pending_operation_); | 484 DCHECK_EQ(kOperationTruncate, pending_operation_); |
513 | 485 |
| 486 StatusCallback cancel_callback = cancel_callback_; |
514 callback.Run(base::PLATFORM_FILE_ERROR_ABORT); | 487 callback.Run(base::PLATFORM_FILE_ERROR_ABORT); |
515 cancel_callback_.Run(base::PLATFORM_FILE_OK); | 488 cancel_callback.Run(base::PLATFORM_FILE_OK); |
516 cancel_callback_.Reset(); | |
517 } else { | 489 } else { |
518 callback.Run(rv); | 490 callback.Run(rv); |
519 } | 491 } |
520 } | 492 } |
521 | 493 |
522 void LocalFileSystemOperation::DidFinishDelegatedOperation( | |
523 const StatusCallback& callback, | |
524 base::PlatformFileError rv) { | |
525 // The callback might be held by the delegate and Owned() may not work, | |
526 // so just explicitly delete this now. | |
527 callback.Run(rv); | |
528 delete this; | |
529 } | |
530 | |
531 void LocalFileSystemOperation::DidDirectoryExists( | 494 void LocalFileSystemOperation::DidDirectoryExists( |
532 const StatusCallback& callback, | 495 const StatusCallback& callback, |
533 base::PlatformFileError rv, | 496 base::PlatformFileError rv, |
534 const base::PlatformFileInfo& file_info, | 497 const base::PlatformFileInfo& file_info, |
535 const base::FilePath& unused) { | 498 const base::FilePath& unused) { |
536 if (rv == base::PLATFORM_FILE_OK && !file_info.is_directory) | 499 if (rv == base::PLATFORM_FILE_OK && !file_info.is_directory) |
537 rv = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | 500 rv = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
538 callback.Run(rv); | 501 callback.Run(rv); |
539 } | 502 } |
540 | 503 |
541 void LocalFileSystemOperation::DidFileExists( | 504 void LocalFileSystemOperation::DidFileExists( |
542 const StatusCallback& callback, | 505 const StatusCallback& callback, |
543 base::PlatformFileError rv, | 506 base::PlatformFileError rv, |
544 const base::PlatformFileInfo& file_info, | 507 const base::PlatformFileInfo& file_info, |
545 const base::FilePath& unused) { | 508 const base::FilePath& unused) { |
546 if (rv == base::PLATFORM_FILE_OK && file_info.is_directory) | 509 if (rv == base::PLATFORM_FILE_OK && file_info.is_directory) |
547 rv = base::PLATFORM_FILE_ERROR_NOT_A_FILE; | 510 rv = base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
548 callback.Run(rv); | 511 callback.Run(rv); |
549 } | 512 } |
550 | 513 |
551 void LocalFileSystemOperation::DidGetMetadata( | |
552 const GetMetadataCallback& callback, | |
553 base::PlatformFileError rv, | |
554 const base::PlatformFileInfo& file_info, | |
555 const base::FilePath& platform_path) { | |
556 callback.Run(rv, file_info, platform_path); | |
557 } | |
558 | |
559 void LocalFileSystemOperation::DidReadDirectory( | |
560 const ReadDirectoryCallback& callback, | |
561 base::PlatformFileError rv, | |
562 const std::vector<DirectoryEntry>& entries, | |
563 bool has_more) { | |
564 callback.Run(rv, entries, has_more); | |
565 } | |
566 | |
567 void LocalFileSystemOperation::DidWrite( | 514 void LocalFileSystemOperation::DidWrite( |
568 const FileSystemURL& url, | 515 const FileSystemURL& url, |
| 516 const WriteCallback& write_callback, |
569 base::PlatformFileError rv, | 517 base::PlatformFileError rv, |
570 int64 bytes, | 518 int64 bytes, |
571 FileWriterDelegate::WriteProgressStatus write_status) { | 519 FileWriterDelegate::WriteProgressStatus write_status) { |
572 if (write_callback_.is_null()) { | |
573 // If cancelled, callback is already invoked and set to null in Cancel(). | |
574 // We must not call it twice. Just shut down this operation object. | |
575 delete this; | |
576 return; | |
577 } | |
578 | |
579 const bool complete = ( | 520 const bool complete = ( |
580 write_status != FileWriterDelegate::SUCCESS_IO_PENDING); | 521 write_status != FileWriterDelegate::SUCCESS_IO_PENDING); |
581 if (complete && write_status != FileWriterDelegate::ERROR_WRITE_NOT_STARTED) { | 522 if (complete && write_status != FileWriterDelegate::ERROR_WRITE_NOT_STARTED) { |
582 operation_context()->change_observers()->Notify( | 523 DCHECK(operation_context_); |
| 524 operation_context_->change_observers()->Notify( |
583 &FileChangeObserver::OnModifyFile, MakeTuple(url)); | 525 &FileChangeObserver::OnModifyFile, MakeTuple(url)); |
584 } | 526 } |
585 | 527 |
586 write_callback_.Run(rv, bytes, complete); | 528 StatusCallback cancel_callback = cancel_callback_; |
587 if (complete || rv != base::PLATFORM_FILE_OK) | 529 write_callback.Run(rv, bytes, complete); |
588 delete this; | 530 if (!cancel_callback.is_null()) |
589 } | 531 cancel_callback.Run(base::PLATFORM_FILE_OK); |
590 | |
591 void LocalFileSystemOperation::DidTouchFile(const StatusCallback& callback, | |
592 base::PlatformFileError rv) { | |
593 callback.Run(rv); | |
594 } | 532 } |
595 | 533 |
596 void LocalFileSystemOperation::DidOpenFile( | 534 void LocalFileSystemOperation::DidOpenFile( |
597 const OpenFileCallback& callback, | 535 const OpenFileCallback& callback, |
598 base::PlatformFileError rv, | 536 base::PlatformFileError rv, |
599 base::PassPlatformFile file, | 537 base::PassPlatformFile file, |
600 bool unused) { | 538 bool unused) { |
601 if (rv == base::PLATFORM_FILE_OK) | 539 if (rv == base::PLATFORM_FILE_OK) |
602 CHECK_NE(base::kNullProcessHandle, peer_handle_); | 540 CHECK_NE(base::kNullProcessHandle, peer_handle_); |
603 callback.Run(rv, file.ReleaseValue(), | 541 callback.Run(rv, file.ReleaseValue(), |
604 base::Bind(&NopCloseFileCallback), | 542 base::Bind(&NopCloseFileCallback), |
605 peer_handle_); | 543 peer_handle_); |
606 } | 544 } |
607 | 545 |
608 void LocalFileSystemOperation::DidCreateSnapshotFile( | |
609 const SnapshotFileCallback& callback, | |
610 base::PlatformFileError result, | |
611 const base::PlatformFileInfo& file_info, | |
612 const base::FilePath& platform_path, | |
613 const scoped_refptr<ShareableFileReference>& file_ref) { | |
614 callback.Run(result, file_info, platform_path, file_ref); | |
615 } | |
616 | |
617 bool LocalFileSystemOperation::SetPendingOperationType(OperationType type) { | 546 bool LocalFileSystemOperation::SetPendingOperationType(OperationType type) { |
618 if (pending_operation_ != kOperationNone) | 547 if (pending_operation_ != kOperationNone) |
619 return false; | 548 return false; |
620 pending_operation_ = type; | 549 pending_operation_ = type; |
621 return true; | 550 return true; |
622 } | 551 } |
623 | 552 |
624 } // namespace fileapi | 553 } // namespace fileapi |
OLD | NEW |