Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / native_media_file_util.cc
blob05a3b539be828c5041f12ca89eb724433c6cddcd
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
3 // found in the LICENSE file.
5 #include "chrome/browser/media_galleries/fileapi/native_media_file_util.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/files/file_util.h"
13 #include "base/strings/string_util.h"
14 #include "base/task_runner_util.h"
15 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "net/base/io_buffer.h"
18 #include "net/base/mime_sniffer.h"
19 #include "storage/browser/blob/shareable_file_reference.h"
20 #include "storage/browser/fileapi/file_system_context.h"
21 #include "storage/browser/fileapi/file_system_operation_context.h"
22 #include "storage/browser/fileapi/native_file_util.h"
23 #include "url/gurl.h"
25 namespace {
27 // Returns true if the current thread is capable of doing IO.
28 bool IsOnTaskRunnerThread(storage::FileSystemOperationContext* context) {
29 return context->task_runner()->RunsTasksOnCurrentThread();
32 base::File::Error IsMediaHeader(const char* buf, size_t length) {
33 if (length == 0)
34 return base::File::FILE_ERROR_SECURITY;
36 std::string mime_type;
37 if (!net::SniffMimeTypeFromLocalData(buf, length, &mime_type))
38 return base::File::FILE_ERROR_SECURITY;
40 if (base::StartsWith(mime_type, "image/", base::CompareCase::SENSITIVE) ||
41 base::StartsWith(mime_type, "audio/", base::CompareCase::SENSITIVE) ||
42 base::StartsWith(mime_type, "video/", base::CompareCase::SENSITIVE) ||
43 mime_type == "application/x-shockwave-flash") {
44 return base::File::FILE_OK;
46 return base::File::FILE_ERROR_SECURITY;
49 void HoldFileRef(
50 const scoped_refptr<storage::ShareableFileReference>& file_ref) {
53 void DidOpenSnapshot(
54 const storage::AsyncFileUtil::CreateOrOpenCallback& callback,
55 const scoped_refptr<storage::ShareableFileReference>& file_ref,
56 base::File file) {
57 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
58 if (!file.IsValid()) {
59 callback.Run(file.Pass(), base::Closure());
60 return;
62 callback.Run(file.Pass(), base::Bind(&HoldFileRef, file_ref));
65 } // namespace
67 NativeMediaFileUtil::NativeMediaFileUtil(MediaPathFilter* media_path_filter)
68 : media_path_filter_(media_path_filter),
69 weak_factory_(this) {
72 NativeMediaFileUtil::~NativeMediaFileUtil() {
75 // static
76 base::File::Error NativeMediaFileUtil::IsMediaFile(
77 const base::FilePath& path) {
78 base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
79 if (!file.IsValid())
80 return file.error_details();
82 char buffer[net::kMaxBytesToSniff];
84 // Read as much as net::SniffMimeTypeFromLocalData() will bother looking at.
85 int64 len = file.Read(0, buffer, net::kMaxBytesToSniff);
86 if (len < 0)
87 return base::File::FILE_ERROR_FAILED;
89 return IsMediaHeader(buffer, len);
92 // static
93 base::File::Error NativeMediaFileUtil::BufferIsMediaHeader(
94 net::IOBuffer* buf, size_t length) {
95 return IsMediaHeader(buf->data(), length);
98 // static
99 void NativeMediaFileUtil::CreatedSnapshotFileForCreateOrOpen(
100 base::SequencedTaskRunner* media_task_runner,
101 int file_flags,
102 const storage::AsyncFileUtil::CreateOrOpenCallback& callback,
103 base::File::Error result,
104 const base::File::Info& file_info,
105 const base::FilePath& platform_path,
106 const scoped_refptr<storage::ShareableFileReference>& file_ref) {
107 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
108 if (result != base::File::FILE_OK) {
109 callback.Run(base::File(), base::Closure());
110 return;
112 base::PostTaskAndReplyWithResult(
113 media_task_runner,
114 FROM_HERE,
115 base::Bind(
116 &storage::NativeFileUtil::CreateOrOpen, platform_path, file_flags),
117 base::Bind(&DidOpenSnapshot, callback, file_ref));
120 void NativeMediaFileUtil::CreateOrOpen(
121 scoped_ptr<storage::FileSystemOperationContext> context,
122 const storage::FileSystemURL& url,
123 int file_flags,
124 const CreateOrOpenCallback& callback) {
125 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
126 // Returns an error if any unsupported flag is found.
127 if (file_flags & ~(base::File::FLAG_OPEN |
128 base::File::FLAG_READ |
129 base::File::FLAG_WRITE_ATTRIBUTES)) {
130 callback.Run(base::File(base::File::FILE_ERROR_SECURITY), base::Closure());
131 return;
133 scoped_refptr<base::SequencedTaskRunner> task_runner = context->task_runner();
134 CreateSnapshotFile(
135 context.Pass(),
136 url,
137 base::Bind(&NativeMediaFileUtil::CreatedSnapshotFileForCreateOrOpen,
138 task_runner,
139 file_flags,
140 callback));
143 void NativeMediaFileUtil::EnsureFileExists(
144 scoped_ptr<storage::FileSystemOperationContext> context,
145 const storage::FileSystemURL& url,
146 const EnsureFileExistsCallback& callback) {
147 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
148 callback.Run(base::File::FILE_ERROR_SECURITY, false);
151 void NativeMediaFileUtil::CreateDirectory(
152 scoped_ptr<storage::FileSystemOperationContext> context,
153 const storage::FileSystemURL& url,
154 bool exclusive,
155 bool recursive,
156 const StatusCallback& callback) {
157 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
158 storage::FileSystemOperationContext* context_ptr = context.get();
159 const bool success = context_ptr->task_runner()->PostTask(
160 FROM_HERE,
161 base::Bind(&NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread,
162 weak_factory_.GetWeakPtr(), base::Passed(&context),
163 url, exclusive, recursive, callback));
164 DCHECK(success);
167 void NativeMediaFileUtil::GetFileInfo(
168 scoped_ptr<storage::FileSystemOperationContext> context,
169 const storage::FileSystemURL& url,
170 const GetFileInfoCallback& callback) {
171 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
172 storage::FileSystemOperationContext* context_ptr = context.get();
173 const bool success = context_ptr->task_runner()->PostTask(
174 FROM_HERE,
175 base::Bind(&NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread,
176 weak_factory_.GetWeakPtr(), base::Passed(&context),
177 url, callback));
178 DCHECK(success);
181 void NativeMediaFileUtil::ReadDirectory(
182 scoped_ptr<storage::FileSystemOperationContext> context,
183 const storage::FileSystemURL& url,
184 const ReadDirectoryCallback& callback) {
185 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
186 storage::FileSystemOperationContext* context_ptr = context.get();
187 const bool success = context_ptr->task_runner()->PostTask(
188 FROM_HERE,
189 base::Bind(&NativeMediaFileUtil::ReadDirectoryOnTaskRunnerThread,
190 weak_factory_.GetWeakPtr(), base::Passed(&context),
191 url, callback));
192 DCHECK(success);
195 void NativeMediaFileUtil::Touch(
196 scoped_ptr<storage::FileSystemOperationContext> context,
197 const storage::FileSystemURL& url,
198 const base::Time& last_access_time,
199 const base::Time& last_modified_time,
200 const StatusCallback& callback) {
201 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
202 callback.Run(base::File::FILE_ERROR_SECURITY);
205 void NativeMediaFileUtil::Truncate(
206 scoped_ptr<storage::FileSystemOperationContext> context,
207 const storage::FileSystemURL& url,
208 int64 length,
209 const StatusCallback& callback) {
210 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
211 callback.Run(base::File::FILE_ERROR_SECURITY);
214 void NativeMediaFileUtil::CopyFileLocal(
215 scoped_ptr<storage::FileSystemOperationContext> context,
216 const storage::FileSystemURL& src_url,
217 const storage::FileSystemURL& dest_url,
218 CopyOrMoveOption option,
219 const CopyFileProgressCallback& progress_callback,
220 const StatusCallback& callback) {
221 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
222 storage::FileSystemOperationContext* context_ptr = context.get();
223 const bool success = context_ptr->task_runner()->PostTask(
224 FROM_HERE,
225 base::Bind(&NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread,
226 weak_factory_.GetWeakPtr(), base::Passed(&context),
227 src_url, dest_url, option, true /* copy */, callback));
228 DCHECK(success);
231 void NativeMediaFileUtil::MoveFileLocal(
232 scoped_ptr<storage::FileSystemOperationContext> context,
233 const storage::FileSystemURL& src_url,
234 const storage::FileSystemURL& dest_url,
235 CopyOrMoveOption option,
236 const StatusCallback& callback) {
237 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
238 storage::FileSystemOperationContext* context_ptr = context.get();
239 const bool success = context_ptr->task_runner()->PostTask(
240 FROM_HERE,
241 base::Bind(&NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread,
242 weak_factory_.GetWeakPtr(), base::Passed(&context),
243 src_url, dest_url, option, false /* copy */, callback));
244 DCHECK(success);
247 void NativeMediaFileUtil::CopyInForeignFile(
248 scoped_ptr<storage::FileSystemOperationContext> context,
249 const base::FilePath& src_file_path,
250 const storage::FileSystemURL& dest_url,
251 const StatusCallback& callback) {
252 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
253 storage::FileSystemOperationContext* context_ptr = context.get();
254 const bool success = context_ptr->task_runner()->PostTask(
255 FROM_HERE,
256 base::Bind(&NativeMediaFileUtil::CopyInForeignFileOnTaskRunnerThread,
257 weak_factory_.GetWeakPtr(), base::Passed(&context),
258 src_file_path, dest_url, callback));
259 DCHECK(success);
262 void NativeMediaFileUtil::DeleteFile(
263 scoped_ptr<storage::FileSystemOperationContext> context,
264 const storage::FileSystemURL& url,
265 const StatusCallback& callback) {
266 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
267 storage::FileSystemOperationContext* context_ptr = context.get();
268 const bool success = context_ptr->task_runner()->PostTask(
269 FROM_HERE,
270 base::Bind(&NativeMediaFileUtil::DeleteFileOnTaskRunnerThread,
271 weak_factory_.GetWeakPtr(), base::Passed(&context),
272 url, callback));
273 DCHECK(success);
276 // This is needed to support Copy and Move.
277 void NativeMediaFileUtil::DeleteDirectory(
278 scoped_ptr<storage::FileSystemOperationContext> context,
279 const storage::FileSystemURL& url,
280 const StatusCallback& callback) {
281 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
282 storage::FileSystemOperationContext* context_ptr = context.get();
283 const bool success = context_ptr->task_runner()->PostTask(
284 FROM_HERE,
285 base::Bind(&NativeMediaFileUtil::DeleteDirectoryOnTaskRunnerThread,
286 weak_factory_.GetWeakPtr(), base::Passed(&context),
287 url, callback));
288 DCHECK(success);
291 void NativeMediaFileUtil::DeleteRecursively(
292 scoped_ptr<storage::FileSystemOperationContext> context,
293 const storage::FileSystemURL& url,
294 const StatusCallback& callback) {
295 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
296 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
299 void NativeMediaFileUtil::CreateSnapshotFile(
300 scoped_ptr<storage::FileSystemOperationContext> context,
301 const storage::FileSystemURL& url,
302 const CreateSnapshotFileCallback& callback) {
303 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
304 storage::FileSystemOperationContext* context_ptr = context.get();
305 const bool success = context_ptr->task_runner()->PostTask(
306 FROM_HERE,
307 base::Bind(&NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread,
308 weak_factory_.GetWeakPtr(), base::Passed(&context),
309 url, callback));
310 DCHECK(success);
313 void NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread(
314 scoped_ptr<storage::FileSystemOperationContext> context,
315 const storage::FileSystemURL& url,
316 bool exclusive,
317 bool recursive,
318 const StatusCallback& callback) {
319 DCHECK(IsOnTaskRunnerThread(context.get()));
320 base::File::Error error =
321 CreateDirectorySync(context.get(), url, exclusive, recursive);
322 content::BrowserThread::PostTask(
323 content::BrowserThread::IO,
324 FROM_HERE,
325 base::Bind(callback, error));
328 void NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread(
329 scoped_ptr<storage::FileSystemOperationContext> context,
330 const storage::FileSystemURL& url,
331 const GetFileInfoCallback& callback) {
332 DCHECK(IsOnTaskRunnerThread(context.get()));
333 base::File::Info file_info;
334 base::File::Error error =
335 GetFileInfoSync(context.get(), url, &file_info, NULL);
336 content::BrowserThread::PostTask(
337 content::BrowserThread::IO,
338 FROM_HERE,
339 base::Bind(callback, error, file_info));
342 void NativeMediaFileUtil::ReadDirectoryOnTaskRunnerThread(
343 scoped_ptr<storage::FileSystemOperationContext> context,
344 const storage::FileSystemURL& url,
345 const ReadDirectoryCallback& callback) {
346 DCHECK(IsOnTaskRunnerThread(context.get()));
347 EntryList entry_list;
348 base::File::Error error =
349 ReadDirectorySync(context.get(), url, &entry_list);
350 content::BrowserThread::PostTask(
351 content::BrowserThread::IO,
352 FROM_HERE,
353 base::Bind(callback, error, entry_list, false /* has_more */));
356 void NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread(
357 scoped_ptr<storage::FileSystemOperationContext> context,
358 const storage::FileSystemURL& src_url,
359 const storage::FileSystemURL& dest_url,
360 CopyOrMoveOption option,
361 bool copy,
362 const StatusCallback& callback) {
363 DCHECK(IsOnTaskRunnerThread(context.get()));
364 base::File::Error error =
365 CopyOrMoveFileSync(context.get(), src_url, dest_url, option, copy);
366 content::BrowserThread::PostTask(
367 content::BrowserThread::IO,
368 FROM_HERE,
369 base::Bind(callback, error));
372 void NativeMediaFileUtil::CopyInForeignFileOnTaskRunnerThread(
373 scoped_ptr<storage::FileSystemOperationContext> context,
374 const base::FilePath& src_file_path,
375 const storage::FileSystemURL& dest_url,
376 const StatusCallback& callback) {
377 DCHECK(IsOnTaskRunnerThread(context.get()));
378 base::File::Error error =
379 CopyInForeignFileSync(context.get(), src_file_path, dest_url);
380 content::BrowserThread::PostTask(
381 content::BrowserThread::IO,
382 FROM_HERE,
383 base::Bind(callback, error));
386 void NativeMediaFileUtil::DeleteFileOnTaskRunnerThread(
387 scoped_ptr<storage::FileSystemOperationContext> context,
388 const storage::FileSystemURL& url,
389 const StatusCallback& callback) {
390 DCHECK(IsOnTaskRunnerThread(context.get()));
391 base::File::Error error = DeleteFileSync(context.get(), url);
392 content::BrowserThread::PostTask(
393 content::BrowserThread::IO,
394 FROM_HERE,
395 base::Bind(callback, error));
398 void NativeMediaFileUtil::DeleteDirectoryOnTaskRunnerThread(
399 scoped_ptr<storage::FileSystemOperationContext> context,
400 const storage::FileSystemURL& url,
401 const StatusCallback& callback) {
402 DCHECK(IsOnTaskRunnerThread(context.get()));
403 base::File::Error error = DeleteDirectorySync(context.get(), url);
404 content::BrowserThread::PostTask(
405 content::BrowserThread::IO,
406 FROM_HERE,
407 base::Bind(callback, error));
410 void NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread(
411 scoped_ptr<storage::FileSystemOperationContext> context,
412 const storage::FileSystemURL& url,
413 const CreateSnapshotFileCallback& callback) {
414 DCHECK(IsOnTaskRunnerThread(context.get()));
415 base::File::Info file_info;
416 base::FilePath platform_path;
417 scoped_refptr<storage::ShareableFileReference> file_ref;
418 base::File::Error error = CreateSnapshotFileSync(
419 context.get(), url, &file_info, &platform_path, &file_ref);
420 content::BrowserThread::PostTask(
421 content::BrowserThread::IO,
422 FROM_HERE,
423 base::Bind(callback, error, file_info, platform_path, file_ref));
426 base::File::Error NativeMediaFileUtil::CreateDirectorySync(
427 storage::FileSystemOperationContext* context,
428 const storage::FileSystemURL& url,
429 bool exclusive,
430 bool recursive) {
431 base::FilePath file_path;
432 base::File::Error error = GetLocalFilePath(context, url, &file_path);
433 if (error != base::File::FILE_OK)
434 return error;
435 return storage::NativeFileUtil::CreateDirectory(
436 file_path, exclusive, recursive);
439 base::File::Error NativeMediaFileUtil::CopyOrMoveFileSync(
440 storage::FileSystemOperationContext* context,
441 const storage::FileSystemURL& src_url,
442 const storage::FileSystemURL& dest_url,
443 CopyOrMoveOption option,
444 bool copy) {
445 DCHECK(IsOnTaskRunnerThread(context));
446 base::FilePath src_file_path;
447 base::File::Error error =
448 GetFilteredLocalFilePathForExistingFileOrDirectory(
449 context, src_url,
450 base::File::FILE_ERROR_NOT_FOUND,
451 &src_file_path);
452 if (error != base::File::FILE_OK)
453 return error;
454 if (storage::NativeFileUtil::DirectoryExists(src_file_path))
455 return base::File::FILE_ERROR_NOT_A_FILE;
457 base::FilePath dest_file_path;
458 error = GetLocalFilePath(context, dest_url, &dest_file_path);
459 if (error != base::File::FILE_OK)
460 return error;
461 base::File::Info file_info;
462 error = storage::NativeFileUtil::GetFileInfo(dest_file_path, &file_info);
463 if (error != base::File::FILE_OK &&
464 error != base::File::FILE_ERROR_NOT_FOUND) {
465 return error;
467 if (error == base::File::FILE_OK && file_info.is_directory)
468 return base::File::FILE_ERROR_INVALID_OPERATION;
469 if (!media_path_filter_->Match(dest_file_path))
470 return base::File::FILE_ERROR_SECURITY;
472 return storage::NativeFileUtil::CopyOrMoveFile(
473 src_file_path,
474 dest_file_path,
475 option,
476 storage::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, copy));
479 base::File::Error NativeMediaFileUtil::CopyInForeignFileSync(
480 storage::FileSystemOperationContext* context,
481 const base::FilePath& src_file_path,
482 const storage::FileSystemURL& dest_url) {
483 DCHECK(IsOnTaskRunnerThread(context));
484 if (src_file_path.empty())
485 return base::File::FILE_ERROR_INVALID_OPERATION;
487 base::FilePath dest_file_path;
488 base::File::Error error =
489 GetFilteredLocalFilePath(context, dest_url, &dest_file_path);
490 if (error != base::File::FILE_OK)
491 return error;
492 return storage::NativeFileUtil::CopyOrMoveFile(
493 src_file_path,
494 dest_file_path,
495 storage::FileSystemOperation::OPTION_NONE,
496 storage::NativeFileUtil::CopyOrMoveModeForDestination(dest_url,
497 true /* copy */));
500 base::File::Error NativeMediaFileUtil::GetFileInfoSync(
501 storage::FileSystemOperationContext* context,
502 const storage::FileSystemURL& url,
503 base::File::Info* file_info,
504 base::FilePath* platform_path) {
505 DCHECK(context);
506 DCHECK(IsOnTaskRunnerThread(context));
507 DCHECK(file_info);
509 base::FilePath file_path;
510 base::File::Error error = GetLocalFilePath(context, url, &file_path);
511 if (error != base::File::FILE_OK)
512 return error;
513 if (base::IsLink(file_path))
514 return base::File::FILE_ERROR_NOT_FOUND;
515 error = storage::NativeFileUtil::GetFileInfo(file_path, file_info);
516 if (error != base::File::FILE_OK)
517 return error;
519 if (platform_path)
520 *platform_path = file_path;
521 if (file_info->is_directory ||
522 media_path_filter_->Match(file_path)) {
523 return base::File::FILE_OK;
525 return base::File::FILE_ERROR_NOT_FOUND;
528 base::File::Error NativeMediaFileUtil::GetLocalFilePath(
529 storage::FileSystemOperationContext* context,
530 const storage::FileSystemURL& url,
531 base::FilePath* local_file_path) {
532 DCHECK(local_file_path);
533 DCHECK(url.is_valid());
534 if (url.path().empty()) {
535 // Root direcory case, which should not be accessed.
536 return base::File::FILE_ERROR_ACCESS_DENIED;
538 *local_file_path = url.path();
539 return base::File::FILE_OK;
542 base::File::Error NativeMediaFileUtil::ReadDirectorySync(
543 storage::FileSystemOperationContext* context,
544 const storage::FileSystemURL& url,
545 EntryList* file_list) {
546 DCHECK(IsOnTaskRunnerThread(context));
547 DCHECK(file_list);
548 DCHECK(file_list->empty());
549 base::File::Info file_info;
550 base::FilePath dir_path;
551 base::File::Error error =
552 GetFileInfoSync(context, url, &file_info, &dir_path);
554 if (error != base::File::FILE_OK)
555 return error;
557 if (!file_info.is_directory)
558 return base::File::FILE_ERROR_NOT_A_DIRECTORY;
560 base::FileEnumerator file_enum(
561 dir_path,
562 false /* recursive */,
563 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
564 for (base::FilePath enum_path = file_enum.Next();
565 !enum_path.empty();
566 enum_path = file_enum.Next()) {
567 // Skip symlinks.
568 if (base::IsLink(enum_path))
569 continue;
571 base::FileEnumerator::FileInfo info = file_enum.GetInfo();
573 // NativeMediaFileUtil skip criteria.
574 if (MediaPathFilter::ShouldSkip(enum_path))
575 continue;
576 if (!info.IsDirectory() && !media_path_filter_->Match(enum_path))
577 continue;
579 storage::DirectoryEntry entry;
580 entry.is_directory = info.IsDirectory();
581 entry.name = enum_path.BaseName().value();
582 entry.size = info.GetSize();
583 entry.last_modified_time = info.GetLastModifiedTime();
585 file_list->push_back(entry);
588 return base::File::FILE_OK;
591 base::File::Error NativeMediaFileUtil::DeleteFileSync(
592 storage::FileSystemOperationContext* context,
593 const storage::FileSystemURL& url) {
594 DCHECK(IsOnTaskRunnerThread(context));
595 base::File::Info file_info;
596 base::FilePath file_path;
597 base::File::Error error =
598 GetFileInfoSync(context, url, &file_info, &file_path);
599 if (error != base::File::FILE_OK)
600 return error;
601 if (file_info.is_directory)
602 return base::File::FILE_ERROR_NOT_A_FILE;
603 return storage::NativeFileUtil::DeleteFile(file_path);
606 base::File::Error NativeMediaFileUtil::DeleteDirectorySync(
607 storage::FileSystemOperationContext* context,
608 const storage::FileSystemURL& url) {
609 DCHECK(IsOnTaskRunnerThread(context));
610 base::FilePath file_path;
611 base::File::Error error = GetLocalFilePath(context, url, &file_path);
612 if (error != base::File::FILE_OK)
613 return error;
614 return storage::NativeFileUtil::DeleteDirectory(file_path);
617 base::File::Error NativeMediaFileUtil::CreateSnapshotFileSync(
618 storage::FileSystemOperationContext* context,
619 const storage::FileSystemURL& url,
620 base::File::Info* file_info,
621 base::FilePath* platform_path,
622 scoped_refptr<storage::ShareableFileReference>* file_ref) {
623 DCHECK(IsOnTaskRunnerThread(context));
624 base::File::Error error =
625 GetFileInfoSync(context, url, file_info, platform_path);
626 if (error == base::File::FILE_OK && file_info->is_directory)
627 error = base::File::FILE_ERROR_NOT_A_FILE;
628 if (error == base::File::FILE_OK)
629 error = NativeMediaFileUtil::IsMediaFile(*platform_path);
631 // We're just returning the local file information.
632 *file_ref = scoped_refptr<storage::ShareableFileReference>();
634 return error;
637 base::File::Error NativeMediaFileUtil::GetFilteredLocalFilePath(
638 storage::FileSystemOperationContext* context,
639 const storage::FileSystemURL& file_system_url,
640 base::FilePath* local_file_path) {
641 DCHECK(IsOnTaskRunnerThread(context));
642 base::FilePath file_path;
643 base::File::Error error =
644 GetLocalFilePath(context, file_system_url, &file_path);
645 if (error != base::File::FILE_OK)
646 return error;
647 if (!media_path_filter_->Match(file_path))
648 return base::File::FILE_ERROR_SECURITY;
650 *local_file_path = file_path;
651 return base::File::FILE_OK;
654 base::File::Error
655 NativeMediaFileUtil::GetFilteredLocalFilePathForExistingFileOrDirectory(
656 storage::FileSystemOperationContext* context,
657 const storage::FileSystemURL& file_system_url,
658 base::File::Error failure_error,
659 base::FilePath* local_file_path) {
660 DCHECK(IsOnTaskRunnerThread(context));
661 base::FilePath file_path;
662 base::File::Error error =
663 GetLocalFilePath(context, file_system_url, &file_path);
664 if (error != base::File::FILE_OK)
665 return error;
667 if (!base::PathExists(file_path))
668 return failure_error;
669 base::File::Info file_info;
670 if (!base::GetFileInfo(file_path, &file_info))
671 return base::File::FILE_ERROR_FAILED;
673 if (!file_info.is_directory &&
674 !media_path_filter_->Match(file_path)) {
675 return failure_error;
678 *local_file_path = file_path;
679 return base::File::FILE_OK;