blob: d552a78319342df4560ac2bd517e8c7a63081c09 [file] [log] [blame]
[email protected]6fb92642013-06-05 13:05:161// Copyright 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/browser/fileapi/file_system_operation_runner.h"
6
7#include "base/bind.h"
[email protected]33f5a4e2013-09-05 11:24:198#include "base/message_loop/message_loop_proxy.h"
9#include "base/stl_util.h"
[email protected]1a6e3902013-06-13 07:09:4010#include "net/url_request/url_request_context.h"
[email protected]84388892013-09-07 04:20:1811#include "webkit/browser/blob/blob_url_request_job_factory.h"
[email protected]5dfa47c2013-06-10 04:57:1512#include "webkit/browser/fileapi/file_observers.h"
[email protected]1a6e3902013-06-13 07:09:4013#include "webkit/browser/fileapi/file_stream_writer.h"
[email protected]6fb92642013-06-05 13:05:1614#include "webkit/browser/fileapi/file_system_context.h"
[email protected]bd69f572013-09-09 06:15:2315#include "webkit/browser/fileapi/file_system_operation.h"
[email protected]1a6e3902013-06-13 07:09:4016#include "webkit/browser/fileapi/file_writer_delegate.h"
[email protected]6fb92642013-06-05 13:05:1617#include "webkit/common/blob/shareable_file_reference.h"
18
19namespace fileapi {
20
21typedef FileSystemOperationRunner::OperationID OperationID;
22
[email protected]33f5a4e2013-09-05 11:24:1923class FileSystemOperationRunner::BeginOperationScoper
24 : public base::SupportsWeakPtr<
25 FileSystemOperationRunner::BeginOperationScoper> {
26 public:
27 BeginOperationScoper() {}
28 private:
29 DISALLOW_COPY_AND_ASSIGN(BeginOperationScoper);
30};
31
32FileSystemOperationRunner::OperationHandle::OperationHandle() {}
33FileSystemOperationRunner::OperationHandle::~OperationHandle() {}
[email protected]6fb92642013-06-05 13:05:1634
35FileSystemOperationRunner::~FileSystemOperationRunner() {
36}
37
[email protected]2c02c8d2013-06-10 17:52:4338void FileSystemOperationRunner::Shutdown() {
39 operations_.Clear();
40}
41
[email protected]6fb92642013-06-05 13:05:1642OperationID FileSystemOperationRunner::CreateFile(
43 const FileSystemURL& url,
44 bool exclusive,
45 const StatusCallback& callback) {
46 base::PlatformFileError error = base::PLATFORM_FILE_OK;
47 FileSystemOperation* operation =
48 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:1949
50 BeginOperationScoper scope;
51 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:1652 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:1953 DidFinish(handle, callback, error);
54 return handle.id;
[email protected]6fb92642013-06-05 13:05:1655 }
[email protected]33f5a4e2013-09-05 11:24:1956 PrepareForWrite(handle.id, url);
[email protected]6fb92642013-06-05 13:05:1657 operation->CreateFile(
58 url, exclusive,
59 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:1960 handle, callback));
61 return handle.id;
[email protected]6fb92642013-06-05 13:05:1662}
63
64OperationID FileSystemOperationRunner::CreateDirectory(
65 const FileSystemURL& url,
66 bool exclusive,
67 bool recursive,
68 const StatusCallback& callback) {
69 base::PlatformFileError error = base::PLATFORM_FILE_OK;
70 FileSystemOperation* operation =
71 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:1972 BeginOperationScoper scope;
73 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:1674 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:1975 DidFinish(handle, callback, error);
76 return handle.id;
[email protected]6fb92642013-06-05 13:05:1677 }
[email protected]33f5a4e2013-09-05 11:24:1978 PrepareForWrite(handle.id, url);
[email protected]6fb92642013-06-05 13:05:1679 operation->CreateDirectory(
80 url, exclusive, recursive,
81 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:1982 handle, callback));
83 return handle.id;
[email protected]6fb92642013-06-05 13:05:1684}
85
86OperationID FileSystemOperationRunner::Copy(
87 const FileSystemURL& src_url,
88 const FileSystemURL& dest_url,
[email protected]824d3892013-09-25 13:00:3089 CopyOrMoveOption option,
[email protected]af349562013-09-09 14:18:5390 const CopyProgressCallback& progress_callback,
[email protected]6fb92642013-06-05 13:05:1691 const StatusCallback& callback) {
92 base::PlatformFileError error = base::PLATFORM_FILE_OK;
93 FileSystemOperation* operation =
94 file_system_context_->CreateFileSystemOperation(dest_url, &error);
[email protected]33f5a4e2013-09-05 11:24:1995 BeginOperationScoper scope;
96 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:1697 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:1998 DidFinish(handle, callback, error);
99 return handle.id;
[email protected]6fb92642013-06-05 13:05:16100 }
[email protected]33f5a4e2013-09-05 11:24:19101 PrepareForWrite(handle.id, dest_url);
102 PrepareForRead(handle.id, src_url);
[email protected]6fb92642013-06-05 13:05:16103 operation->Copy(
[email protected]824d3892013-09-25 13:00:30104 src_url, dest_url, option,
[email protected]d3072432013-09-12 17:39:29105 progress_callback.is_null() ?
106 CopyProgressCallback() :
107 base::Bind(&FileSystemOperationRunner::OnCopyProgress, AsWeakPtr(),
108 handle, progress_callback),
[email protected]6fb92642013-06-05 13:05:16109 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19110 handle, callback));
111 return handle.id;
[email protected]6fb92642013-06-05 13:05:16112}
113
114OperationID FileSystemOperationRunner::Move(
115 const FileSystemURL& src_url,
116 const FileSystemURL& dest_url,
[email protected]824d3892013-09-25 13:00:30117 CopyOrMoveOption option,
[email protected]6fb92642013-06-05 13:05:16118 const StatusCallback& callback) {
119 base::PlatformFileError error = base::PLATFORM_FILE_OK;
120 FileSystemOperation* operation =
121 file_system_context_->CreateFileSystemOperation(dest_url, &error);
[email protected]33f5a4e2013-09-05 11:24:19122 BeginOperationScoper scope;
123 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16124 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19125 DidFinish(handle, callback, error);
126 return handle.id;
[email protected]6fb92642013-06-05 13:05:16127 }
[email protected]33f5a4e2013-09-05 11:24:19128 PrepareForWrite(handle.id, dest_url);
129 PrepareForWrite(handle.id, src_url);
[email protected]6fb92642013-06-05 13:05:16130 operation->Move(
[email protected]824d3892013-09-25 13:00:30131 src_url, dest_url, option,
[email protected]6fb92642013-06-05 13:05:16132 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19133 handle, callback));
134 return handle.id;
[email protected]6fb92642013-06-05 13:05:16135}
136
137OperationID FileSystemOperationRunner::DirectoryExists(
138 const FileSystemURL& url,
139 const StatusCallback& callback) {
140 base::PlatformFileError error = base::PLATFORM_FILE_OK;
141 FileSystemOperation* operation =
142 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19143 BeginOperationScoper scope;
144 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16145 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19146 DidFinish(handle, callback, error);
147 return handle.id;
[email protected]6fb92642013-06-05 13:05:16148 }
[email protected]33f5a4e2013-09-05 11:24:19149 PrepareForRead(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16150 operation->DirectoryExists(
151 url,
152 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19153 handle, callback));
154 return handle.id;
[email protected]6fb92642013-06-05 13:05:16155}
156
157OperationID FileSystemOperationRunner::FileExists(
158 const FileSystemURL& url,
159 const StatusCallback& callback) {
160 base::PlatformFileError error = base::PLATFORM_FILE_OK;
161 FileSystemOperation* operation =
162 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19163 BeginOperationScoper scope;
164 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16165 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19166 DidFinish(handle, callback, error);
167 return handle.id;
[email protected]6fb92642013-06-05 13:05:16168 }
[email protected]33f5a4e2013-09-05 11:24:19169 PrepareForRead(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16170 operation->FileExists(
171 url,
172 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19173 handle, callback));
174 return handle.id;
[email protected]6fb92642013-06-05 13:05:16175}
176
177OperationID FileSystemOperationRunner::GetMetadata(
178 const FileSystemURL& url,
179 const GetMetadataCallback& callback) {
180 base::PlatformFileError error = base::PLATFORM_FILE_OK;
181 FileSystemOperation* operation =
182 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19183 BeginOperationScoper scope;
184 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16185 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19186 DidGetMetadata(handle, callback, error, base::PlatformFileInfo());
187 return handle.id;
[email protected]6fb92642013-06-05 13:05:16188 }
[email protected]33f5a4e2013-09-05 11:24:19189 PrepareForRead(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16190 operation->GetMetadata(
191 url,
192 base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19193 handle, callback));
194 return handle.id;
[email protected]6fb92642013-06-05 13:05:16195}
196
197OperationID FileSystemOperationRunner::ReadDirectory(
198 const FileSystemURL& url,
199 const ReadDirectoryCallback& callback) {
200 base::PlatformFileError error = base::PLATFORM_FILE_OK;
201 FileSystemOperation* operation =
202 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19203 BeginOperationScoper scope;
204 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16205 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19206 DidReadDirectory(handle, callback, error, std::vector<DirectoryEntry>(),
207 false);
208 return handle.id;
[email protected]6fb92642013-06-05 13:05:16209 }
[email protected]33f5a4e2013-09-05 11:24:19210 PrepareForRead(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16211 operation->ReadDirectory(
212 url,
213 base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19214 handle, callback));
215 return handle.id;
[email protected]6fb92642013-06-05 13:05:16216}
217
218OperationID FileSystemOperationRunner::Remove(
219 const FileSystemURL& url, bool recursive,
220 const StatusCallback& callback) {
221 base::PlatformFileError error = base::PLATFORM_FILE_OK;
222 FileSystemOperation* operation =
223 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19224 BeginOperationScoper scope;
225 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16226 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19227 DidFinish(handle, callback, error);
228 return handle.id;
[email protected]6fb92642013-06-05 13:05:16229 }
[email protected]33f5a4e2013-09-05 11:24:19230 PrepareForWrite(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16231 operation->Remove(
232 url, recursive,
233 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19234 handle, callback));
235 return handle.id;
[email protected]6fb92642013-06-05 13:05:16236}
237
238OperationID FileSystemOperationRunner::Write(
239 const net::URLRequestContext* url_request_context,
240 const FileSystemURL& url,
[email protected]84388892013-09-07 04:20:18241 scoped_ptr<webkit_blob::BlobDataHandle> blob,
[email protected]6fb92642013-06-05 13:05:16242 int64 offset,
243 const WriteCallback& callback) {
244 base::PlatformFileError error = base::PLATFORM_FILE_OK;
245 FileSystemOperation* operation =
246 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19247
248 BeginOperationScoper scope;
249 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16250 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19251 DidWrite(handle, callback, error, 0, true);
252 return handle.id;
[email protected]6fb92642013-06-05 13:05:16253 }
[email protected]1a6e3902013-06-13 07:09:40254
255 scoped_ptr<FileStreamWriter> writer(
256 file_system_context_->CreateFileStreamWriter(url, offset));
257 if (!writer) {
258 // Write is not supported.
[email protected]33f5a4e2013-09-05 11:24:19259 DidWrite(handle, callback, base::PLATFORM_FILE_ERROR_SECURITY, 0, true);
260 return handle.id;
[email protected]1a6e3902013-06-13 07:09:40261 }
262
[email protected]1a6e3902013-06-13 07:09:40263 scoped_ptr<FileWriterDelegate> writer_delegate(
264 new FileWriterDelegate(writer.Pass()));
[email protected]84388892013-09-07 04:20:18265
266 scoped_ptr<net::URLRequest> blob_request(
267 webkit_blob::BlobProtocolHandler::CreateBlobRequest(
268 blob.Pass(),
269 url_request_context,
270 writer_delegate.get()));
[email protected]1a6e3902013-06-13 07:09:40271
[email protected]33f5a4e2013-09-05 11:24:19272 PrepareForWrite(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16273 operation->Write(
[email protected]1a6e3902013-06-13 07:09:40274 url, writer_delegate.Pass(), blob_request.Pass(),
[email protected]6fb92642013-06-05 13:05:16275 base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19276 handle, callback));
277 return handle.id;
[email protected]6fb92642013-06-05 13:05:16278}
279
280OperationID FileSystemOperationRunner::Truncate(
281 const FileSystemURL& url, int64 length,
282 const StatusCallback& callback) {
283 base::PlatformFileError error = base::PLATFORM_FILE_OK;
284 FileSystemOperation* operation =
285 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19286 BeginOperationScoper scope;
287 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16288 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19289 DidFinish(handle, callback, error);
290 return handle.id;
[email protected]6fb92642013-06-05 13:05:16291 }
[email protected]33f5a4e2013-09-05 11:24:19292 PrepareForWrite(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16293 operation->Truncate(
294 url, length,
295 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19296 handle, callback));
297 return handle.id;
[email protected]6fb92642013-06-05 13:05:16298}
299
300void FileSystemOperationRunner::Cancel(
301 OperationID id,
302 const StatusCallback& callback) {
[email protected]33f5a4e2013-09-05 11:24:19303 if (ContainsKey(finished_operations_, id)) {
304 DCHECK(!ContainsKey(stray_cancel_callbacks_, id));
305 stray_cancel_callbacks_[id] = callback;
[email protected]6fb92642013-06-05 13:05:16306 return;
307 }
[email protected]33f5a4e2013-09-05 11:24:19308 FileSystemOperation* operation = operations_.Lookup(id);
[email protected]4f976f7612013-09-13 15:51:27309 if (!operation) {
310 // There is no operation with |id|.
311 callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
312 return;
313 }
[email protected]6fb92642013-06-05 13:05:16314 operation->Cancel(callback);
315}
316
317OperationID FileSystemOperationRunner::TouchFile(
318 const FileSystemURL& url,
319 const base::Time& last_access_time,
320 const base::Time& last_modified_time,
321 const StatusCallback& callback) {
322 base::PlatformFileError error = base::PLATFORM_FILE_OK;
323 FileSystemOperation* operation =
324 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19325 BeginOperationScoper scope;
326 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16327 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19328 DidFinish(handle, callback, error);
329 return handle.id;
[email protected]6fb92642013-06-05 13:05:16330 }
[email protected]33f5a4e2013-09-05 11:24:19331 PrepareForWrite(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16332 operation->TouchFile(
333 url, last_access_time, last_modified_time,
334 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19335 handle, callback));
336 return handle.id;
[email protected]6fb92642013-06-05 13:05:16337}
338
339OperationID FileSystemOperationRunner::OpenFile(
340 const FileSystemURL& url,
341 int file_flags,
[email protected]6fb92642013-06-05 13:05:16342 const OpenFileCallback& callback) {
343 base::PlatformFileError error = base::PLATFORM_FILE_OK;
344 FileSystemOperation* operation =
345 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19346 BeginOperationScoper scope;
347 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16348 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19349 DidOpenFile(handle, callback, error, base::kInvalidPlatformFileValue,
[email protected]10c39222013-11-13 20:09:25350 base::Closure());
[email protected]33f5a4e2013-09-05 11:24:19351 return handle.id;
[email protected]6fb92642013-06-05 13:05:16352 }
[email protected]5dfa47c2013-06-10 04:57:15353 if (file_flags &
354 (base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_OPEN_ALWAYS |
355 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_TRUNCATED |
356 base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_WRITE |
357 base::PLATFORM_FILE_DELETE_ON_CLOSE |
358 base::PLATFORM_FILE_WRITE_ATTRIBUTES)) {
[email protected]33f5a4e2013-09-05 11:24:19359 PrepareForWrite(handle.id, url);
[email protected]5dfa47c2013-06-10 04:57:15360 } else {
[email protected]33f5a4e2013-09-05 11:24:19361 PrepareForRead(handle.id, url);
[email protected]5dfa47c2013-06-10 04:57:15362 }
[email protected]6fb92642013-06-05 13:05:16363 operation->OpenFile(
[email protected]10c39222013-11-13 20:09:25364 url, file_flags,
[email protected]6fb92642013-06-05 13:05:16365 base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19366 handle, callback));
367 return handle.id;
[email protected]6fb92642013-06-05 13:05:16368}
369
370OperationID FileSystemOperationRunner::CreateSnapshotFile(
371 const FileSystemURL& url,
372 const SnapshotFileCallback& callback) {
373 base::PlatformFileError error = base::PLATFORM_FILE_OK;
374 FileSystemOperation* operation =
375 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19376 BeginOperationScoper scope;
377 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]6fb92642013-06-05 13:05:16378 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19379 DidCreateSnapshot(handle, callback, error, base::PlatformFileInfo(),
380 base::FilePath(), NULL);
381 return handle.id;
[email protected]6fb92642013-06-05 13:05:16382 }
[email protected]33f5a4e2013-09-05 11:24:19383 PrepareForRead(handle.id, url);
[email protected]6fb92642013-06-05 13:05:16384 operation->CreateSnapshotFile(
385 url,
386 base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19387 handle, callback));
388 return handle.id;
[email protected]6fb92642013-06-05 13:05:16389}
390
[email protected]3c631b22013-06-05 16:13:34391OperationID FileSystemOperationRunner::CopyInForeignFile(
392 const base::FilePath& src_local_disk_path,
393 const FileSystemURL& dest_url,
394 const StatusCallback& callback) {
395 base::PlatformFileError error = base::PLATFORM_FILE_OK;
[email protected]5d4d7a62013-08-27 07:43:31396 FileSystemOperation* operation =
397 file_system_context_->CreateFileSystemOperation(dest_url, &error);
[email protected]33f5a4e2013-09-05 11:24:19398 BeginOperationScoper scope;
399 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]3c631b22013-06-05 16:13:34400 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19401 DidFinish(handle, callback, error);
402 return handle.id;
[email protected]3c631b22013-06-05 16:13:34403 }
[email protected]5d4d7a62013-08-27 07:43:31404 operation->CopyInForeignFile(
[email protected]3c631b22013-06-05 16:13:34405 src_local_disk_path, dest_url,
406 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19407 handle, callback));
408 return handle.id;
[email protected]3c631b22013-06-05 16:13:34409}
410
411OperationID FileSystemOperationRunner::RemoveFile(
412 const FileSystemURL& url,
413 const StatusCallback& callback) {
414 base::PlatformFileError error = base::PLATFORM_FILE_OK;
[email protected]5d4d7a62013-08-27 07:43:31415 FileSystemOperation* operation =
416 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19417 BeginOperationScoper scope;
418 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]3c631b22013-06-05 16:13:34419 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19420 DidFinish(handle, callback, error);
421 return handle.id;
[email protected]3c631b22013-06-05 16:13:34422 }
[email protected]5d4d7a62013-08-27 07:43:31423 operation->RemoveFile(
[email protected]3c631b22013-06-05 16:13:34424 url,
425 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19426 handle, callback));
427 return handle.id;
[email protected]3c631b22013-06-05 16:13:34428}
429
430OperationID FileSystemOperationRunner::RemoveDirectory(
431 const FileSystemURL& url,
432 const StatusCallback& callback) {
433 base::PlatformFileError error = base::PLATFORM_FILE_OK;
[email protected]5d4d7a62013-08-27 07:43:31434 FileSystemOperation* operation =
435 file_system_context_->CreateFileSystemOperation(url, &error);
[email protected]33f5a4e2013-09-05 11:24:19436 BeginOperationScoper scope;
437 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]3c631b22013-06-05 16:13:34438 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19439 DidFinish(handle, callback, error);
440 return handle.id;
[email protected]3c631b22013-06-05 16:13:34441 }
[email protected]5d4d7a62013-08-27 07:43:31442 operation->RemoveDirectory(
[email protected]3c631b22013-06-05 16:13:34443 url,
444 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19445 handle, callback));
446 return handle.id;
[email protected]3c631b22013-06-05 16:13:34447}
448
449OperationID FileSystemOperationRunner::CopyFileLocal(
450 const FileSystemURL& src_url,
451 const FileSystemURL& dest_url,
[email protected]824d3892013-09-25 13:00:30452 CopyOrMoveOption option,
[email protected]af349562013-09-09 14:18:53453 const CopyFileProgressCallback& progress_callback,
[email protected]3c631b22013-06-05 16:13:34454 const StatusCallback& callback) {
455 base::PlatformFileError error = base::PLATFORM_FILE_OK;
[email protected]5d4d7a62013-08-27 07:43:31456 FileSystemOperation* operation =
457 file_system_context_->CreateFileSystemOperation(src_url, &error);
[email protected]33f5a4e2013-09-05 11:24:19458 BeginOperationScoper scope;
459 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]3c631b22013-06-05 16:13:34460 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19461 DidFinish(handle, callback, error);
462 return handle.id;
[email protected]3c631b22013-06-05 16:13:34463 }
[email protected]5d4d7a62013-08-27 07:43:31464 operation->CopyFileLocal(
[email protected]824d3892013-09-25 13:00:30465 src_url, dest_url, option, progress_callback,
[email protected]3c631b22013-06-05 16:13:34466 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19467 handle, callback));
468 return handle.id;
[email protected]3c631b22013-06-05 16:13:34469}
470
471OperationID FileSystemOperationRunner::MoveFileLocal(
472 const FileSystemURL& src_url,
473 const FileSystemURL& dest_url,
[email protected]824d3892013-09-25 13:00:30474 CopyOrMoveOption option,
[email protected]3c631b22013-06-05 16:13:34475 const StatusCallback& callback) {
476 base::PlatformFileError error = base::PLATFORM_FILE_OK;
[email protected]5d4d7a62013-08-27 07:43:31477 FileSystemOperation* operation =
478 file_system_context_->CreateFileSystemOperation(src_url, &error);
[email protected]33f5a4e2013-09-05 11:24:19479 BeginOperationScoper scope;
480 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
[email protected]3c631b22013-06-05 16:13:34481 if (!operation) {
[email protected]33f5a4e2013-09-05 11:24:19482 DidFinish(handle, callback, error);
483 return handle.id;
[email protected]3c631b22013-06-05 16:13:34484 }
[email protected]5d4d7a62013-08-27 07:43:31485 operation->MoveFileLocal(
[email protected]824d3892013-09-25 13:00:30486 src_url, dest_url, option,
[email protected]3c631b22013-06-05 16:13:34487 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
[email protected]33f5a4e2013-09-05 11:24:19488 handle, callback));
489 return handle.id;
[email protected]3c631b22013-06-05 16:13:34490}
491
[email protected]3a7bf222013-06-09 14:14:12492base::PlatformFileError FileSystemOperationRunner::SyncGetPlatformPath(
493 const FileSystemURL& url,
494 base::FilePath* platform_path) {
495 base::PlatformFileError error = base::PLATFORM_FILE_OK;
[email protected]ee387932013-10-28 19:46:09496 scoped_ptr<FileSystemOperation> operation(
497 file_system_context_->CreateFileSystemOperation(url, &error));
498 if (!operation.get())
[email protected]3a7bf222013-06-09 14:14:12499 return error;
[email protected]5d4d7a62013-08-27 07:43:31500 return operation->SyncGetPlatformPath(url, platform_path);
[email protected]3a7bf222013-06-09 14:14:12501}
502
[email protected]6fb92642013-06-05 13:05:16503FileSystemOperationRunner::FileSystemOperationRunner(
504 FileSystemContext* file_system_context)
505 : file_system_context_(file_system_context) {}
506
507void FileSystemOperationRunner::DidFinish(
[email protected]33f5a4e2013-09-05 11:24:19508 const OperationHandle& handle,
[email protected]6fb92642013-06-05 13:05:16509 const StatusCallback& callback,
510 base::PlatformFileError rv) {
[email protected]33f5a4e2013-09-05 11:24:19511 if (handle.scope) {
512 finished_operations_.insert(handle.id);
513 base::MessageLoopProxy::current()->PostTask(
514 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidFinish,
515 AsWeakPtr(), handle, callback, rv));
516 return;
517 }
[email protected]6fb92642013-06-05 13:05:16518 callback.Run(rv);
[email protected]33f5a4e2013-09-05 11:24:19519 FinishOperation(handle.id);
[email protected]6fb92642013-06-05 13:05:16520}
521
522void FileSystemOperationRunner::DidGetMetadata(
[email protected]33f5a4e2013-09-05 11:24:19523 const OperationHandle& handle,
[email protected]6fb92642013-06-05 13:05:16524 const GetMetadataCallback& callback,
525 base::PlatformFileError rv,
[email protected]86b74ce2013-06-14 06:57:10526 const base::PlatformFileInfo& file_info) {
[email protected]33f5a4e2013-09-05 11:24:19527 if (handle.scope) {
528 finished_operations_.insert(handle.id);
529 base::MessageLoopProxy::current()->PostTask(
530 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidGetMetadata,
531 AsWeakPtr(), handle, callback, rv, file_info));
532 return;
533 }
[email protected]86b74ce2013-06-14 06:57:10534 callback.Run(rv, file_info);
[email protected]33f5a4e2013-09-05 11:24:19535 FinishOperation(handle.id);
[email protected]6fb92642013-06-05 13:05:16536}
537
538void FileSystemOperationRunner::DidReadDirectory(
[email protected]33f5a4e2013-09-05 11:24:19539 const OperationHandle& handle,
[email protected]6fb92642013-06-05 13:05:16540 const ReadDirectoryCallback& callback,
541 base::PlatformFileError rv,
542 const std::vector<DirectoryEntry>& entries,
543 bool has_more) {
[email protected]33f5a4e2013-09-05 11:24:19544 if (handle.scope) {
545 finished_operations_.insert(handle.id);
546 base::MessageLoopProxy::current()->PostTask(
547 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidReadDirectory,
548 AsWeakPtr(), handle, callback, rv,
549 entries, has_more));
550 return;
551 }
[email protected]6fb92642013-06-05 13:05:16552 callback.Run(rv, entries, has_more);
[email protected]5dfa47c2013-06-10 04:57:15553 if (rv != base::PLATFORM_FILE_OK || !has_more)
[email protected]33f5a4e2013-09-05 11:24:19554 FinishOperation(handle.id);
[email protected]6fb92642013-06-05 13:05:16555}
556
557void FileSystemOperationRunner::DidWrite(
[email protected]33f5a4e2013-09-05 11:24:19558 const OperationHandle& handle,
[email protected]6fb92642013-06-05 13:05:16559 const WriteCallback& callback,
560 base::PlatformFileError rv,
561 int64 bytes,
562 bool complete) {
[email protected]33f5a4e2013-09-05 11:24:19563 if (handle.scope) {
564 finished_operations_.insert(handle.id);
565 base::MessageLoopProxy::current()->PostTask(
566 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
567 handle, callback, rv, bytes, complete));
568 return;
569 }
[email protected]6fb92642013-06-05 13:05:16570 callback.Run(rv, bytes, complete);
[email protected]5dfa47c2013-06-10 04:57:15571 if (rv != base::PLATFORM_FILE_OK || complete)
[email protected]33f5a4e2013-09-05 11:24:19572 FinishOperation(handle.id);
[email protected]6fb92642013-06-05 13:05:16573}
574
575void FileSystemOperationRunner::DidOpenFile(
[email protected]33f5a4e2013-09-05 11:24:19576 const OperationHandle& handle,
[email protected]6fb92642013-06-05 13:05:16577 const OpenFileCallback& callback,
578 base::PlatformFileError rv,
579 base::PlatformFile file,
[email protected]10c39222013-11-13 20:09:25580 const base::Closure& on_close_callback) {
[email protected]33f5a4e2013-09-05 11:24:19581 if (handle.scope) {
582 finished_operations_.insert(handle.id);
583 base::MessageLoopProxy::current()->PostTask(
584 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidOpenFile,
585 AsWeakPtr(), handle, callback, rv, file,
[email protected]10c39222013-11-13 20:09:25586 on_close_callback));
[email protected]33f5a4e2013-09-05 11:24:19587 return;
588 }
[email protected]10c39222013-11-13 20:09:25589 callback.Run(rv, file, on_close_callback);
[email protected]33f5a4e2013-09-05 11:24:19590 FinishOperation(handle.id);
[email protected]6fb92642013-06-05 13:05:16591}
592
593void FileSystemOperationRunner::DidCreateSnapshot(
[email protected]33f5a4e2013-09-05 11:24:19594 const OperationHandle& handle,
[email protected]6fb92642013-06-05 13:05:16595 const SnapshotFileCallback& callback,
596 base::PlatformFileError rv,
597 const base::PlatformFileInfo& file_info,
598 const base::FilePath& platform_path,
599 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
[email protected]33f5a4e2013-09-05 11:24:19600 if (handle.scope) {
601 finished_operations_.insert(handle.id);
602 base::MessageLoopProxy::current()->PostTask(
603 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidCreateSnapshot,
604 AsWeakPtr(), handle, callback, rv, file_info,
605 platform_path, file_ref));
606 return;
607 }
[email protected]6fb92642013-06-05 13:05:16608 callback.Run(rv, file_info, platform_path, file_ref);
[email protected]33f5a4e2013-09-05 11:24:19609 FinishOperation(handle.id);
[email protected]6fb92642013-06-05 13:05:16610}
611
[email protected]d3072432013-09-12 17:39:29612void FileSystemOperationRunner::OnCopyProgress(
613 const OperationHandle& handle,
614 const CopyProgressCallback& callback,
615 FileSystemOperation::CopyProgressType type,
[email protected]9def5562013-09-20 11:24:45616 const FileSystemURL& source_url,
617 const FileSystemURL& dest_url,
[email protected]d3072432013-09-12 17:39:29618 int64 size) {
619 if (handle.scope) {
620 base::MessageLoopProxy::current()->PostTask(
[email protected]9def5562013-09-20 11:24:45621 FROM_HERE, base::Bind(
622 &FileSystemOperationRunner::OnCopyProgress,
623 AsWeakPtr(), handle, callback, type, source_url, dest_url, size));
[email protected]d3072432013-09-12 17:39:29624 return;
625 }
[email protected]9def5562013-09-20 11:24:45626 callback.Run(type, source_url, dest_url, size);
[email protected]d3072432013-09-12 17:39:29627}
628
[email protected]5dfa47c2013-06-10 04:57:15629void FileSystemOperationRunner::PrepareForWrite(OperationID id,
630 const FileSystemURL& url) {
631 if (file_system_context_->GetUpdateObservers(url.type())) {
632 file_system_context_->GetUpdateObservers(url.type())->Notify(
633 &FileUpdateObserver::OnStartUpdate, MakeTuple(url));
634 }
635 write_target_urls_[id].insert(url);
636}
637
638void FileSystemOperationRunner::PrepareForRead(OperationID id,
639 const FileSystemURL& url) {
640 if (file_system_context_->GetAccessObservers(url.type())) {
641 file_system_context_->GetAccessObservers(url.type())->Notify(
642 &FileAccessObserver::OnAccess, MakeTuple(url));
643 }
644}
645
[email protected]33f5a4e2013-09-05 11:24:19646FileSystemOperationRunner::OperationHandle
647FileSystemOperationRunner::BeginOperation(
648 FileSystemOperation* operation,
649 base::WeakPtr<BeginOperationScoper> scope) {
650 OperationHandle handle;
651 handle.id = operations_.Add(operation);
652 handle.scope = scope;
653 return handle;
654}
655
[email protected]5dfa47c2013-06-10 04:57:15656void FileSystemOperationRunner::FinishOperation(OperationID id) {
657 OperationToURLSet::iterator found = write_target_urls_.find(id);
658 if (found != write_target_urls_.end()) {
659 const FileSystemURLSet& urls = found->second;
660 for (FileSystemURLSet::const_iterator iter = urls.begin();
661 iter != urls.end(); ++iter) {
662 if (file_system_context_->GetUpdateObservers(iter->type())) {
663 file_system_context_->GetUpdateObservers(iter->type())->Notify(
664 &FileUpdateObserver::OnEndUpdate, MakeTuple(*iter));
665 }
666 }
667 write_target_urls_.erase(found);
668 }
[email protected]33f5a4e2013-09-05 11:24:19669
670 // IDMap::Lookup fails if the operation is NULL, so we don't check
671 // operations_.Lookup(id) here.
672
[email protected]5dfa47c2013-06-10 04:57:15673 operations_.Remove(id);
[email protected]33f5a4e2013-09-05 11:24:19674 finished_operations_.erase(id);
675
676 // Dispatch stray cancel callback if exists.
677 std::map<OperationID, StatusCallback>::iterator found_cancel =
678 stray_cancel_callbacks_.find(id);
679 if (found_cancel != stray_cancel_callbacks_.end()) {
680 // This cancel has been requested after the operation has finished,
681 // so report that we failed to stop it.
682 found_cancel->second.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
683 stray_cancel_callbacks_.erase(found_cancel);
684 }
[email protected]5dfa47c2013-06-10 04:57:15685}
686
[email protected]6fb92642013-06-05 13:05:16687} // namespace fileapi