| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/media_galleries/fileapi/native_media_file_util.h" | 5 #include "chrome/browser/media_galleries/fileapi/native_media_file_util.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/task_runner_util.h" | 10 #include "base/task_runner_util.h" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 } | 91 } |
| 92 | 92 |
| 93 } // namespace | 93 } // namespace |
| 94 | 94 |
| 95 NativeMediaFileUtil::NativeMediaFileUtil() : weak_factory_(this) { | 95 NativeMediaFileUtil::NativeMediaFileUtil() : weak_factory_(this) { |
| 96 } | 96 } |
| 97 | 97 |
| 98 NativeMediaFileUtil::~NativeMediaFileUtil() { | 98 NativeMediaFileUtil::~NativeMediaFileUtil() { |
| 99 } | 99 } |
| 100 | 100 |
| 101 // static |
| 102 base::PlatformFileError NativeMediaFileUtil::IsMediaFile( |
| 103 const base::FilePath& path) { |
| 104 base::PlatformFile file_handle; |
| 105 const int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; |
| 106 base::PlatformFileError error = |
| 107 fileapi::NativeFileUtil::CreateOrOpen(path, flags, &file_handle, NULL); |
| 108 if (error != base::PLATFORM_FILE_OK) |
| 109 return error; |
| 110 |
| 111 ScopedPlatformFile scoped_platform_file(&file_handle); |
| 112 char buffer[net::kMaxBytesToSniff]; |
| 113 |
| 114 // Read as much as net::SniffMimeTypeFromLocalData() will bother looking at. |
| 115 int64 len = |
| 116 base::ReadPlatformFile(file_handle, 0, buffer, net::kMaxBytesToSniff); |
| 117 if (len < 0) |
| 118 return base::PLATFORM_FILE_ERROR_FAILED; |
| 119 if (len == 0) |
| 120 return base::PLATFORM_FILE_ERROR_SECURITY; |
| 121 |
| 122 std::string mime_type; |
| 123 if (!net::SniffMimeTypeFromLocalData(buffer, len, &mime_type)) |
| 124 return base::PLATFORM_FILE_ERROR_SECURITY; |
| 125 |
| 126 if (StartsWithASCII(mime_type, "image/", true) || |
| 127 StartsWithASCII(mime_type, "audio/", true) || |
| 128 StartsWithASCII(mime_type, "video/", true) || |
| 129 mime_type == "application/x-shockwave-flash") { |
| 130 return base::PLATFORM_FILE_OK; |
| 131 } |
| 132 return base::PLATFORM_FILE_ERROR_SECURITY; |
| 133 } |
| 134 |
| 101 bool NativeMediaFileUtil::CreateOrOpen( | 135 bool NativeMediaFileUtil::CreateOrOpen( |
| 102 fileapi::FileSystemOperationContext* context, | 136 fileapi::FileSystemOperationContext* context, |
| 103 const fileapi::FileSystemURL& url, | 137 const fileapi::FileSystemURL& url, |
| 104 int file_flags, | 138 int file_flags, |
| 105 const CreateOrOpenCallback& callback) { | 139 const CreateOrOpenCallback& callback) { |
| 106 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 140 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 107 // Only called by NaCl, which should not have access to media file systems. | 141 // Only called by NaCl, which should not have access to media file systems. |
| 108 base::PlatformFile invalid_file(base::kInvalidPlatformFileValue); | 142 base::PlatformFile invalid_file(base::kInvalidPlatformFileValue); |
| 109 if (!callback.is_null()) { | 143 if (!callback.is_null()) { |
| 110 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, | 144 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 127 bool NativeMediaFileUtil::CreateDirectory( | 161 bool NativeMediaFileUtil::CreateDirectory( |
| 128 fileapi::FileSystemOperationContext* context, | 162 fileapi::FileSystemOperationContext* context, |
| 129 const fileapi::FileSystemURL& url, | 163 const fileapi::FileSystemURL& url, |
| 130 bool exclusive, | 164 bool exclusive, |
| 131 bool recursive, | 165 bool recursive, |
| 132 const StatusCallback& callback) { | 166 const StatusCallback& callback) { |
| 133 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 167 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 134 return context->task_runner()->PostTask( | 168 return context->task_runner()->PostTask( |
| 135 FROM_HERE, | 169 FROM_HERE, |
| 136 base::Bind(&NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread, | 170 base::Bind(&NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread, |
| 137 weak_factory_.GetWeakPtr(), context, url, exclusive, | 171 weak_factory_.GetWeakPtr(), context, url, exclusive, recursive, |
| 138 recursive, callback)); | 172 callback)); |
| 139 } | 173 } |
| 140 | 174 |
| 141 bool NativeMediaFileUtil::GetFileInfo( | 175 bool NativeMediaFileUtil::GetFileInfo( |
| 142 fileapi::FileSystemOperationContext* context, | 176 fileapi::FileSystemOperationContext* context, |
| 143 const fileapi::FileSystemURL& url, | 177 const fileapi::FileSystemURL& url, |
| 144 const GetFileInfoCallback& callback) { | 178 const GetFileInfoCallback& callback) { |
| 145 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 179 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 146 return context->task_runner()->PostTask( | 180 return context->task_runner()->PostTask( |
| 147 FROM_HERE, | 181 FROM_HERE, |
| 148 base::Bind(&NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread, | 182 base::Bind(&NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread, |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 fileapi::FileSystemOperationContext* context, | 282 fileapi::FileSystemOperationContext* context, |
| 249 const fileapi::FileSystemURL& url, | 283 const fileapi::FileSystemURL& url, |
| 250 const CreateSnapshotFileCallback& callback) { | 284 const CreateSnapshotFileCallback& callback) { |
| 251 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 285 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 252 return context->task_runner()->PostTask( | 286 return context->task_runner()->PostTask( |
| 253 FROM_HERE, | 287 FROM_HERE, |
| 254 base::Bind(&NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread, | 288 base::Bind(&NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread, |
| 255 weak_factory_.GetWeakPtr(), context, url, callback)); | 289 weak_factory_.GetWeakPtr(), context, url, callback)); |
| 256 } | 290 } |
| 257 | 291 |
| 292 void NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread( |
| 293 fileapi::FileSystemOperationContext* context, |
| 294 const fileapi::FileSystemURL& url, |
| 295 bool exclusive, |
| 296 bool recursive, |
| 297 const StatusCallback& callback) { |
| 298 DCHECK(IsOnTaskRunnerThread(context)); |
| 299 base::PlatformFileError error = |
| 300 CreateDirectorySync(context, url, exclusive, recursive); |
| 301 if (callback.is_null()) |
| 302 return; |
| 303 content::BrowserThread::PostTask( |
| 304 content::BrowserThread::IO, |
| 305 FROM_HERE, |
| 306 base::Bind(callback, error)); |
| 307 } |
| 308 |
| 309 void NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread( |
| 310 fileapi::FileSystemOperationContext* context, |
| 311 const fileapi::FileSystemURL& url, |
| 312 const GetFileInfoCallback& callback) { |
| 313 DCHECK(IsOnTaskRunnerThread(context)); |
| 314 base::PlatformFileInfo file_info; |
| 315 base::FilePath platform_path; |
| 316 base::PlatformFileError error = |
| 317 GetFileInfoSync(context, url, &file_info, &platform_path); |
| 318 if (callback.is_null()) |
| 319 return; |
| 320 content::BrowserThread::PostTask( |
| 321 content::BrowserThread::IO, |
| 322 FROM_HERE, |
| 323 base::Bind(callback, error, file_info, platform_path)); |
| 324 } |
| 325 |
| 326 void NativeMediaFileUtil::ReadDirectoryOnTaskRunnerThread( |
| 327 fileapi::FileSystemOperationContext* context, |
| 328 const fileapi::FileSystemURL& url, |
| 329 const ReadDirectoryCallback& callback) { |
| 330 DCHECK(IsOnTaskRunnerThread(context)); |
| 331 EntryList entry_list; |
| 332 base::PlatformFileError error = |
| 333 ReadDirectorySync(context, url, &entry_list); |
| 334 if (callback.is_null()) |
| 335 return; |
| 336 content::BrowserThread::PostTask( |
| 337 content::BrowserThread::IO, |
| 338 FROM_HERE, |
| 339 base::Bind(callback, error, entry_list, false /* has_more */)); |
| 340 } |
| 341 |
| 342 void NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread( |
| 343 fileapi::FileSystemOperationContext* context, |
| 344 const fileapi::FileSystemURL& src_url, |
| 345 const fileapi::FileSystemURL& dest_url, |
| 346 bool copy, |
| 347 const StatusCallback& callback) { |
| 348 DCHECK(IsOnTaskRunnerThread(context)); |
| 349 base::PlatformFileError error = |
| 350 CopyOrMoveFileSync(context, src_url, dest_url, copy); |
| 351 if (callback.is_null()) |
| 352 return; |
| 353 content::BrowserThread::PostTask( |
| 354 content::BrowserThread::IO, |
| 355 FROM_HERE, |
| 356 base::Bind(callback, error)); |
| 357 } |
| 358 |
| 359 void NativeMediaFileUtil::CopyInForeignFileOnTaskRunnerThread( |
| 360 fileapi::FileSystemOperationContext* context, |
| 361 const base::FilePath& src_file_path, |
| 362 const fileapi::FileSystemURL& dest_url, |
| 363 const StatusCallback& callback) { |
| 364 DCHECK(IsOnTaskRunnerThread(context)); |
| 365 base::PlatformFileError error = |
| 366 CopyInForeignFileSync(context, src_file_path, dest_url); |
| 367 if (callback.is_null()) |
| 368 return; |
| 369 content::BrowserThread::PostTask( |
| 370 content::BrowserThread::IO, |
| 371 FROM_HERE, |
| 372 base::Bind(callback, error)); |
| 373 } |
| 374 |
| 375 void NativeMediaFileUtil::DeleteDirectoryOnTaskRunnerThread( |
| 376 fileapi::FileSystemOperationContext* context, |
| 377 const fileapi::FileSystemURL& url, |
| 378 const StatusCallback& callback) { |
| 379 DCHECK(IsOnTaskRunnerThread(context)); |
| 380 base::PlatformFileError error = DeleteDirectorySync(context, url); |
| 381 if (callback.is_null()) |
| 382 return; |
| 383 content::BrowserThread::PostTask( |
| 384 content::BrowserThread::IO, |
| 385 FROM_HERE, |
| 386 base::Bind(callback, error)); |
| 387 } |
| 388 |
| 389 void NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread( |
| 390 fileapi::FileSystemOperationContext* context, |
| 391 const fileapi::FileSystemURL& url, |
| 392 const CreateSnapshotFileCallback& callback) { |
| 393 DCHECK(IsOnTaskRunnerThread(context)); |
| 394 base::PlatformFileInfo file_info; |
| 395 base::FilePath platform_path; |
| 396 scoped_refptr<webkit_blob::ShareableFileReference> file_ref; |
| 397 base::PlatformFileError error = |
| 398 CreateSnapshotFileSync(context, url, &file_info, &platform_path, |
| 399 &file_ref); |
| 400 if (callback.is_null()) |
| 401 return; |
| 402 content::BrowserThread::PostTask( |
| 403 content::BrowserThread::IO, |
| 404 FROM_HERE, |
| 405 base::Bind(callback, error, file_info, platform_path, file_ref)); |
| 406 } |
| 407 |
| 258 base::PlatformFileError NativeMediaFileUtil::CreateDirectorySync( | 408 base::PlatformFileError NativeMediaFileUtil::CreateDirectorySync( |
| 259 fileapi::FileSystemOperationContext* context, | 409 fileapi::FileSystemOperationContext* context, |
| 260 const fileapi::FileSystemURL& url, | 410 const fileapi::FileSystemURL& url, |
| 261 bool exclusive, | 411 bool exclusive, |
| 262 bool recursive) { | 412 bool recursive) { |
| 263 base::FilePath file_path; | 413 base::FilePath file_path; |
| 264 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); | 414 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); |
| 265 if (error != base::PLATFORM_FILE_OK) | 415 if (error != base::PLATFORM_FILE_OK) |
| 266 return error; | 416 return error; |
| 267 return fileapi::NativeFileUtil::CreateDirectory(file_path, exclusive, | 417 return fileapi::NativeFileUtil::CreateDirectory(file_path, exclusive, |
| 268 recursive); | 418 recursive); |
| 269 } | 419 } |
| 270 | 420 |
| 271 base::PlatformFileError NativeMediaFileUtil::GetLocalFilePath( | |
| 272 fileapi::FileSystemOperationContext* context, | |
| 273 const fileapi::FileSystemURL& url, | |
| 274 base::FilePath* local_file_path) { | |
| 275 DCHECK(local_file_path); | |
| 276 DCHECK(url.is_valid()); | |
| 277 if (url.path().empty()) { | |
| 278 // Root direcory case, which should not be accessed. | |
| 279 return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; | |
| 280 } | |
| 281 *local_file_path = url.path(); | |
| 282 return base::PLATFORM_FILE_OK; | |
| 283 } | |
| 284 | |
| 285 base::PlatformFileError NativeMediaFileUtil::ReadDirectorySync( | |
| 286 fileapi::FileSystemOperationContext* context, | |
| 287 const fileapi::FileSystemURL& url, | |
| 288 EntryList* file_list) { | |
| 289 DCHECK(IsOnTaskRunnerThread(context)); | |
| 290 DCHECK(file_list); | |
| 291 DCHECK(file_list->empty()); | |
| 292 base::PlatformFileInfo file_info; | |
| 293 base::FilePath platform_path; | |
| 294 base::PlatformFileError error = GetFileInfoSync(context, url, &file_info, | |
| 295 &platform_path); | |
| 296 | |
| 297 if (error != base::PLATFORM_FILE_OK) | |
| 298 return error; | |
| 299 | |
| 300 if (!file_info.is_directory) | |
| 301 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | |
| 302 | |
| 303 file_util::FileEnumerator file_enum( | |
| 304 platform_path, | |
| 305 false /* recursive */, | |
| 306 file_util::FileEnumerator::FILES | | |
| 307 file_util::FileEnumerator::DIRECTORIES); | |
| 308 file_util::FileEnumerator::FindInfo file_util_info; | |
| 309 #if defined(OS_WIN) | |
| 310 memset(&file_util_info, 0, sizeof(file_util_info)); | |
| 311 #endif // defined(OS_WIN) | |
| 312 | |
| 313 for (base::FilePath platform_path = file_enum.Next(); | |
| 314 !platform_path.empty(); | |
| 315 platform_path = file_enum.Next()) { | |
| 316 // Skip symlinks. | |
| 317 if (file_util::IsLink(platform_path)) | |
| 318 continue; | |
| 319 | |
| 320 file_enum.GetFindInfo(&file_util_info); | |
| 321 | |
| 322 // NativeMediaFileUtil skip criteria. | |
| 323 if (ShouldSkip(platform_path)) | |
| 324 continue; | |
| 325 if (!file_util::FileEnumerator::IsDirectory(file_util_info) && | |
| 326 !GetMediaPathFilter(context)->Match(platform_path)) | |
| 327 continue; | |
| 328 | |
| 329 fileapi::DirectoryEntry entry; | |
| 330 entry.is_directory = file_util::FileEnumerator::IsDirectory(file_util_info); | |
| 331 entry.name = platform_path.BaseName().value(); | |
| 332 entry.size = file_util::FileEnumerator::GetFilesize(file_util_info); | |
| 333 entry.last_modified_time = | |
| 334 file_util::FileEnumerator::GetLastModifiedTime(file_util_info); | |
| 335 | |
| 336 file_list->push_back(entry); | |
| 337 } | |
| 338 | |
| 339 return base::PLATFORM_FILE_OK; | |
| 340 } | |
| 341 | |
| 342 base::PlatformFileError NativeMediaFileUtil::CopyOrMoveFileSync( | 421 base::PlatformFileError NativeMediaFileUtil::CopyOrMoveFileSync( |
| 343 fileapi::FileSystemOperationContext* context, | 422 fileapi::FileSystemOperationContext* context, |
| 344 const fileapi::FileSystemURL& src_url, | 423 const fileapi::FileSystemURL& src_url, |
| 345 const fileapi::FileSystemURL& dest_url, | 424 const fileapi::FileSystemURL& dest_url, |
| 346 bool copy) { | 425 bool copy) { |
| 347 DCHECK(IsOnTaskRunnerThread(context)); | 426 DCHECK(IsOnTaskRunnerThread(context)); |
| 348 base::FilePath src_file_path; | 427 base::FilePath src_file_path; |
| 349 base::PlatformFileError error = | 428 base::PlatformFileError error = |
| 350 GetFilteredLocalFilePathForExistingFileOrDirectory( | 429 GetFilteredLocalFilePathForExistingFileOrDirectory( |
| 351 context, src_url, | 430 context, src_url, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 | 463 |
| 385 base::FilePath dest_file_path; | 464 base::FilePath dest_file_path; |
| 386 base::PlatformFileError error = | 465 base::PlatformFileError error = |
| 387 GetFilteredLocalFilePath(context, dest_url, &dest_file_path); | 466 GetFilteredLocalFilePath(context, dest_url, &dest_file_path); |
| 388 if (error != base::PLATFORM_FILE_OK) | 467 if (error != base::PLATFORM_FILE_OK) |
| 389 return error; | 468 return error; |
| 390 return fileapi::NativeFileUtil::CopyOrMoveFile(src_file_path, dest_file_path, | 469 return fileapi::NativeFileUtil::CopyOrMoveFile(src_file_path, dest_file_path, |
| 391 true); | 470 true); |
| 392 } | 471 } |
| 393 | 472 |
| 394 base::PlatformFileError NativeMediaFileUtil::GetFilteredLocalFilePath( | |
| 395 fileapi::FileSystemOperationContext* context, | |
| 396 const fileapi::FileSystemURL& file_system_url, | |
| 397 base::FilePath* local_file_path) { | |
| 398 DCHECK(IsOnTaskRunnerThread(context)); | |
| 399 base::FilePath file_path; | |
| 400 base::PlatformFileError error = | |
| 401 GetLocalFilePath(context, file_system_url, &file_path); | |
| 402 if (error != base::PLATFORM_FILE_OK) | |
| 403 return error; | |
| 404 if (!GetMediaPathFilter(context)->Match(file_path)) | |
| 405 return base::PLATFORM_FILE_ERROR_SECURITY; | |
| 406 | |
| 407 *local_file_path = file_path; | |
| 408 return base::PLATFORM_FILE_OK; | |
| 409 } | |
| 410 | |
| 411 base::PlatformFileError NativeMediaFileUtil::GetFileInfoSync( | 473 base::PlatformFileError NativeMediaFileUtil::GetFileInfoSync( |
| 412 fileapi::FileSystemOperationContext* context, | 474 fileapi::FileSystemOperationContext* context, |
| 413 const fileapi::FileSystemURL& url, | 475 const fileapi::FileSystemURL& url, |
| 414 base::PlatformFileInfo* file_info, | 476 base::PlatformFileInfo* file_info, |
| 415 base::FilePath* platform_path) { | 477 base::FilePath* platform_path) { |
| 416 DCHECK(IsOnTaskRunnerThread(context)); | 478 DCHECK(IsOnTaskRunnerThread(context)); |
| 417 DCHECK(context); | 479 DCHECK(context); |
| 418 DCHECK(file_info); | 480 DCHECK(file_info); |
| 419 DCHECK(GetMediaPathFilter(context)); | 481 DCHECK(GetMediaPathFilter(context)); |
| 420 | 482 |
| 421 base::FilePath file_path; | 483 base::FilePath file_path; |
| 422 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); | 484 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); |
| 423 if (error != base::PLATFORM_FILE_OK) | 485 if (error != base::PLATFORM_FILE_OK) |
| 424 return error; | 486 return error; |
| 425 if (file_util::IsLink(file_path)) | 487 if (file_util::IsLink(file_path)) |
| 426 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 488 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 427 error = fileapi::NativeFileUtil::GetFileInfo(file_path, file_info); | 489 error = fileapi::NativeFileUtil::GetFileInfo(file_path, file_info); |
| 428 if (error != base::PLATFORM_FILE_OK) | 490 if (error != base::PLATFORM_FILE_OK) |
| 429 return error; | 491 return error; |
| 430 | 492 |
| 431 if (platform_path) | 493 if (platform_path) |
| 432 *platform_path = file_path; | 494 *platform_path = file_path; |
| 433 if (file_info->is_directory || | 495 if (file_info->is_directory || |
| 434 GetMediaPathFilter(context)->Match(file_path)) { | 496 GetMediaPathFilter(context)->Match(file_path)) { |
| 435 return base::PLATFORM_FILE_OK; | 497 return base::PLATFORM_FILE_OK; |
| 436 } | 498 } |
| 437 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | 499 return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
| 438 } | 500 } |
| 439 | 501 |
| 440 base::PlatformFileError | 502 base::PlatformFileError NativeMediaFileUtil::GetLocalFilePath( |
| 441 NativeMediaFileUtil::GetFilteredLocalFilePathForExistingFileOrDirectory( | |
| 442 fileapi::FileSystemOperationContext* context, | 503 fileapi::FileSystemOperationContext* context, |
| 443 const fileapi::FileSystemURL& file_system_url, | 504 const fileapi::FileSystemURL& url, |
| 444 base::PlatformFileError failure_error, | |
| 445 base::FilePath* local_file_path) { | 505 base::FilePath* local_file_path) { |
| 506 DCHECK(local_file_path); |
| 507 DCHECK(url.is_valid()); |
| 508 if (url.path().empty()) { |
| 509 // Root direcory case, which should not be accessed. |
| 510 return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; |
| 511 } |
| 512 *local_file_path = url.path(); |
| 513 return base::PLATFORM_FILE_OK; |
| 514 } |
| 515 |
| 516 base::PlatformFileError NativeMediaFileUtil::ReadDirectorySync( |
| 517 fileapi::FileSystemOperationContext* context, |
| 518 const fileapi::FileSystemURL& url, |
| 519 EntryList* file_list) { |
| 446 DCHECK(IsOnTaskRunnerThread(context)); | 520 DCHECK(IsOnTaskRunnerThread(context)); |
| 447 base::FilePath file_path; | 521 DCHECK(file_list); |
| 448 base::PlatformFileError error = | 522 DCHECK(file_list->empty()); |
| 449 GetLocalFilePath(context, file_system_url, &file_path); | 523 base::PlatformFileInfo file_info; |
| 524 base::FilePath platform_path; |
| 525 base::PlatformFileError error = GetFileInfoSync(context, url, &file_info, |
| 526 &platform_path); |
| 527 |
| 450 if (error != base::PLATFORM_FILE_OK) | 528 if (error != base::PLATFORM_FILE_OK) |
| 451 return error; | 529 return error; |
| 452 | 530 |
| 453 if (!file_util::PathExists(file_path)) | 531 if (!file_info.is_directory) |
| 454 return failure_error; | 532 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
| 455 base::PlatformFileInfo file_info; | |
| 456 if (!file_util::GetFileInfo(file_path, &file_info)) | |
| 457 return base::PLATFORM_FILE_ERROR_FAILED; | |
| 458 | 533 |
| 459 if (!file_info.is_directory && | 534 file_util::FileEnumerator file_enum( |
| 460 !GetMediaPathFilter(context)->Match(file_path)) { | 535 platform_path, |
| 461 return failure_error; | 536 false /* recursive */, |
| 537 file_util::FileEnumerator::FILES | |
| 538 file_util::FileEnumerator::DIRECTORIES); |
| 539 file_util::FileEnumerator::FindInfo file_util_info; |
| 540 #if defined(OS_WIN) |
| 541 memset(&file_util_info, 0, sizeof(file_util_info)); |
| 542 #endif // defined(OS_WIN) |
| 543 |
| 544 for (base::FilePath platform_path = file_enum.Next(); |
| 545 !platform_path.empty(); |
| 546 platform_path = file_enum.Next()) { |
| 547 // Skip symlinks. |
| 548 if (file_util::IsLink(platform_path)) |
| 549 continue; |
| 550 |
| 551 file_enum.GetFindInfo(&file_util_info); |
| 552 |
| 553 // NativeMediaFileUtil skip criteria. |
| 554 if (ShouldSkip(platform_path)) |
| 555 continue; |
| 556 if (!file_util::FileEnumerator::IsDirectory(file_util_info) && |
| 557 !GetMediaPathFilter(context)->Match(platform_path)) |
| 558 continue; |
| 559 |
| 560 fileapi::DirectoryEntry entry; |
| 561 entry.is_directory = file_util::FileEnumerator::IsDirectory(file_util_info); |
| 562 entry.name = platform_path.BaseName().value(); |
| 563 entry.size = file_util::FileEnumerator::GetFilesize(file_util_info); |
| 564 entry.last_modified_time = |
| 565 file_util::FileEnumerator::GetLastModifiedTime(file_util_info); |
| 566 |
| 567 file_list->push_back(entry); |
| 462 } | 568 } |
| 463 | 569 |
| 464 *local_file_path = file_path; | |
| 465 return base::PLATFORM_FILE_OK; | 570 return base::PLATFORM_FILE_OK; |
| 466 } | 571 } |
| 467 | 572 |
| 468 base::PlatformFileError NativeMediaFileUtil::DeleteDirectorySync( | 573 base::PlatformFileError NativeMediaFileUtil::DeleteDirectorySync( |
| 469 fileapi::FileSystemOperationContext* context, | 574 fileapi::FileSystemOperationContext* context, |
| 470 const fileapi::FileSystemURL& url) { | 575 const fileapi::FileSystemURL& url) { |
| 471 DCHECK(IsOnTaskRunnerThread(context)); | 576 DCHECK(IsOnTaskRunnerThread(context)); |
| 472 base::FilePath file_path; | 577 base::FilePath file_path; |
| 473 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); | 578 base::PlatformFileError error = GetLocalFilePath(context, url, &file_path); |
| 474 if (error != base::PLATFORM_FILE_OK) | 579 if (error != base::PLATFORM_FILE_OK) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 489 error = base::PLATFORM_FILE_ERROR_NOT_A_FILE; | 594 error = base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
| 490 if (error == base::PLATFORM_FILE_OK) | 595 if (error == base::PLATFORM_FILE_OK) |
| 491 error = NativeMediaFileUtil::IsMediaFile(*platform_path); | 596 error = NativeMediaFileUtil::IsMediaFile(*platform_path); |
| 492 | 597 |
| 493 // We're just returning the local file information. | 598 // We're just returning the local file information. |
| 494 *file_ref = scoped_refptr<webkit_blob::ShareableFileReference>(); | 599 *file_ref = scoped_refptr<webkit_blob::ShareableFileReference>(); |
| 495 | 600 |
| 496 return error; | 601 return error; |
| 497 } | 602 } |
| 498 | 603 |
| 499 // static | 604 base::PlatformFileError NativeMediaFileUtil::GetFilteredLocalFilePath( |
| 500 base::PlatformFileError NativeMediaFileUtil::IsMediaFile( | 605 fileapi::FileSystemOperationContext* context, |
| 501 const base::FilePath& path) { | 606 const fileapi::FileSystemURL& file_system_url, |
| 502 base::PlatformFile file_handle; | 607 base::FilePath* local_file_path) { |
| 503 const int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; | 608 DCHECK(IsOnTaskRunnerThread(context)); |
| 609 base::FilePath file_path; |
| 504 base::PlatformFileError error = | 610 base::PlatformFileError error = |
| 505 fileapi::NativeFileUtil::CreateOrOpen(path, flags, &file_handle, NULL); | 611 GetLocalFilePath(context, file_system_url, &file_path); |
| 612 if (error != base::PLATFORM_FILE_OK) |
| 613 return error; |
| 614 if (!GetMediaPathFilter(context)->Match(file_path)) |
| 615 return base::PLATFORM_FILE_ERROR_SECURITY; |
| 616 |
| 617 *local_file_path = file_path; |
| 618 return base::PLATFORM_FILE_OK; |
| 619 } |
| 620 |
| 621 base::PlatformFileError |
| 622 NativeMediaFileUtil::GetFilteredLocalFilePathForExistingFileOrDirectory( |
| 623 fileapi::FileSystemOperationContext* context, |
| 624 const fileapi::FileSystemURL& file_system_url, |
| 625 base::PlatformFileError failure_error, |
| 626 base::FilePath* local_file_path) { |
| 627 DCHECK(IsOnTaskRunnerThread(context)); |
| 628 base::FilePath file_path; |
| 629 base::PlatformFileError error = |
| 630 GetLocalFilePath(context, file_system_url, &file_path); |
| 506 if (error != base::PLATFORM_FILE_OK) | 631 if (error != base::PLATFORM_FILE_OK) |
| 507 return error; | 632 return error; |
| 508 | 633 |
| 509 ScopedPlatformFile scoped_platform_file(&file_handle); | 634 if (!file_util::PathExists(file_path)) |
| 510 char buffer[net::kMaxBytesToSniff]; | 635 return failure_error; |
| 636 base::PlatformFileInfo file_info; |
| 637 if (!file_util::GetFileInfo(file_path, &file_info)) |
| 638 return base::PLATFORM_FILE_ERROR_FAILED; |
| 511 | 639 |
| 512 // Read as much as net::SniffMimeTypeFromLocalData() will bother looking at. | 640 if (!file_info.is_directory && |
| 513 int64 len = | 641 !GetMediaPathFilter(context)->Match(file_path)) { |
| 514 base::ReadPlatformFile(file_handle, 0, buffer, net::kMaxBytesToSniff); | 642 return failure_error; |
| 515 if (len < 0) | 643 } |
| 516 return base::PLATFORM_FILE_ERROR_FAILED; | |
| 517 if (len == 0) | |
| 518 return base::PLATFORM_FILE_ERROR_SECURITY; | |
| 519 | 644 |
| 520 std::string mime_type; | 645 *local_file_path = file_path; |
| 521 if (!net::SniffMimeTypeFromLocalData(buffer, len, &mime_type)) | 646 return base::PLATFORM_FILE_OK; |
| 522 return base::PLATFORM_FILE_ERROR_SECURITY; | |
| 523 | |
| 524 if (StartsWithASCII(mime_type, "image/", true) || | |
| 525 StartsWithASCII(mime_type, "audio/", true) || | |
| 526 StartsWithASCII(mime_type, "video/", true) || | |
| 527 mime_type == "application/x-shockwave-flash") { | |
| 528 return base::PLATFORM_FILE_OK; | |
| 529 } | |
| 530 return base::PLATFORM_FILE_ERROR_SECURITY; | |
| 531 } | |
| 532 | |
| 533 void NativeMediaFileUtil::CreateDirectoryOnTaskRunnerThread( | |
| 534 fileapi::FileSystemOperationContext* context, | |
| 535 const fileapi::FileSystemURL& url, | |
| 536 bool exclusive, | |
| 537 bool recursive, | |
| 538 const StatusCallback& callback) { | |
| 539 DCHECK(IsOnTaskRunnerThread(context)); | |
| 540 base::PlatformFileError error = | |
| 541 CreateDirectorySync(context, url, exclusive, recursive); | |
| 542 if (callback.is_null()) | |
| 543 return; | |
| 544 content::BrowserThread::PostTask( | |
| 545 content::BrowserThread::IO, | |
| 546 FROM_HERE, | |
| 547 base::Bind(callback, error)); | |
| 548 } | |
| 549 | |
| 550 void NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread( | |
| 551 fileapi::FileSystemOperationContext* context, | |
| 552 const fileapi::FileSystemURL& url, | |
| 553 const GetFileInfoCallback& callback) { | |
| 554 DCHECK(IsOnTaskRunnerThread(context)); | |
| 555 base::PlatformFileInfo file_info; | |
| 556 base::FilePath platform_path; | |
| 557 base::PlatformFileError error = | |
| 558 GetFileInfoSync(context, url, &file_info, &platform_path); | |
| 559 if (callback.is_null()) | |
| 560 return; | |
| 561 content::BrowserThread::PostTask( | |
| 562 content::BrowserThread::IO, | |
| 563 FROM_HERE, | |
| 564 base::Bind(callback, error, file_info, platform_path)); | |
| 565 } | |
| 566 | |
| 567 void NativeMediaFileUtil::ReadDirectoryOnTaskRunnerThread( | |
| 568 fileapi::FileSystemOperationContext* context, | |
| 569 const fileapi::FileSystemURL& url, | |
| 570 const ReadDirectoryCallback& callback) { | |
| 571 DCHECK(IsOnTaskRunnerThread(context)); | |
| 572 EntryList entry_list; | |
| 573 base::PlatformFileError error = | |
| 574 ReadDirectorySync(context, url, &entry_list); | |
| 575 if (callback.is_null()) | |
| 576 return; | |
| 577 content::BrowserThread::PostTask( | |
| 578 content::BrowserThread::IO, | |
| 579 FROM_HERE, | |
| 580 base::Bind(callback, error, entry_list, false /* has_more */)); | |
| 581 } | |
| 582 | |
| 583 void NativeMediaFileUtil::CopyOrMoveFileLocalOnTaskRunnerThread( | |
| 584 fileapi::FileSystemOperationContext* context, | |
| 585 const fileapi::FileSystemURL& src_url, | |
| 586 const fileapi::FileSystemURL& dest_url, | |
| 587 bool copy, | |
| 588 const StatusCallback& callback) { | |
| 589 DCHECK(IsOnTaskRunnerThread(context)); | |
| 590 base::PlatformFileError error = | |
| 591 CopyOrMoveFileSync(context, src_url, dest_url, copy); | |
| 592 if (callback.is_null()) | |
| 593 return; | |
| 594 content::BrowserThread::PostTask( | |
| 595 content::BrowserThread::IO, | |
| 596 FROM_HERE, | |
| 597 base::Bind(callback, error)); | |
| 598 } | |
| 599 | |
| 600 void NativeMediaFileUtil::CopyInForeignFileOnTaskRunnerThread( | |
| 601 fileapi::FileSystemOperationContext* context, | |
| 602 const base::FilePath& src_file_path, | |
| 603 const fileapi::FileSystemURL& dest_url, | |
| 604 const StatusCallback& callback) { | |
| 605 DCHECK(IsOnTaskRunnerThread(context)); | |
| 606 base::PlatformFileError error = | |
| 607 CopyInForeignFileSync(context, src_file_path, dest_url); | |
| 608 if (callback.is_null()) | |
| 609 return; | |
| 610 content::BrowserThread::PostTask( | |
| 611 content::BrowserThread::IO, | |
| 612 FROM_HERE, | |
| 613 base::Bind(callback, error)); | |
| 614 } | |
| 615 | |
| 616 void NativeMediaFileUtil::DeleteDirectoryOnTaskRunnerThread( | |
| 617 fileapi::FileSystemOperationContext* context, | |
| 618 const fileapi::FileSystemURL& url, | |
| 619 const StatusCallback& callback) { | |
| 620 DCHECK(IsOnTaskRunnerThread(context)); | |
| 621 base::PlatformFileError error = DeleteDirectorySync(context, url); | |
| 622 if (callback.is_null()) | |
| 623 return; | |
| 624 content::BrowserThread::PostTask( | |
| 625 content::BrowserThread::IO, | |
| 626 FROM_HERE, | |
| 627 base::Bind(callback, error)); | |
| 628 } | |
| 629 | |
| 630 void NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread( | |
| 631 fileapi::FileSystemOperationContext* context, | |
| 632 const fileapi::FileSystemURL& url, | |
| 633 const CreateSnapshotFileCallback& callback) { | |
| 634 DCHECK(IsOnTaskRunnerThread(context)); | |
| 635 base::PlatformFileInfo file_info; | |
| 636 base::FilePath platform_path; | |
| 637 scoped_refptr<webkit_blob::ShareableFileReference> file_ref; | |
| 638 base::PlatformFileError error = | |
| 639 CreateSnapshotFileSync(context, url, &file_info, &platform_path, | |
| 640 &file_ref); | |
| 641 if (callback.is_null()) | |
| 642 return; | |
| 643 content::BrowserThread::PostTask( | |
| 644 content::BrowserThread::IO, | |
| 645 FROM_HERE, | |
| 646 base::Bind(callback, error, file_info, platform_path, file_ref)); | |
| 647 } | 647 } |
| 648 | 648 |
| 649 } // namespace chrome | 649 } // namespace chrome |
| OLD | NEW |