Index: chrome/browser/media_galleries/fileapi/native_media_file_util.cc |
diff --git a/chrome/browser/media_galleries/fileapi/native_media_file_util.cc b/chrome/browser/media_galleries/fileapi/native_media_file_util.cc |
index 0239a6c6d25d7bf76126989c4a4b908e1e89da8b..25f933cd3a92ba7827508312e4f515eb232bfc56 100644 |
--- a/chrome/browser/media_galleries/fileapi/native_media_file_util.cc |
+++ b/chrome/browser/media_galleries/fileapi/native_media_file_util.cc |
@@ -6,7 +6,6 @@ |
#include "base/file_util.h" |
#include "base/string_util.h" |
-#include "chrome/browser/media_galleries/fileapi/filtering_file_enumerator.h" |
#include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_provider.h" |
#include "chrome/browser/media_galleries/fileapi/media_path_filter.h" |
#include "googleurl/src/gurl.h" |
@@ -15,6 +14,8 @@ |
#include "webkit/browser/fileapi/file_system_operation_context.h" |
#include "webkit/browser/fileapi/file_system_task_runners.h" |
#include "webkit/browser/fileapi/native_file_util.h" |
+#include "webkit/common/blob/shareable_file_reference.h" |
+#include "webkit/common/fileapi/file_system_util.h" |
using base::PlatformFile; |
using base::PlatformFileError; |
@@ -38,6 +39,49 @@ struct ScopedPlatformFileClose { |
typedef scoped_ptr<base::PlatformFile, ScopedPlatformFileClose> |
ScopedPlatformFile; |
+// Used to skip the hidden folders and files. Returns true if the file specified |
+// by |path| should be skipped. |
+bool ShouldSkip(const base::FilePath::StringType& base_name) { |
+ if (base_name.empty()) |
+ return false; |
+ |
+ // Dot files (aka hidden files) |
+ if (base_name[0] == '.') |
+ return true; |
+ |
+ // Mac OS X file. |
+ if (base_name == FILE_PATH_LITERAL("__MACOSX")) |
+ return true; |
+ |
+#if defined(OS_WIN) |
+ DWORD file_attributes = ::GetFileAttributes(path.value().c_str()); |
+ if ((file_attributes != INVALID_FILE_ATTRIBUTES) && |
+ ((file_attributes & FILE_ATTRIBUTE_HIDDEN) != 0)) |
+ return true; |
+#else |
+ // Windows always creates a recycle bin folder in the attached device to store |
+ // all the deleted contents. On non-windows operating systems, there is no way |
+ // to get the hidden attribute of windows recycle bin folders that are present |
+ // on the attached device. Therefore, compare the file path name to the |
+ // recycle bin name and exclude those folders. For more details, please refer |
+ // to http://support.microsoft.com/kb/171694. |
+ const char win_98_recycle_bin_name[] = "RECYCLED"; |
+ const char win_xp_recycle_bin_name[] = "RECYCLER"; |
+ const char win_vista_recycle_bin_name[] = "$Recycle.bin"; |
+ if ((base::strncasecmp(base_name.c_str(), |
+ win_98_recycle_bin_name, |
+ strlen(win_98_recycle_bin_name)) == 0) || |
+ (base::strncasecmp(base_name.c_str(), |
+ win_xp_recycle_bin_name, |
+ strlen(win_xp_recycle_bin_name)) == 0) || |
+ (base::strncasecmp(base_name.c_str(), |
+ win_vista_recycle_bin_name, |
+ strlen(win_vista_recycle_bin_name)) == 0)) |
+ return true; |
+#endif |
+ return false; |
+} |
+ |
// Returns true if the current thread is capable of doing IO. |
bool IsOnTaskRunnerThread(fileapi::FileSystemOperationContext* context) { |
return context->file_system_context()->task_runners()-> |
@@ -54,219 +98,244 @@ MediaPathFilter* GetMediaPathFilter(FileSystemOperationContext* context) { |
NativeMediaFileUtil::NativeMediaFileUtil() { |
} |
-PlatformFileError NativeMediaFileUtil::CreateOrOpen( |
+bool NativeMediaFileUtil::CreateOrOpen( |
FileSystemOperationContext* context, |
const FileSystemURL& url, |
int file_flags, |
- PlatformFile* file_handle, |
- bool* created) { |
+ const CreateOrOpenCallback& callback) { |
// Only called by NaCl, which should not have access to media file systems. |
- return base::PLATFORM_FILE_ERROR_SECURITY; |
+ base::PlatformFile invalid_file(base::kInvalidPlatformFileValue); |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, |
+ base::PassPlatformFile(&invalid_file), |
+ false); |
+ return true; |
} |
-PlatformFileError NativeMediaFileUtil::EnsureFileExists( |
+bool NativeMediaFileUtil::EnsureFileExists( |
FileSystemOperationContext* context, |
- const FileSystemURL& url, bool* created) { |
- base::FilePath file_path; |
- PlatformFileError error = GetFilteredLocalFilePath(context, url, &file_path); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
- return NativeFileUtil::EnsureFileExists(file_path, created); |
vandebo (ex-Chrome)
2013/05/30 18:39:19
This was for write support?
tommycli
2013/05/30 19:35:20
Yes, this function must make an empty file if one
|
+ const FileSystemURL& url, |
+ const EnsureFileExistsCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, false); |
+ return true; |
} |
-scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> |
-NativeMediaFileUtil::CreateFileEnumerator( |
+bool NativeMediaFileUtil::CreateDirectory( |
FileSystemOperationContext* context, |
- const FileSystemURL& root_url) { |
- DCHECK(context); |
- return make_scoped_ptr(new FilteringFileEnumerator( |
- IsolatedFileUtil::CreateFileEnumerator(context, root_url), |
- GetMediaPathFilter(context))) |
- .PassAs<FileSystemFileUtil::AbstractFileEnumerator>(); |
+ const FileSystemURL& url, |
+ bool exclusive, |
+ bool recursive, |
+ const StatusCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
+ return true; |
} |
-PlatformFileError NativeMediaFileUtil::Touch( |
+bool NativeMediaFileUtil::GetFileInfo( |
+ FileSystemOperationContext* context, |
+ const FileSystemURL& url, |
+ const GetFileInfoCallback& callback) { |
+ PlatformFileInfo file_info; |
+ base::FilePath platform_path; |
+ PlatformFileError error = |
+ GetFileInfoSync(context, url, &file_info, &platform_path); |
+ callback.Run(error, file_info, platform_path); |
+ return true; |
+} |
+ |
+bool NativeMediaFileUtil::ReadDirectory( |
+ FileSystemOperationContext* context, |
+ const FileSystemURL& url, |
+ const ReadDirectoryCallback& callback) { |
+ EntryList entry_list; |
+ PlatformFileError error = ReadDirectorySync( |
+ context, url, &entry_list); |
+ callback.Run(error, entry_list, false /* has_more */); |
+ return true; |
+} |
+ |
+bool NativeMediaFileUtil::Touch( |
FileSystemOperationContext* context, |
const FileSystemURL& url, |
const base::Time& last_access_time, |
- const base::Time& last_modified_time) { |
- base::FilePath file_path; |
- PlatformFileError error = GetFilteredLocalFilePathForExistingFileOrDirectory( |
- context, |
- url, |
- // Touch fails for non-existent paths and filtered paths. |
- base::PLATFORM_FILE_ERROR_FAILED, |
- &file_path); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
- return NativeFileUtil::Touch(file_path, last_access_time, last_modified_time); |
+ const base::Time& last_modified_time, |
+ const StatusCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
+ return true; |
} |
-PlatformFileError NativeMediaFileUtil::Truncate( |
+bool NativeMediaFileUtil::Truncate( |
FileSystemOperationContext* context, |
const FileSystemURL& url, |
- int64 length) { |
- base::FilePath file_path; |
- PlatformFileError error = GetFilteredLocalFilePathForExistingFileOrDirectory( |
- context, |
- url, |
- // Cannot truncate paths that do not exist, or are filtered. |
- base::PLATFORM_FILE_ERROR_NOT_FOUND, |
- &file_path); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
- return NativeFileUtil::Truncate(file_path, length); |
+ int64 length, |
+ const StatusCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
+ return true; |
} |
-PlatformFileError NativeMediaFileUtil::CopyOrMoveFile( |
+bool NativeMediaFileUtil::CopyFileLocal( |
FileSystemOperationContext* context, |
const FileSystemURL& src_url, |
const FileSystemURL& dest_url, |
- bool copy) { |
- base::FilePath src_file_path; |
- PlatformFileError error = |
- GetFilteredLocalFilePathForExistingFileOrDirectory( |
- context, src_url, |
- base::PLATFORM_FILE_ERROR_NOT_FOUND, |
- &src_file_path); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
- if (NativeFileUtil::DirectoryExists(src_file_path)) |
- return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
- |
- base::FilePath dest_file_path; |
- error = GetLocalFilePath(context, dest_url, &dest_file_path); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
- PlatformFileInfo file_info; |
- error = NativeFileUtil::GetFileInfo(dest_file_path, &file_info); |
- if (error != base::PLATFORM_FILE_OK && |
- error != base::PLATFORM_FILE_ERROR_NOT_FOUND) |
- return error; |
- if (error == base::PLATFORM_FILE_OK && file_info.is_directory) |
- return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
- if (!GetMediaPathFilter(context)->Match(dest_file_path)) |
- return base::PLATFORM_FILE_ERROR_SECURITY; |
+ const StatusCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
+ return true; |
+} |
- return NativeFileUtil::CopyOrMoveFile(src_file_path, dest_file_path, copy); |
+bool NativeMediaFileUtil::MoveFileLocal( |
+ FileSystemOperationContext* context, |
+ const FileSystemURL& src_url, |
+ const FileSystemURL& dest_url, |
+ const StatusCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
+ return true; |
} |
-PlatformFileError NativeMediaFileUtil::CopyInForeignFile( |
+bool NativeMediaFileUtil::CopyInForeignFile( |
FileSystemOperationContext* context, |
const base::FilePath& src_file_path, |
- const FileSystemURL& dest_url) { |
- if (src_file_path.empty()) |
- return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; |
+ const FileSystemURL& dest_url, |
+ const StatusCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
+ return true; |
+} |
- base::FilePath dest_file_path; |
- PlatformFileError error = |
- GetFilteredLocalFilePath(context, dest_url, &dest_file_path); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
- return NativeFileUtil::CopyOrMoveFile(src_file_path, dest_file_path, true); |
+bool NativeMediaFileUtil::DeleteFile( |
+ FileSystemOperationContext* context, |
+ const FileSystemURL& url, |
+ const StatusCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
+ return true; |
} |
-PlatformFileError NativeMediaFileUtil::DeleteFile( |
+bool NativeMediaFileUtil::DeleteDirectory( |
FileSystemOperationContext* context, |
- const FileSystemURL& url) { |
- base::FilePath file_path; |
- PlatformFileError error = GetLocalFilePath(context, url, &file_path); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
+ const FileSystemURL& url, |
+ const StatusCallback& callback) { |
+ callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); |
+ return true; |
+} |
+ |
+bool NativeMediaFileUtil::CreateSnapshotFile( |
+ FileSystemOperationContext* context, |
+ const FileSystemURL& url, |
+ const CreateSnapshotFileCallback& callback) { |
+ // We're just returning the local file information. |
PlatformFileInfo file_info; |
- error = NativeFileUtil::GetFileInfo(file_path, &file_info); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
- if (file_info.is_directory) |
- return base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
- if (!GetMediaPathFilter(context)->Match(file_path)) |
- return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
- return NativeFileUtil::DeleteFile(file_path); |
+ base::FilePath platform_path; |
+ PlatformFileError error = |
+ GetFileInfoSync(context, url, &file_info, &platform_path); |
+ if (error == base::PLATFORM_FILE_OK && file_info.is_directory) |
+ error = base::PLATFORM_FILE_ERROR_NOT_A_FILE; |
+ if (error == base::PLATFORM_FILE_OK) |
+ error = IsMediaFile(platform_path); |
+ |
+ callback.Run(error, file_info, platform_path, |
+ scoped_refptr<webkit_blob::ShareableFileReference>()); |
+ return true; |
} |
-PlatformFileError NativeMediaFileUtil::GetFileInfo( |
+PlatformFileError NativeMediaFileUtil::GetFileInfoSync( |
FileSystemOperationContext* context, |
const FileSystemURL& url, |
PlatformFileInfo* file_info, |
base::FilePath* platform_path) { |
DCHECK(context); |
- DCHECK(GetMediaPathFilter(context)); |
DCHECK(file_info); |
DCHECK(platform_path); |
+ DCHECK(GetMediaPathFilter(context)); |
- base::PlatformFileError error = |
- IsolatedFileUtil::GetFileInfo(context, url, file_info, platform_path); |
+ base::FilePath file_path; |
+ PlatformFileError error = GetLocalFilePath(context, url, &file_path); |
+ if (error != base::PLATFORM_FILE_OK) |
+ return error; |
+ // We should not follow symbolic links in sandboxed file system. |
vandebo (ex-Chrome)
2013/05/30 18:39:19
This isn't a sandboxed file system.
tommycli
2013/05/30 19:35:20
Done.
|
+ if (file_util::IsLink(file_path)) |
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
+ error = NativeFileUtil::GetFileInfo(file_path, file_info); |
if (error != base::PLATFORM_FILE_OK) |
return error; |
+ *platform_path = file_path; |
if (file_info->is_directory || |
- GetMediaPathFilter(context)->Match(*platform_path)) { |
+ GetMediaPathFilter(context)->Match(platform_path->BaseName().value())) { |
vandebo (ex-Chrome)
2013/05/30 18:39:19
Just pass the whole platform_path
tommycli
2013/05/30 19:35:20
Done. There was a reason I changed this, but that
|
return base::PLATFORM_FILE_OK; |
} |
return base::PLATFORM_FILE_ERROR_NOT_FOUND; |
} |
-PlatformFileError NativeMediaFileUtil::GetFilteredLocalFilePath( |
+PlatformFileError NativeMediaFileUtil::GetLocalFilePath( |
FileSystemOperationContext* context, |
- const FileSystemURL& file_system_url, |
+ const FileSystemURL& url, |
base::FilePath* local_file_path) { |
- base::FilePath file_path; |
- PlatformFileError error = |
- IsolatedFileUtil::GetLocalFilePath(context, file_system_url, &file_path); |
- if (error != base::PLATFORM_FILE_OK) |
- return error; |
- if (!GetMediaPathFilter(context)->Match(file_path)) |
- return base::PLATFORM_FILE_ERROR_SECURITY; |
- |
- *local_file_path = file_path; |
+ DCHECK(local_file_path); |
+ DCHECK(url.is_valid()); |
+ if (url.path().empty()) { |
+ // Root direcory case, which should not be accessed. |
+ return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; |
+ } |
+ *local_file_path = url.path(); |
return base::PLATFORM_FILE_OK; |
} |
-PlatformFileError |
-NativeMediaFileUtil::GetFilteredLocalFilePathForExistingFileOrDirectory( |
- FileSystemOperationContext* context, |
- const FileSystemURL& file_system_url, |
- PlatformFileError failure_error, |
- base::FilePath* local_file_path) { |
- base::FilePath file_path; |
- PlatformFileError error = |
- GetLocalFilePath(context, file_system_url, &file_path); |
+base::PlatformFileError NativeMediaFileUtil::ReadDirectorySync( |
+ FileSystemOperationContext* context, |
+ const FileSystemURL& url, |
+ EntryList* file_list) { |
+ DCHECK(file_list); |
+ DCHECK(file_list->empty()); |
+ base::PlatformFileInfo file_info; |
+ base::FilePath platform_path; |
+ PlatformFileError error = GetFileInfoSync(context, url, &file_info, |
+ &platform_path); |
+ |
+ if (error == base::PLATFORM_FILE_OK && !file_info.is_directory) |
+ return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
+ |
if (error != base::PLATFORM_FILE_OK) |
return error; |
- if (!file_util::PathExists(file_path)) |
- return failure_error; |
- PlatformFileInfo file_info; |
- if (!file_util::GetFileInfo(file_path, &file_info)) |
- return base::PLATFORM_FILE_ERROR_FAILED; |
- |
- if (!file_info.is_directory && |
- !GetMediaPathFilter(context)->Match(file_path)) { |
- return failure_error; |
+ file_util::FileEnumerator file_enum( |
+ platform_path, |
+ false /* recursive */, |
+ file_util::FileEnumerator::FILES | |
+ file_util::FileEnumerator::DIRECTORIES); |
+ file_util::FileEnumerator::FindInfo file_util_info; |
+#if defined(OS_WIN) |
+ memset(&file_util_info_, 0, sizeof(file_util_info)); |
+#endif // defined(OS_WIN) |
+ |
+ for (base::FilePath platform_path = file_enum.Next(); |
+ !platform_path.empty(); |
+ platform_path = file_enum.Next()) { |
+ base::FilePath::StringType base_name = |
+ fileapi::VirtualPath::BaseName(platform_path).value(); |
vandebo (ex-Chrome)
2013/05/30 18:39:19
platform_path is a a platform path not a virtual p
tommycli
2013/05/30 19:35:20
Done.
|
+ |
+ // Skip symlinks. |
+ if (file_util::IsLink(platform_path)) |
+ continue; |
+ |
+ file_enum.GetFindInfo(&file_util_info); |
+ |
+ // NativeMediaFileUtil skip criteria. |
+ if (ShouldSkip(base_name)) |
+ continue; |
+ |
+ if (!file_util::FileEnumerator::IsDirectory(file_util_info) && |
+ !GetMediaPathFilter(context)->Match(base_name)) |
+ continue; |
+ |
+ fileapi::DirectoryEntry entry; |
+ entry.is_directory = file_util::FileEnumerator::IsDirectory(file_util_info); |
+ entry.name = base_name; |
vandebo (ex-Chrome)
2013/05/30 18:39:19
There's a lot of mechanism to get this value in th
tommycli
2013/05/30 19:35:20
Done. Should be clearer in new version.
|
+ entry.size = file_util::FileEnumerator::GetFilesize(file_util_info); |
+ entry.last_modified_time = |
+ file_util::FileEnumerator::GetLastModifiedTime(file_util_info); |
+ |
+ file_list->push_back(entry); |
} |
- *local_file_path = file_path; |
return base::PLATFORM_FILE_OK; |
} |
-webkit_blob::ScopedFile NativeMediaFileUtil::CreateSnapshotFile( |
- fileapi::FileSystemOperationContext* context, |
- const fileapi::FileSystemURL& url, |
- base::PlatformFileError* error, |
- base::PlatformFileInfo* file_info, |
- base::FilePath* platform_path) { |
- DCHECK(IsOnTaskRunnerThread(context)); |
- webkit_blob::ScopedFile file; |
- file = IsolatedFileUtil::CreateSnapshotFile( |
- context, url, error, file_info, platform_path); |
- if (*error != base::PLATFORM_FILE_OK) |
- return file.Pass(); |
- *error = IsMediaFile(*platform_path); |
- if (*error == base::PLATFORM_FILE_OK) |
- return file.Pass(); |
- return webkit_blob::ScopedFile(); |
-} |
- |
// static |
base::PlatformFileError NativeMediaFileUtil::IsMediaFile( |
const base::FilePath& path) { |