[Storage] Blob Storage Refactoring pt 1:
[chromium-blink-merge.git] / chrome / browser / chromeos / file_system_provider / fileapi / provider_async_file_util.cc
blob7ef074a33811959543ebf2bbf362c47e4813d5f6
1 // Copyright 2014 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.
5 #include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h"
7 #include "base/callback.h"
8 #include "base/files/file.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
12 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "storage/browser/blob/shareable_file_reference.h"
15 #include "storage/browser/fileapi/file_system_operation_context.h"
16 #include "storage/browser/fileapi/file_system_url.h"
18 using content::BrowserThread;
20 namespace chromeos {
21 namespace file_system_provider {
22 namespace internal {
23 namespace {
25 // Executes GetFileInfo on the UI thread.
26 void GetFileInfoOnUIThread(
27 scoped_ptr<storage::FileSystemOperationContext> context,
28 const storage::FileSystemURL& url,
29 const ProvidedFileSystemInterface::GetMetadataCallback& callback) {
30 util::FileSystemURLParser parser(url);
31 if (!parser.Parse()) {
32 callback.Run(make_scoped_ptr<EntryMetadata>(NULL),
33 base::File::FILE_ERROR_INVALID_OPERATION);
34 return;
37 parser.file_system()->GetMetadata(
38 parser.file_path(),
39 ProvidedFileSystemInterface::METADATA_FIELD_DEFAULT,
40 callback);
43 // Routes the response of GetFileInfo back to the IO thread with a type
44 // conversion.
45 void OnGetFileInfo(const storage::AsyncFileUtil::GetFileInfoCallback& callback,
46 scoped_ptr<EntryMetadata> metadata,
47 base::File::Error result) {
48 if (result != base::File::FILE_OK) {
49 BrowserThread::PostTask(BrowserThread::IO,
50 FROM_HERE,
51 base::Bind(callback, result, base::File::Info()));
52 return;
55 DCHECK(metadata.get());
56 base::File::Info file_info;
58 // TODO(mtomasz): Add support for last modified time and creation time.
59 // See: crbug.com/388540.
60 file_info.size = metadata->size;
61 file_info.is_directory = metadata->is_directory;
62 file_info.is_symbolic_link = false; // Not supported.
63 file_info.last_modified = metadata->modification_time;
64 file_info.last_accessed = metadata->modification_time; // Not supported.
65 file_info.creation_time = metadata->modification_time; // Not supported.
67 BrowserThread::PostTask(BrowserThread::IO,
68 FROM_HERE,
69 base::Bind(callback, base::File::FILE_OK, file_info));
72 // Executes ReadDirectory on the UI thread.
73 void ReadDirectoryOnUIThread(
74 scoped_ptr<storage::FileSystemOperationContext> context,
75 const storage::FileSystemURL& url,
76 const storage::AsyncFileUtil::ReadDirectoryCallback& callback) {
77 util::FileSystemURLParser parser(url);
78 if (!parser.Parse()) {
79 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION,
80 storage::AsyncFileUtil::EntryList(),
81 false /* has_more */);
82 return;
85 parser.file_system()->ReadDirectory(parser.file_path(), callback);
88 // Routes the response of ReadDirectory back to the IO thread.
89 void OnReadDirectory(
90 const storage::AsyncFileUtil::ReadDirectoryCallback& callback,
91 base::File::Error result,
92 const storage::AsyncFileUtil::EntryList& entry_list,
93 bool has_more) {
94 BrowserThread::PostTask(BrowserThread::IO,
95 FROM_HERE,
96 base::Bind(callback, result, entry_list, has_more));
99 // Executes CreateDirectory on the UI thread.
100 void CreateDirectoryOnUIThread(
101 scoped_ptr<storage::FileSystemOperationContext> context,
102 const storage::FileSystemURL& url,
103 bool exclusive,
104 bool recursive,
105 const storage::AsyncFileUtil::StatusCallback& callback) {
106 util::FileSystemURLParser parser(url);
107 if (!parser.Parse()) {
108 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
109 return;
112 parser.file_system()->CreateDirectory(
113 parser.file_path(), recursive, callback);
116 // Routes the response of CreateDirectory back to the IO thread.
117 void OnCreateDirectory(bool exclusive,
118 const storage::AsyncFileUtil::StatusCallback& callback,
119 base::File::Error result) {
120 // If the directory already existed and the operation wasn't exclusive, then
121 // return success anyway, since it is not an error.
122 const base::File::Error error =
123 (result == base::File::FILE_ERROR_EXISTS && !exclusive)
124 ? base::File::FILE_OK
125 : result;
127 BrowserThread::PostTask(
128 BrowserThread::IO, FROM_HERE, base::Bind(callback, error));
131 // Executes DeleteEntry on the UI thread.
132 void DeleteEntryOnUIThread(
133 scoped_ptr<storage::FileSystemOperationContext> context,
134 const storage::FileSystemURL& url,
135 bool recursive,
136 const storage::AsyncFileUtil::StatusCallback& callback) {
137 util::FileSystemURLParser parser(url);
138 if (!parser.Parse()) {
139 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
140 return;
143 parser.file_system()->DeleteEntry(parser.file_path(), recursive, callback);
146 // Routes the response of DeleteEntry back to the IO thread.
147 void OnDeleteEntry(const storage::AsyncFileUtil::StatusCallback& callback,
148 base::File::Error result) {
149 BrowserThread::PostTask(
150 BrowserThread::IO, FROM_HERE, base::Bind(callback, result));
153 // Executes CreateFile on the UI thread.
154 void CreateFileOnUIThread(
155 scoped_ptr<storage::FileSystemOperationContext> context,
156 const storage::FileSystemURL& url,
157 const storage::AsyncFileUtil::StatusCallback& callback) {
158 util::FileSystemURLParser parser(url);
159 if (!parser.Parse()) {
160 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
161 return;
164 parser.file_system()->CreateFile(parser.file_path(), callback);
167 // Routes the response of CreateFile to a callback of EnsureFileExists() on the
168 // IO thread.
169 void OnCreateFileForEnsureFileExists(
170 const storage::AsyncFileUtil::EnsureFileExistsCallback& callback,
171 base::File::Error result) {
172 const bool created = result == base::File::FILE_OK;
174 // If the file already existed, then return success anyway, since it is not
175 // an error.
176 const base::File::Error error =
177 result == base::File::FILE_ERROR_EXISTS ? base::File::FILE_OK : result;
179 BrowserThread::PostTask(
180 BrowserThread::IO, FROM_HERE, base::Bind(callback, error, created));
183 // Executes CopyEntry on the UI thread.
184 void CopyEntryOnUIThread(
185 scoped_ptr<storage::FileSystemOperationContext> context,
186 const storage::FileSystemURL& source_url,
187 const storage::FileSystemURL& target_url,
188 const storage::AsyncFileUtil::StatusCallback& callback) {
189 util::FileSystemURLParser source_parser(source_url);
190 util::FileSystemURLParser target_parser(target_url);
192 if (!source_parser.Parse() || !target_parser.Parse() ||
193 source_parser.file_system() != target_parser.file_system()) {
194 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
195 return;
198 target_parser.file_system()->CopyEntry(
199 source_parser.file_path(), target_parser.file_path(), callback);
202 // Routes the response of CopyEntry to a callback of CopyLocalFile() on the
203 // IO thread.
204 void OnCopyEntry(const storage::AsyncFileUtil::StatusCallback& callback,
205 base::File::Error result) {
206 BrowserThread::PostTask(
207 BrowserThread::IO, FROM_HERE, base::Bind(callback, result));
210 // Executes MoveEntry on the UI thread.
211 void MoveEntryOnUIThread(
212 scoped_ptr<storage::FileSystemOperationContext> context,
213 const storage::FileSystemURL& source_url,
214 const storage::FileSystemURL& target_url,
215 const storage::AsyncFileUtil::StatusCallback& callback) {
216 util::FileSystemURLParser source_parser(source_url);
217 util::FileSystemURLParser target_parser(target_url);
219 if (!source_parser.Parse() || !target_parser.Parse() ||
220 source_parser.file_system() != target_parser.file_system()) {
221 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
222 return;
225 target_parser.file_system()->MoveEntry(
226 source_parser.file_path(), target_parser.file_path(), callback);
229 // Routes the response of CopyEntry to a callback of MoveLocalFile() on the
230 // IO thread.
231 void OnMoveEntry(const storage::AsyncFileUtil::StatusCallback& callback,
232 base::File::Error result) {
233 BrowserThread::PostTask(
234 BrowserThread::IO, FROM_HERE, base::Bind(callback, result));
237 // Executes Truncate on the UI thread.
238 void TruncateOnUIThread(
239 scoped_ptr<storage::FileSystemOperationContext> context,
240 const storage::FileSystemURL& url,
241 int64 length,
242 const storage::AsyncFileUtil::StatusCallback& callback) {
243 util::FileSystemURLParser parser(url);
244 if (!parser.Parse()) {
245 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
246 return;
249 parser.file_system()->Truncate(parser.file_path(), length, callback);
252 // Routes the response of Truncate back to the IO thread.
253 void OnTruncate(const storage::AsyncFileUtil::StatusCallback& callback,
254 base::File::Error result) {
255 BrowserThread::PostTask(
256 BrowserThread::IO, FROM_HERE, base::Bind(callback, result));
259 } // namespace
261 ProviderAsyncFileUtil::ProviderAsyncFileUtil() {}
263 ProviderAsyncFileUtil::~ProviderAsyncFileUtil() {}
265 void ProviderAsyncFileUtil::CreateOrOpen(
266 scoped_ptr<storage::FileSystemOperationContext> context,
267 const storage::FileSystemURL& url,
268 int file_flags,
269 const CreateOrOpenCallback& callback) {
270 DCHECK_CURRENTLY_ON(BrowserThread::IO);
271 if ((file_flags & base::File::FLAG_CREATE) ||
272 (file_flags & base::File::FLAG_OPEN_ALWAYS) ||
273 (file_flags & base::File::FLAG_CREATE_ALWAYS) ||
274 (file_flags & base::File::FLAG_OPEN_TRUNCATED)) {
275 callback.Run(base::File(base::File::FILE_ERROR_ACCESS_DENIED),
276 base::Closure());
277 return;
280 NOTIMPLEMENTED();
281 callback.Run(base::File(base::File::FILE_ERROR_INVALID_OPERATION),
282 base::Closure());
285 void ProviderAsyncFileUtil::EnsureFileExists(
286 scoped_ptr<storage::FileSystemOperationContext> context,
287 const storage::FileSystemURL& url,
288 const EnsureFileExistsCallback& callback) {
289 DCHECK_CURRENTLY_ON(BrowserThread::IO);
290 BrowserThread::PostTask(
291 BrowserThread::UI,
292 FROM_HERE,
293 base::Bind(&CreateFileOnUIThread,
294 base::Passed(&context),
295 url,
296 base::Bind(&OnCreateFileForEnsureFileExists, callback)));
299 void ProviderAsyncFileUtil::CreateDirectory(
300 scoped_ptr<storage::FileSystemOperationContext> context,
301 const storage::FileSystemURL& url,
302 bool exclusive,
303 bool recursive,
304 const StatusCallback& callback) {
305 DCHECK_CURRENTLY_ON(BrowserThread::IO);
306 BrowserThread::PostTask(
307 BrowserThread::UI,
308 FROM_HERE,
309 base::Bind(&CreateDirectoryOnUIThread,
310 base::Passed(&context),
311 url,
312 exclusive,
313 recursive,
314 base::Bind(&OnCreateDirectory, exclusive, callback)));
317 void ProviderAsyncFileUtil::GetFileInfo(
318 scoped_ptr<storage::FileSystemOperationContext> context,
319 const storage::FileSystemURL& url,
320 const GetFileInfoCallback& callback) {
321 DCHECK_CURRENTLY_ON(BrowserThread::IO);
322 BrowserThread::PostTask(BrowserThread::UI,
323 FROM_HERE,
324 base::Bind(&GetFileInfoOnUIThread,
325 base::Passed(&context),
326 url,
327 base::Bind(&OnGetFileInfo, callback)));
330 void ProviderAsyncFileUtil::ReadDirectory(
331 scoped_ptr<storage::FileSystemOperationContext> context,
332 const storage::FileSystemURL& url,
333 const ReadDirectoryCallback& callback) {
334 DCHECK_CURRENTLY_ON(BrowserThread::IO);
335 BrowserThread::PostTask(BrowserThread::UI,
336 FROM_HERE,
337 base::Bind(&ReadDirectoryOnUIThread,
338 base::Passed(&context),
339 url,
340 base::Bind(&OnReadDirectory, callback)));
343 void ProviderAsyncFileUtil::Touch(
344 scoped_ptr<storage::FileSystemOperationContext> context,
345 const storage::FileSystemURL& url,
346 const base::Time& last_access_time,
347 const base::Time& last_modified_time,
348 const StatusCallback& callback) {
349 DCHECK_CURRENTLY_ON(BrowserThread::IO);
350 callback.Run(base::File::FILE_ERROR_ACCESS_DENIED);
353 void ProviderAsyncFileUtil::Truncate(
354 scoped_ptr<storage::FileSystemOperationContext> context,
355 const storage::FileSystemURL& url,
356 int64 length,
357 const StatusCallback& callback) {
358 DCHECK_CURRENTLY_ON(BrowserThread::IO);
359 BrowserThread::PostTask(BrowserThread::UI,
360 FROM_HERE,
361 base::Bind(&TruncateOnUIThread,
362 base::Passed(&context),
363 url,
364 length,
365 base::Bind(&OnTruncate, callback)));
368 void ProviderAsyncFileUtil::CopyFileLocal(
369 scoped_ptr<storage::FileSystemOperationContext> context,
370 const storage::FileSystemURL& src_url,
371 const storage::FileSystemURL& dest_url,
372 CopyOrMoveOption option,
373 const CopyFileProgressCallback& progress_callback,
374 const StatusCallback& callback) {
375 DCHECK_CURRENTLY_ON(BrowserThread::IO);
376 // TODO(mtomasz): Consier adding support for options (preserving last modified
377 // time) as well as the progress callback.
378 BrowserThread::PostTask(BrowserThread::UI,
379 FROM_HERE,
380 base::Bind(&CopyEntryOnUIThread,
381 base::Passed(&context),
382 src_url,
383 dest_url,
384 base::Bind(&OnCopyEntry, callback)));
387 void ProviderAsyncFileUtil::MoveFileLocal(
388 scoped_ptr<storage::FileSystemOperationContext> context,
389 const storage::FileSystemURL& src_url,
390 const storage::FileSystemURL& dest_url,
391 CopyOrMoveOption option,
392 const StatusCallback& callback) {
393 DCHECK_CURRENTLY_ON(BrowserThread::IO);
394 // TODO(mtomasz): Consier adding support for options (preserving last modified
395 // time) as well as the progress callback.
396 BrowserThread::PostTask(BrowserThread::UI,
397 FROM_HERE,
398 base::Bind(&MoveEntryOnUIThread,
399 base::Passed(&context),
400 src_url,
401 dest_url,
402 base::Bind(&OnMoveEntry, callback)));
405 void ProviderAsyncFileUtil::CopyInForeignFile(
406 scoped_ptr<storage::FileSystemOperationContext> context,
407 const base::FilePath& src_file_path,
408 const storage::FileSystemURL& dest_url,
409 const StatusCallback& callback) {
410 DCHECK_CURRENTLY_ON(BrowserThread::IO);
411 callback.Run(base::File::FILE_ERROR_ACCESS_DENIED);
414 void ProviderAsyncFileUtil::DeleteFile(
415 scoped_ptr<storage::FileSystemOperationContext> context,
416 const storage::FileSystemURL& url,
417 const StatusCallback& callback) {
418 DCHECK_CURRENTLY_ON(BrowserThread::IO);
419 BrowserThread::PostTask(BrowserThread::UI,
420 FROM_HERE,
421 base::Bind(&DeleteEntryOnUIThread,
422 base::Passed(&context),
423 url,
424 false, // recursive
425 base::Bind(&OnDeleteEntry, callback)));
428 void ProviderAsyncFileUtil::DeleteDirectory(
429 scoped_ptr<storage::FileSystemOperationContext> context,
430 const storage::FileSystemURL& url,
431 const StatusCallback& callback) {
432 DCHECK_CURRENTLY_ON(BrowserThread::IO);
433 BrowserThread::PostTask(BrowserThread::UI,
434 FROM_HERE,
435 base::Bind(&DeleteEntryOnUIThread,
436 base::Passed(&context),
437 url,
438 false, // recursive
439 base::Bind(&OnDeleteEntry, callback)));
442 void ProviderAsyncFileUtil::DeleteRecursively(
443 scoped_ptr<storage::FileSystemOperationContext> context,
444 const storage::FileSystemURL& url,
445 const StatusCallback& callback) {
446 DCHECK_CURRENTLY_ON(BrowserThread::IO);
447 BrowserThread::PostTask(BrowserThread::UI,
448 FROM_HERE,
449 base::Bind(&DeleteEntryOnUIThread,
450 base::Passed(&context),
451 url,
452 true, // recursive
453 base::Bind(&OnDeleteEntry, callback)));
456 void ProviderAsyncFileUtil::CreateSnapshotFile(
457 scoped_ptr<storage::FileSystemOperationContext> context,
458 const storage::FileSystemURL& url,
459 const CreateSnapshotFileCallback& callback) {
460 DCHECK_CURRENTLY_ON(BrowserThread::IO);
461 NOTIMPLEMENTED();
462 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION,
463 base::File::Info(),
464 base::FilePath(),
465 scoped_refptr<storage::ShareableFileReference>());
468 } // namespace internal
469 } // namespace file_system_provider
470 } // namespace chromeos