native_media_file_util.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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. 4 5#include "chrome/browser/media_galleries/fileapi/native_media_file_util.h" 6 7#include <string> 8 9#include "base/bind.h" 10#include "base/bind_helpers.h" 11#include "base/file_util.h" 12#include "base/files/file_enumerator.h" 13#include "base/files/scoped_platform_file_closer.h" 14#include "base/strings/string_util.h" 15#include "base/task_runner_util.h" 16#include "chrome/browser/media_galleries/fileapi/media_path_filter.h" 17#include "content/public/browser/browser_thread.h" 18#include "net/base/mime_sniffer.h" 19#include "url/gurl.h" 20#include "webkit/browser/fileapi/file_system_context.h" 21#include "webkit/browser/fileapi/file_system_operation_context.h" 22#include "webkit/browser/fileapi/native_file_util.h" 23#include "webkit/common/blob/shareable_file_reference.h" 24 25namespace { 26 27// Used to skip the hidden folders and files. Returns true if the file specified 28// by |path| should be skipped. 29bool ShouldSkip(const base::FilePath& path) { 30 const base::FilePath::StringType base_name = path.BaseName().value(); 31 if (base_name.empty()) 32 return false; 33 34 // Dot files (aka hidden files) 35 if (base_name[0] == '.') 36 return true; 37 38 // Mac OS X file. 39 if (base_name == FILE_PATH_LITERAL("__MACOSX")) 40 return true; 41 42#if defined(OS_WIN) 43 DWORD file_attributes = ::GetFileAttributes(path.value().c_str()); 44 if ((file_attributes != INVALID_FILE_ATTRIBUTES) && 45 ((file_attributes & FILE_ATTRIBUTE_HIDDEN) != 0)) 46 return true; 47#else 48 // Windows always creates a recycle bin folder in the attached device to store 49 // all the deleted contents. On non-windows operating systems, there is no way 50 // to get the hidden attribute of windows recycle bin folders that are present 51 // on the attached device. Therefore, compare the file path name to the 52 // recycle bin name and exclude those folders. For more details, please refer 53 // to http://support.microsoft.com/kb/171694. 54 const char win_98_recycle_bin_name[] = "RECYCLED"; 55 const char win_xp_recycle_bin_name[] = "RECYCLER"; 56 const char win_vista_recycle_bin_name[] = "$Recycle.bin"; 57 if ((base::strncasecmp(base_name.c_str(), 58 win_98_recycle_bin_name, 59 strlen(win_98_recycle_bin_name)) == 0) || 60 (base::strncasecmp(base_name.c_str(), 61 win_xp_recycle_bin_name, 62 strlen(win_xp_recycle_bin_name)) == 0) || 63 (base::strncasecmp(base_name.c_str(), 64 win_vista_recycle_bin_name, 65 strlen(win_vista_recycle_bin_name)) == 0)) 66 return true; 67#endif 68 return false; 69} 70 71// Returns true if the current thread is capable of doing IO. 72bool IsOnTaskRunnerThread(fileapi::FileSystemOperationContext* context) { 73 return context->task_runner()->RunsTasksOnCurrentThread(); 74} 75 76} // namespace 77 78NativeMediaFileUtil::NativeMediaFileUtil(MediaPathFilter* media_path_filter) 79 : weak_factory_(this), 80 media_path_filter_(media_path_filter) { 81} 82 83NativeMediaFileUtil::~NativeMediaFileUtil() { 84} 85 86// static 87base::PlatformFileError NativeMediaFileUtil::IsMediaFile( 88 const base::FilePath& path) { 89 base::PlatformFile file_handle; 90 const int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; 91 base::PlatformFileError error = 92 fileapi::NativeFileUtil::CreateOrOpen(path, flags, &file_handle, NULL); 93 if (error != base::PLATFORM_FILE_OK) 94 return error; 95 96 base::ScopedPlatformFileCloser scoped_platform_file(&file_handle); 97 char buffer[net::kMaxBytesToSniff]; 98 99 // Read as much as net::SniffMimeTypeFromLocalData() will bother looking at. 100 int64 len = 101 base::ReadPlatformFile(file_handle, 0, buffer, net::kMaxBytesToSniff); 102 if (len < 0) 103 return base::PLATFORM_FILE_ERROR_FAILED; 104 if (len == 0) 105 return base::PLATFORM_FILE_ERROR_SECURITY; 106 107 std::string mime_type; 108 if (!net::SniffMimeTypeFromLocalData(buffer, len, &mime_type)) 109 return base::PLATFORM_FILE_ERROR_SECURITY; 110 111 if (StartsWithASCII(mime_type, "image/", true) || 112 StartsWithASCII(mime_type, "audio/", true) || 113 StartsWithASCII(mime_type, "video/", true) || 114 mime_type == "application/x-shockwave-flash") { 115 return base::PLATFORM_FILE_OK; 116 } 117 return base::PLATFORM_FILE_ERROR_SECURITY; 118} 119 120void NativeMediaFileUtil::CreateOrOpen( 121 scoped_ptr<fileapi::FileSystemOperationContext> context, 122 const fileapi::FileSystemURL& url, 123 int file_flags, 124 const CreateOrOpenCallback& callback) { 125 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 126 // Only called by NaCl, which should not have access to media file systems. 127 base::PlatformFile invalid_file(base::kInvalidPlatformFileValue); 128 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, 129 base::PassPlatformFile(&invalid_file), 130 base::Closure()); 131} 132 133void NativeMediaFileUtil::EnsureFileExists( 134 scoped_ptr<fileapi::FileSystemOperationContext> context, 135 const fileapi::FileSystemURL& url, 136 const EnsureFileExistsCallback& callback) { 137 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 138 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, false); 139} 140 141void NativeMediaFileUtil::CreateDirectory( 142 scoped_ptr<fileapi::FileSystemOperationContext> context, 143 const fileapi::FileSystemURL& url, 144 bool exclusive, 145 bool recursive, 146 const StatusCallback& callback) { 147 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 148 fileapi::FileSystemOperationContext* context_ptr = context.get(); 149 const bool success = context_ptr->task_runner()->PostTask( 150 FROM_HERE, 151 base::Bind(&NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread, 152 weak_factory_.GetWeakPtr(), base::Passed(&context), 153 url, exclusive, recursive, callback)); 154 DCHECK(success); 155} 156 157void NativeMediaFileUtil::GetFileInfo( 158 scoped_ptr<fileapi::FileSystemOperationContext> context, 159 const fileapi::FileSystemURL& url, 160 const GetFileInfoCallback& callback) { 161 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 162 fileapi::FileSystemOperationContext* context_ptr = context.get(); 163 const bool success = context_ptr->task_runner()->PostTask( 164 FROM_HERE, 165 base::Bind(&NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread, 166 weak_factory_.GetWeakPtr(), base::Passed(&context), 167 url, callback)); 168 DCHECK(success); 169} 170 171void NativeMediaFileUtil::ReadDirectory( 172 scoped_ptr<fileapi::FileSystemOperationContext> context, 173 const fileapi::FileSystemURL& url, 174 const ReadDirectoryCallback& callback) { 175 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 176 fileapi::FileSystemOperationContext* context_ptr = context.get(); 177 const bool success = context_ptr->task_runner()->PostTask( 178 FROM_HERE, 179 base::Bind(&NativeMediaFileUtil::ReadDirectoryOnTaskRunnerThread, 180 weak_factory_.GetWeakPtr(), base::Passed(&context), 181 url, callback)); 182 DCHECK(success); 183} 184 185void NativeMediaFileUtil::Touch( 186 scoped_ptr<fileapi::FileSystemOperationContext> context, 187 const fileapi::FileSystemURL& url, 188 const base::Time& last_access_time, 189 const base::Time& last_modified_time, 190 const StatusCallback& callback) { 191 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 192 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); 193} 194 195void NativeMediaFileUtil::Truncate( 196 scoped_ptr<fileapi::FileSystemOperationContext> context, 197 const fileapi::FileSystemURL& url, 198 int64 length, 199 const StatusCallback& callback) { 200 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 201 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); 202} 203 204void NativeMediaFileUtil::CopyFileLocal( 205 scoped_ptr<fileapi::FileSystemOperationContext> context, 206 const fileapi::FileSystemURL& src_url, 207 const fileapi::FileSystemURL& dest_url, 208 const CopyFileProgressCallback& progress_callback, 209 const StatusCallback& callback) { 210 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 211 fileapi::FileSystemOperationContext* context_ptr = context.get(); 212 const bool success = context_ptr->task_runner()->PostTask( 213 FROM_HERE, 214 base::Bind(&NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread, 215 weak_factory_.GetWeakPtr(), base::Passed(&context), 216 src_url, dest_url, true /* copy */, callback)); 217 DCHECK(success); 218} 219 220void NativeMediaFileUtil::MoveFileLocal( 221 scoped_ptr<fileapi::FileSystemOperationContext> context, 222 const fileapi::FileSystemURL& src_url, 223 const fileapi::FileSystemURL& dest_url, 224 const StatusCallback& callback) { 225 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 226 fileapi::FileSystemOperationContext* context_ptr = context.get(); 227 const bool success = context_ptr->task_runner()->PostTask( 228 FROM_HERE, 229 base::Bind(&NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread, 230 weak_factory_.GetWeakPtr(), base::Passed(&context), 231 src_url, dest_url, false /* copy */, callback)); 232 DCHECK(success); 233} 234 235void NativeMediaFileUtil::CopyInForeignFile( 236 scoped_ptr<fileapi::FileSystemOperationContext> context, 237 const base::FilePath& src_file_path, 238 const fileapi::FileSystemURL& dest_url, 239 const StatusCallback& callback) { 240 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 241 fileapi::FileSystemOperationContext* context_ptr = context.get(); 242 const bool success = context_ptr->task_runner()->PostTask( 243 FROM_HERE, 244 base::Bind(&NativeMediaFileUtil::CopyInForeignFileOnTaskRunnerThread, 245 weak_factory_.GetWeakPtr(), base::Passed(&context), 246 src_file_path, dest_url, callback)); 247 DCHECK(success); 248} 249 250void NativeMediaFileUtil::DeleteFile( 251 scoped_ptr<fileapi::FileSystemOperationContext> context, 252 const fileapi::FileSystemURL& url, 253 const StatusCallback& callback) { 254 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 255 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); 256} 257 258// This is needed to support Copy and Move. 259void NativeMediaFileUtil::DeleteDirectory( 260 scoped_ptr<fileapi::FileSystemOperationContext> context, 261 const fileapi::FileSystemURL& url, 262 const StatusCallback& callback) { 263 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 264 fileapi::FileSystemOperationContext* context_ptr = context.get(); 265 const bool success = context_ptr->task_runner()->PostTask( 266 FROM_HERE, 267 base::Bind(&NativeMediaFileUtil::DeleteDirectoryOnTaskRunnerThread, 268 weak_factory_.GetWeakPtr(), base::Passed(&context), 269 url, callback)); 270 DCHECK(success); 271} 272 273void NativeMediaFileUtil::DeleteRecursively( 274 scoped_ptr<fileapi::FileSystemOperationContext> context, 275 const fileapi::FileSystemURL& url, 276 const StatusCallback& callback) { 277 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 278 callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); 279} 280 281void NativeMediaFileUtil::CreateSnapshotFile( 282 scoped_ptr<fileapi::FileSystemOperationContext> context, 283 const fileapi::FileSystemURL& url, 284 const CreateSnapshotFileCallback& callback) { 285 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 286 fileapi::FileSystemOperationContext* context_ptr = context.get(); 287 const bool success = context_ptr->task_runner()->PostTask( 288 FROM_HERE, 289 base::Bind(&NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread, 290 weak_factory_.GetWeakPtr(), base::Passed(&context), 291 url, callback)); 292 DCHECK(success); 293} 294 295void NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread( 296 scoped_ptr<fileapi::FileSystemOperationContext> context, 297 const fileapi::FileSystemURL& url, 298 bool exclusive, 299 bool recursive, 300 const StatusCallback& callback) { 301 DCHECK(IsOnTaskRunnerThread(context.get())); 302 base::PlatformFileError error = 303 CreateDirectorySync(context.get(), url, exclusive, recursive); 304 content::BrowserThread::PostTask( 305 content::BrowserThread::IO, 306 FROM_HERE, 307 base::Bind(callback, error)); 308} 309 310void NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread( 311 scoped_ptr<fileapi::FileSystemOperationContext> context, 312 const fileapi::FileSystemURL& url, 313 const GetFileInfoCallback& callback) { 314 DCHECK(IsOnTaskRunnerThread(context.get())); 315 base::PlatformFileInfo file_info; 316 base::PlatformFileError error = 317 GetFileInfoSync(context.get(), url, &file_info, NULL); 318 content::BrowserThread::PostTask( 319 content::BrowserThread::IO, 320 FROM_HERE, 321 base::Bind(callback, error, file_info)); 322} 323 324void NativeMediaFileUtil::ReadDirectoryOnTaskRunnerThread( 325 scoped_ptr<fileapi::FileSystemOperationContext> context, 326 const fileapi::FileSystemURL& url, 327 const ReadDirectoryCallback& callback) { 328 DCHECK(IsOnTaskRunnerThread(context.get())); 329 EntryList entry_list; 330 base::PlatformFileError error = 331 ReadDirectorySync(context.get(), url, &entry_list); 332 content::BrowserThread::PostTask( 333 content::BrowserThread::IO, 334 FROM_HERE, 335 base::Bind(callback, error, entry_list, false /* has_more */)); 336} 337 338void NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread( 339 scoped_ptr<fileapi::FileSystemOperationContext> context, 340 const fileapi::FileSystemURL& src_url, 341 const fileapi::FileSystemURL& dest_url, 342 bool copy, 343 const StatusCallback& callback) { 344 DCHECK(IsOnTaskRunnerThread(context.get())); 345 base::PlatformFileError error = 346 CopyOrMoveFileSync(context.get(), src_url, dest_url, copy); 347 content::BrowserThread::PostTask( 348 content::BrowserThread::IO, 349 FROM_HERE, 350 base::Bind(callback, error)); 351} 352 353void NativeMediaFileUtil::CopyInForeignFileOnTaskRunnerThread( 354 scoped_ptr<fileapi::FileSystemOperationContext> context, 355 const base::FilePath& src_file_path, 356 const fileapi::FileSystemURL& dest_url, 357 const StatusCallback& callback) { 358 DCHECK(IsOnTaskRunnerThread(context.get())); 359 base::PlatformFileError error = 360 CopyInForeignFileSync(context.get(), src_file_path, dest_url); 361 content::BrowserThread::PostTask( 362 content::BrowserThread::IO, 363 FROM_HERE, 364 base::Bind(callback, error)); 365} 366 367void NativeMediaFileUtil::DeleteDirectoryOnTaskRunnerThread( 368 scoped_ptr<fileapi::FileSystemOperationContext> context, 369 const fileapi::FileSystemURL& url, 370 const StatusCallback& callback) { 371 DCHECK(IsOnTaskRunnerThread(context.get())); 372 base::PlatformFileError error = DeleteDirectorySync(context.get(), url); 373 content::BrowserThread::PostTask( 374 content::BrowserThread::IO, 375 FROM_HERE, 376 base::Bind(callback, error)); 377} 378 379void NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread( 380 scoped_ptr<fileapi::FileSystemOperationContext> context, 381 const fileapi::FileSystemURL& url, 382 const CreateSnapshotFileCallback& callback) { 383 DCHECK(IsOnTaskRunnerThread(context.get())); 384 base::PlatformFileInfo file_info; 385 base::FilePath platform_path; 386 scoped_refptr<webkit_blob::ShareableFileReference> file_ref; 387 base::PlatformFileError error = 388 CreateSnapshotFileSync(context.get(), url, &file_info, &platform_path, 389 &file_ref); 390 content::BrowserThread::PostTask( 391 content::BrowserThread::IO, 392 FROM_HERE, 393 base::Bind(callback, error, file_info, platform_path, file_ref)); 394} 395 396base::PlatformFileError NativeMediaFileUtil::CreateDirectorySync( 397 fileapi::FileSystemOperationContext* context, 398 const fileapi::FileSystemURL& url, 399 bool exclusive, 400 bool recursive) { 401 base::FilePath file_path; 402 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); 403 if (error != base::PLATFORM_FILE_OK) 404 return error; 405 return fileapi::NativeFileUtil::CreateDirectory(file_path, exclusive, 406 recursive); 407} 408 409base::PlatformFileError NativeMediaFileUtil::CopyOrMoveFileSync( 410 fileapi::FileSystemOperationContext* context, 411 const fileapi::FileSystemURL& src_url, 412 const fileapi::FileSystemURL& dest_url, 413 bool copy) { 414 DCHECK(IsOnTaskRunnerThread(context)); 415 base::FilePath src_file_path; 416 base::PlatformFileError error = 417 GetFilteredLocalFilePathForExistingFileOrDirectory( 418 context, src_url, 419 base::PLATFORM_FILE_ERROR_NOT_FOUND, 420 &src_file_path); 421 if (error != base::PLATFORM_FILE_OK) 422 return error; 423 if (fileapi::NativeFileUtil::DirectoryExists(src_file_path)) 424 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; 425 426 base::FilePath dest_file_path; 427 error = GetLocalFilePath(context, dest_url, &dest_file_path); 428 if (error != base::PLATFORM_FILE_OK) 429 return error; 430 base::PlatformFileInfo file_info; 431 error = fileapi::NativeFileUtil::GetFileInfo(dest_file_path, &file_info); 432 if (error != base::PLATFORM_FILE_OK && 433 error != base::PLATFORM_FILE_ERROR_NOT_FOUND) 434 return error; 435 if (error == base::PLATFORM_FILE_OK && file_info.is_directory) 436 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 437 if (!media_path_filter_->Match(dest_file_path)) 438 return base::PLATFORM_FILE_ERROR_SECURITY; 439 440 return fileapi::NativeFileUtil::CopyOrMoveFile(src_file_path, dest_file_path, 441 copy); 442} 443 444base::PlatformFileError NativeMediaFileUtil::CopyInForeignFileSync( 445 fileapi::FileSystemOperationContext* context, 446 const base::FilePath& src_file_path, 447 const fileapi::FileSystemURL& dest_url) { 448 DCHECK(IsOnTaskRunnerThread(context)); 449 if (src_file_path.empty()) 450 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; 451 452 base::FilePath dest_file_path; 453 base::PlatformFileError error = 454 GetFilteredLocalFilePath(context, dest_url, &dest_file_path); 455 if (error != base::PLATFORM_FILE_OK) 456 return error; 457 return fileapi::NativeFileUtil::CopyOrMoveFile(src_file_path, dest_file_path, 458 true); 459} 460 461base::PlatformFileError NativeMediaFileUtil::GetFileInfoSync( 462 fileapi::FileSystemOperationContext* context, 463 const fileapi::FileSystemURL& url, 464 base::PlatformFileInfo* file_info, 465 base::FilePath* platform_path) { 466 DCHECK(context); 467 DCHECK(IsOnTaskRunnerThread(context)); 468 DCHECK(file_info); 469 470 base::FilePath file_path; 471 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); 472 if (error != base::PLATFORM_FILE_OK) 473 return error; 474 if (file_util::IsLink(file_path)) 475 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 476 error = fileapi::NativeFileUtil::GetFileInfo(file_path, file_info); 477 if (error != base::PLATFORM_FILE_OK) 478 return error; 479 480 if (platform_path) 481 *platform_path = file_path; 482 if (file_info->is_directory || 483 media_path_filter_->Match(file_path)) { 484 return base::PLATFORM_FILE_OK; 485 } 486 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 487} 488 489base::PlatformFileError NativeMediaFileUtil::GetLocalFilePath( 490 fileapi::FileSystemOperationContext* context, 491 const fileapi::FileSystemURL& url, 492 base::FilePath* local_file_path) { 493 DCHECK(local_file_path); 494 DCHECK(url.is_valid()); 495 if (url.path().empty()) { 496 // Root direcory case, which should not be accessed. 497 return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; 498 } 499 *local_file_path = url.path(); 500 return base::PLATFORM_FILE_OK; 501} 502 503base::PlatformFileError NativeMediaFileUtil::ReadDirectorySync( 504 fileapi::FileSystemOperationContext* context, 505 const fileapi::FileSystemURL& url, 506 EntryList* file_list) { 507 DCHECK(IsOnTaskRunnerThread(context)); 508 DCHECK(file_list); 509 DCHECK(file_list->empty()); 510 base::PlatformFileInfo file_info; 511 base::FilePath dir_path; 512 base::PlatformFileError error = 513 GetFileInfoSync(context, url, &file_info, &dir_path); 514 515 if (error != base::PLATFORM_FILE_OK) 516 return error; 517 518 if (!file_info.is_directory) 519 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; 520 521 base::FileEnumerator file_enum( 522 dir_path, 523 false /* recursive */, 524 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES); 525 for (base::FilePath enum_path = file_enum.Next(); 526 !enum_path.empty(); 527 enum_path = file_enum.Next()) { 528 // Skip symlinks. 529 if (file_util::IsLink(enum_path)) 530 continue; 531 532 base::FileEnumerator::FileInfo info = file_enum.GetInfo(); 533 534 // NativeMediaFileUtil skip criteria. 535 if (ShouldSkip(enum_path)) 536 continue; 537 if (!info.IsDirectory() && !media_path_filter_->Match(enum_path)) 538 continue; 539 540 fileapi::DirectoryEntry entry; 541 entry.is_directory = info.IsDirectory(); 542 entry.name = enum_path.BaseName().value(); 543 entry.size = info.GetSize(); 544 entry.last_modified_time = info.GetLastModifiedTime(); 545 546 file_list->push_back(entry); 547 } 548 549 return base::PLATFORM_FILE_OK; 550} 551 552base::PlatformFileError NativeMediaFileUtil::DeleteDirectorySync( 553 fileapi::FileSystemOperationContext* context, 554 const fileapi::FileSystemURL& url) { 555 DCHECK(IsOnTaskRunnerThread(context)); 556 base::FilePath file_path; 557 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); 558 if (error != base::PLATFORM_FILE_OK) 559 return error; 560 return fileapi::NativeFileUtil::DeleteDirectory(file_path); 561} 562 563base::PlatformFileError NativeMediaFileUtil::CreateSnapshotFileSync( 564 fileapi::FileSystemOperationContext* context, 565 const fileapi::FileSystemURL& url, 566 base::PlatformFileInfo* file_info, 567 base::FilePath* platform_path, 568 scoped_refptr<webkit_blob::ShareableFileReference>* file_ref) { 569 DCHECK(IsOnTaskRunnerThread(context)); 570 base::PlatformFileError error = 571 GetFileInfoSync(context, url, file_info, platform_path); 572 if (error == base::PLATFORM_FILE_OK && file_info->is_directory) 573 error = base::PLATFORM_FILE_ERROR_NOT_A_FILE; 574 if (error == base::PLATFORM_FILE_OK) 575 error = NativeMediaFileUtil::IsMediaFile(*platform_path); 576 577 // We're just returning the local file information. 578 *file_ref = scoped_refptr<webkit_blob::ShareableFileReference>(); 579 580 return error; 581} 582 583base::PlatformFileError NativeMediaFileUtil::GetFilteredLocalFilePath( 584 fileapi::FileSystemOperationContext* context, 585 const fileapi::FileSystemURL& file_system_url, 586 base::FilePath* local_file_path) { 587 DCHECK(IsOnTaskRunnerThread(context)); 588 base::FilePath file_path; 589 base::PlatformFileError error = 590 GetLocalFilePath(context, file_system_url, &file_path); 591 if (error != base::PLATFORM_FILE_OK) 592 return error; 593 if (!media_path_filter_->Match(file_path)) 594 return base::PLATFORM_FILE_ERROR_SECURITY; 595 596 *local_file_path = file_path; 597 return base::PLATFORM_FILE_OK; 598} 599 600base::PlatformFileError 601NativeMediaFileUtil::GetFilteredLocalFilePathForExistingFileOrDirectory( 602 fileapi::FileSystemOperationContext* context, 603 const fileapi::FileSystemURL& file_system_url, 604 base::PlatformFileError failure_error, 605 base::FilePath* local_file_path) { 606 DCHECK(IsOnTaskRunnerThread(context)); 607 base::FilePath file_path; 608 base::PlatformFileError error = 609 GetLocalFilePath(context, file_system_url, &file_path); 610 if (error != base::PLATFORM_FILE_OK) 611 return error; 612 613 if (!base::PathExists(file_path)) 614 return failure_error; 615 base::PlatformFileInfo file_info; 616 if (!file_util::GetFileInfo(file_path, &file_info)) 617 return base::PLATFORM_FILE_ERROR_FAILED; 618 619 if (!file_info.is_directory && 620 !media_path_filter_->Match(file_path)) { 621 return failure_error; 622 } 623 624 *local_file_path = file_path; 625 return base::PLATFORM_FILE_OK; 626} 627