summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authortzik@chromium.org <tzik@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-02 02:55:28 +0000
committertzik@chromium.org <tzik@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-02 02:55:28 +0000
commit6ef35d66ae67adf6cc21dc315ad6dc24e74591b8 (patch)
treee5c041745c20d1b2e26923ddbd758ef599d6a366 /webkit
parentd5286715d9edd31b2082339df6f2345431454fff (diff)
downloadchromium_src-6ef35d66ae67adf6cc21dc315ad6dc24e74591b8.zip
chromium_src-6ef35d66ae67adf6cc21dc315ad6dc24e74591b8.tar.gz
chromium_src-6ef35d66ae67adf6cc21dc315ad6dc24e74591b8.tar.bz2
Implement media path filter
BUG=137670 TEST='NativeMediaFileUtilTest.*' Review URL: https://chromiumcodereview.appspot.com/10825042 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149566 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/fileapi/file_system_context.cc2
-rw-r--r--webkit/fileapi/file_system_operation_context.h11
-rw-r--r--webkit/fileapi/file_system_operation_interface.h5
-rw-r--r--webkit/fileapi/file_system_types.h8
-rw-r--r--webkit/fileapi/file_system_util.cc2
-rw-r--r--webkit/fileapi/isolated_mount_point_provider.cc32
-rw-r--r--webkit/fileapi/isolated_mount_point_provider.h5
-rw-r--r--webkit/fileapi/media/media_path_filter.cc51
-rw-r--r--webkit/fileapi/media/media_path_filter.h35
-rw-r--r--webkit/fileapi/media/native_media_file_util.cc191
-rw-r--r--webkit/fileapi/media/native_media_file_util.h72
-rw-r--r--webkit/fileapi/media/native_media_file_util_unittest.cc201
-rw-r--r--webkit/fileapi/obfuscated_file_util.cc22
-rw-r--r--webkit/fileapi/webkit_fileapi.gypi4
14 files changed, 619 insertions, 22 deletions
diff --git a/webkit/fileapi/file_system_context.cc b/webkit/fileapi/file_system_context.cc
index 2b8c7fa..53afbb1 100644
--- a/webkit/fileapi/file_system_context.cc
+++ b/webkit/fileapi/file_system_context.cc
@@ -124,6 +124,8 @@ FileSystemMountPointProvider* FileSystemContext::GetMountPointProvider(
return external_provider_.get();
case kFileSystemTypeIsolated:
case kFileSystemTypeDragged:
+ case kFileSystemTypeNativeMedia:
+ case kFileSystemTypeDeviceMedia:
return isolated_provider_.get();
default:
if (provider_map_.find(type) != provider_map_.end())
diff --git a/webkit/fileapi/file_system_operation_context.h b/webkit/fileapi/file_system_operation_context.h
index 1cb51b9..7b26539 100644
--- a/webkit/fileapi/file_system_operation_context.h
+++ b/webkit/fileapi/file_system_operation_context.h
@@ -19,6 +19,8 @@ class SequencedTaskRunner;
namespace fileapi {
+class MediaPathFilter;
+
class FILEAPI_EXPORT_PRIVATE FileSystemOperationContext {
public:
explicit FileSystemOperationContext(FileSystemContext* context);
@@ -35,10 +37,19 @@ class FILEAPI_EXPORT_PRIVATE FileSystemOperationContext {
base::SequencedTaskRunner* file_task_runner() const;
+ void set_media_path_filter(MediaPathFilter* media_path_filter) {
+ media_path_filter_ = media_path_filter;
+ }
+
+ MediaPathFilter* media_path_filter() {
+ return media_path_filter_;
+ }
+
private:
scoped_refptr<FileSystemContext> file_system_context_;
int64 allowed_bytes_growth_;
+ MediaPathFilter* media_path_filter_;
};
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_operation_interface.h b/webkit/fileapi/file_system_operation_interface.h
index 404c9f7..7ea0ae1 100644
--- a/webkit/fileapi/file_system_operation_interface.h
+++ b/webkit/fileapi/file_system_operation_interface.h
@@ -74,12 +74,15 @@ class FileSystemOperationInterface {
base::PlatformFile file,
base::ProcessHandle peer_handle)> OpenFileCallback;
+ // Used for ReadDirectoryCallback.
+ typedef std::vector<base::FileUtilProxy::Entry> FileEntryList;
+
// Used for ReadDirectory(). |result| is the return code of the operation,
// |file_list| is the list of files read, and |has_more| is true if some files
// are yet to be read.
typedef base::Callback<
void(base::PlatformFileError result,
- const std::vector<base::FileUtilProxy::Entry>& file_list,
+ const FileEntryList& file_list,
bool has_more)> ReadDirectoryCallback;
// Used for CreateSnapshotFile(). (Please see the comment at
diff --git a/webkit/fileapi/file_system_types.h b/webkit/fileapi/file_system_types.h
index 85de365..4816781 100644
--- a/webkit/fileapi/file_system_types.h
+++ b/webkit/fileapi/file_system_types.h
@@ -37,6 +37,14 @@ enum FileSystemType {
// Internal filesystem types, which are not exposed to WebKit but are
// accessible via Isolated file system.
kFileSystemTypeDragged,
+
+ // Indicates media filesystem which we can access with same manner to
+ // regular filesystem.
+ kFileSystemTypeNativeMedia,
+
+ // Indicates media filesystem to which we need special protocol to access,
+ // such as MTP or PTP.
+ kFileSystemTypeDeviceMedia,
};
} // namespace fileapi
diff --git a/webkit/fileapi/file_system_util.cc b/webkit/fileapi/file_system_util.cc
index ec406ac..d77d7f3 100644
--- a/webkit/fileapi/file_system_util.cc
+++ b/webkit/fileapi/file_system_util.cc
@@ -157,6 +157,8 @@ GURL GetFileSystemRootURI(const GURL& origin_url, FileSystemType type) {
return GURL(url + "/");
case kFileSystemTypeUnknown:
case kFileSystemTypeDragged:
+ case kFileSystemTypeNativeMedia:
+ case kFileSystemTypeDeviceMedia:
NOTREACHED();
}
NOTREACHED();
diff --git a/webkit/fileapi/isolated_mount_point_provider.cc b/webkit/fileapi/isolated_mount_point_provider.cc
index a8875a0..7e66106 100644
--- a/webkit/fileapi/isolated_mount_point_provider.cc
+++ b/webkit/fileapi/isolated_mount_point_provider.cc
@@ -21,6 +21,8 @@
#include "webkit/fileapi/isolated_file_util.h"
#include "webkit/fileapi/local_file_stream_writer.h"
#include "webkit/fileapi/local_file_system_operation.h"
+#include "webkit/fileapi/media/media_path_filter.h"
+#include "webkit/fileapi/media/native_media_file_util.h"
#include "webkit/fileapi/native_file_util.h"
namespace fileapi {
@@ -34,8 +36,10 @@ IsolatedContext* isolated_context() {
} // namespace
IsolatedMountPointProvider::IsolatedMountPointProvider()
- : isolated_file_util_(new IsolatedFileUtil()),
- dragged_file_util_(new DraggedFileUtil()) {
+ : media_path_filter_(new MediaPathFilter()),
+ isolated_file_util_(new IsolatedFileUtil()),
+ dragged_file_util_(new DraggedFileUtil()),
+ native_media_file_util_(new NativeMediaFileUtil()) {
}
IsolatedMountPointProvider::~IsolatedMountPointProvider() {
@@ -76,10 +80,23 @@ bool IsolatedMountPointProvider::IsRestrictedFileName(
FileSystemFileUtil* IsolatedMountPointProvider::GetFileUtil(
FileSystemType type) {
- if (type == kFileSystemTypeDragged)
- return dragged_file_util_.get();
- else
- return isolated_file_util_.get();
+ switch (type) {
+ case kFileSystemTypeIsolated:
+ return isolated_file_util_.get();
+ case kFileSystemTypeDragged:
+ return dragged_file_util_.get();
+ case kFileSystemTypeNativeMedia:
+ return native_media_file_util_.get();
+
+ case kFileSystemTypeDeviceMedia:
+ case kFileSystemTypeTemporary:
+ case kFileSystemTypePersistent:
+ case kFileSystemTypeExternal:
+ case kFileSystemTypeTest:
+ case kFileSystemTypeUnknown:
+ NOTREACHED();
+ }
+ return NULL;
}
FilePath IsolatedMountPointProvider::GetPathForPermissionsCheck(
@@ -95,6 +112,9 @@ IsolatedMountPointProvider::CreateFileSystemOperation(
FileSystemContext* context) const {
scoped_ptr<FileSystemOperationContext> operation_context(
new FileSystemOperationContext(context));
+ if (url.type() == kFileSystemTypeNativeMedia ||
+ url.type() == kFileSystemTypeDeviceMedia)
+ operation_context->set_media_path_filter(media_path_filter_.get());
return new LocalFileSystemOperation(context, operation_context.Pass());
}
diff --git a/webkit/fileapi/isolated_mount_point_provider.h b/webkit/fileapi/isolated_mount_point_provider.h
index fe6f6bd..0bd5182 100644
--- a/webkit/fileapi/isolated_mount_point_provider.h
+++ b/webkit/fileapi/isolated_mount_point_provider.h
@@ -15,6 +15,8 @@ namespace fileapi {
class DraggedFileUtil;
class IsolatedContext;
class IsolatedFileUtil;
+class MediaPathFilter;
+class NativeMediaFileUtil;
class IsolatedMountPointProvider : public FileSystemMountPointProvider {
public:
@@ -56,8 +58,11 @@ class IsolatedMountPointProvider : public FileSystemMountPointProvider {
virtual FileSystemQuotaUtil* GetQuotaUtil() OVERRIDE;
private:
+ scoped_ptr<MediaPathFilter> media_path_filter_;
+
scoped_ptr<IsolatedFileUtil> isolated_file_util_;
scoped_ptr<DraggedFileUtil> dragged_file_util_;
+ scoped_ptr<NativeMediaFileUtil> native_media_file_util_;
};
} // namespace fileapi
diff --git a/webkit/fileapi/media/media_path_filter.cc b/webkit/fileapi/media/media_path_filter.cc
new file mode 100644
index 0000000..1239f83
--- /dev/null
+++ b/webkit/fileapi/media/media_path_filter.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/fileapi/media/media_path_filter.h"
+
+#include <algorithm>
+#include <string>
+
+#include "base/string_util.h"
+#include "net/base/mime_util.h"
+
+namespace fileapi {
+
+namespace {
+
+bool IsUnsupportedExtension(const FilePath::StringType& extension) {
+ std::string mime_type;
+ return !net::GetMimeTypeFromExtension(extension, &mime_type) ||
+ !net::IsSupportedMimeType(mime_type);
+}
+
+} // namespace
+
+MediaPathFilter::MediaPathFilter() {
+ net::GetImageExtensions(&media_file_extensions_);
+ net::GetAudioExtensions(&media_file_extensions_);
+ net::GetVideoExtensions(&media_file_extensions_);
+
+ MediaFileExtensionList::iterator new_end =
+ std::remove_if(media_file_extensions_.begin(),
+ media_file_extensions_.end(),
+ &IsUnsupportedExtension);
+ media_file_extensions_.erase(new_end, media_file_extensions_.end());
+
+ for (MediaFileExtensionList::iterator itr = media_file_extensions_.begin();
+ itr != media_file_extensions_.end(); ++itr)
+ *itr = FilePath::kExtensionSeparator + *itr;
+ std::sort(media_file_extensions_.begin(), media_file_extensions_.end());
+}
+
+MediaPathFilter::~MediaPathFilter() {
+}
+
+bool MediaPathFilter::Match(const FilePath& path) const {
+ return std::binary_search(media_file_extensions_.begin(),
+ media_file_extensions_.end(),
+ StringToLowerASCII(path.Extension()));
+}
+
+} // namespace fileapi
diff --git a/webkit/fileapi/media/media_path_filter.h b/webkit/fileapi/media/media_path_filter.h
new file mode 100644
index 0000000..003e979
--- /dev/null
+++ b/webkit/fileapi/media/media_path_filter.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_FILEAPI_MEDIA_MEDIA_PATH_FILTER_H_
+#define WEBKIT_FILEAPI_MEDIA_MEDIA_PATH_FILTER_H_
+
+#include <vector>
+
+#include "base/file_path.h"
+#include "webkit/fileapi/fileapi_export.h"
+
+class FilePath;
+
+namespace fileapi {
+
+// This class holds the list of file path extensions that we should expose on
+// media filesystem.
+class FILEAPI_EXPORT MediaPathFilter {
+ public:
+ MediaPathFilter();
+ ~MediaPathFilter();
+ bool Match(const FilePath& path) const;
+
+ private:
+ typedef std::vector<FilePath::StringType> MediaFileExtensionList;
+
+ MediaFileExtensionList media_file_extensions_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaPathFilter);
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_MEDIA_MEDIA_PATH_FILTER_H_
diff --git a/webkit/fileapi/media/native_media_file_util.cc b/webkit/fileapi/media/native_media_file_util.cc
new file mode 100644
index 0000000..e873523
--- /dev/null
+++ b/webkit/fileapi/media/native_media_file_util.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/fileapi/media/native_media_file_util.h"
+
+#include "net/base/mime_util.h"
+#include "webkit/fileapi/file_system_operation_context.h"
+#include "webkit/fileapi/media/media_path_filter.h"
+
+using base::PlatformFileError;
+using base::PlatformFileInfo;
+
+namespace fileapi {
+
+class MediaPathFilter;
+
+namespace {
+
+class FilteringFileEnumerator
+ : public FileSystemFileUtil::AbstractFileEnumerator {
+ public:
+ FilteringFileEnumerator(
+ scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> base_enumerator,
+ MediaPathFilter* filter)
+ : base_enumerator_(base_enumerator.Pass()),
+ filter_(filter) {
+ DCHECK(base_enumerator_.get());
+ DCHECK(filter);
+ }
+
+ virtual FilePath Next() OVERRIDE {
+ while (true) {
+ FilePath next = base_enumerator_->Next();
+ if (next.empty() ||
+ base_enumerator_->IsDirectory() ||
+ filter_->Match(next))
+ return next;
+ }
+ }
+
+ virtual int64 Size() OVERRIDE {
+ return base_enumerator_->Size();
+ }
+
+ virtual base::Time LastModifiedTime() OVERRIDE {
+ return base_enumerator_->LastModifiedTime();
+ }
+
+ virtual bool IsDirectory() OVERRIDE {
+ return base_enumerator_->IsDirectory();
+ }
+
+ private:
+ scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> base_enumerator_;
+ MediaPathFilter* filter_;
+};
+
+} // namespace
+
+NativeMediaFileUtil::NativeMediaFileUtil() {
+}
+
+PlatformFileError NativeMediaFileUtil::CreateOrOpen(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url,
+ int file_flags,
+ PlatformFile* file_handle,
+ bool* created) {
+ // TODO(tzik): Apply context()->mime_path_filter() here when we support write
+ // access.
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+}
+
+PlatformFileError NativeMediaFileUtil::EnsureFileExists(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url, bool* created) {
+ // TODO(tzik): Apply context()->mime_path_filter() here when we support write
+ // access.
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+}
+
+FileSystemFileUtil::AbstractFileEnumerator*
+NativeMediaFileUtil::CreateFileEnumerator(
+ FileSystemOperationContext* context,
+ const FileSystemURL& root_url,
+ bool recursive) {
+ DCHECK(context);
+
+ AbstractFileEnumerator* base_enumerator =
+ IsolatedFileUtil::CreateFileEnumerator(context, root_url, recursive);
+ return new FilteringFileEnumerator(
+ scoped_ptr<AbstractFileEnumerator>(base_enumerator),
+ context->media_path_filter());
+}
+
+PlatformFileError NativeMediaFileUtil::Touch(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url,
+ const base::Time& last_access_time,
+ const base::Time& last_modified_time) {
+ // TODO(tzik): Apply context()->mime_path_filter() here when we support write
+ // access.
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+}
+
+PlatformFileError NativeMediaFileUtil::Truncate(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url,
+ int64 length) {
+ // TODO(tzik): Apply context()->mime_path_filter() here when we support write
+ // access.
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+}
+
+bool NativeMediaFileUtil::PathExists(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url) {
+ DCHECK(context);
+
+ FilePath path;
+ PlatformFileInfo file_info;
+ PlatformFileError error =
+ GetFileInfo(context, url, &file_info, &path);
+ return error == base::PLATFORM_FILE_OK;
+}
+
+bool NativeMediaFileUtil::IsDirectoryEmpty(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url) {
+ DCHECK(context);
+ DCHECK(context->media_path_filter());
+
+ scoped_ptr<AbstractFileEnumerator> enumerator(
+ CreateFileEnumerator(context, url, false));
+ FilePath path;
+ while (!(path = enumerator->Next()).empty()) {
+ if (enumerator->IsDirectory() ||
+ context->media_path_filter()->Match(path))
+ return false;
+ }
+ return true;
+}
+
+PlatformFileError NativeMediaFileUtil::CopyOrMoveFile(
+ FileSystemOperationContext* context,
+ const FileSystemURL& src_url,
+ const FileSystemURL& dest_url,
+ bool copy) {
+ // TODO(tzik): Apply context()->mime_path_filter() here when we support write
+ // access.
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+}
+
+PlatformFileError NativeMediaFileUtil::CopyInForeignFile(
+ FileSystemOperationContext* context,
+ const FilePath& src_file_path,
+ const FileSystemURL& dest_url) {
+ // TODO(tzik): Apply context()->mime_path_filter() here when we support write
+ // access.
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+}
+
+PlatformFileError NativeMediaFileUtil::DeleteFile(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url) {
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+}
+
+PlatformFileError NativeMediaFileUtil::GetFileInfo(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url,
+ PlatformFileInfo* file_info,
+ FilePath* platform_path) {
+ DCHECK(context);
+ DCHECK(context->media_path_filter());
+ DCHECK(file_info);
+ DCHECK(platform_path);
+
+ base::PlatformFileError error =
+ IsolatedFileUtil::GetFileInfo(context, url, file_info, platform_path);
+ if (error != base::PLATFORM_FILE_OK)
+ return error;
+
+ if (file_info->is_directory ||
+ context->media_path_filter()->Match(*platform_path))
+ return base::PLATFORM_FILE_OK;
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND;
+}
+
+} // namespace fileapi
diff --git a/webkit/fileapi/media/native_media_file_util.h b/webkit/fileapi/media/native_media_file_util.h
new file mode 100644
index 0000000..2087340
--- /dev/null
+++ b/webkit/fileapi/media/native_media_file_util.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_FILEAPI_MEDIA_NATIVE_MEDIA_FILE_UTIL_H_
+#define WEBKIT_FILEAPI_MEDIA_NATIVE_MEDIA_FILE_UTIL_H_
+
+#include "webkit/fileapi/fileapi_export.h"
+#include "webkit/fileapi/isolated_file_util.h"
+
+namespace fileapi {
+
+// This class handles native file system operations with media type filtering
+// which is passed to each method via FileSystemOperationContext as
+// MediaPathFilter.
+class FILEAPI_EXPORT_PRIVATE NativeMediaFileUtil : public IsolatedFileUtil {
+ public:
+ NativeMediaFileUtil();
+
+ virtual PlatformFileError CreateOrOpen(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url,
+ int file_flags,
+ PlatformFile* file_handle,
+ bool* created) OVERRIDE;
+ virtual PlatformFileError EnsureFileExists(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url, bool* created) OVERRIDE;
+ virtual AbstractFileEnumerator* CreateFileEnumerator(
+ FileSystemOperationContext* context,
+ const FileSystemURL& root_url,
+ bool recursive) OVERRIDE;
+ virtual PlatformFileError Touch(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url,
+ const base::Time& last_access_time,
+ const base::Time& last_modified_time) OVERRIDE;
+ virtual PlatformFileError Truncate(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url,
+ int64 length) OVERRIDE;
+ virtual bool PathExists(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url) OVERRIDE;
+ virtual bool IsDirectoryEmpty(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url) OVERRIDE;
+ virtual PlatformFileError CopyOrMoveFile(
+ FileSystemOperationContext* context,
+ const FileSystemURL& src_url,
+ const FileSystemURL& dest_url,
+ bool copy) OVERRIDE;
+ virtual PlatformFileError CopyInForeignFile(
+ FileSystemOperationContext* context,
+ const FilePath& src_file_path,
+ const FileSystemURL& dest_url) OVERRIDE;
+ virtual PlatformFileError DeleteFile(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url) OVERRIDE;
+ virtual PlatformFileError GetFileInfo(
+ FileSystemOperationContext* context,
+ const FileSystemURL& url,
+ base::PlatformFileInfo* file_info,
+ FilePath* platform_path) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NativeMediaFileUtil);
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_MEDIA_NATIVE_MEDIA_FILE_UTIL_H_
diff --git a/webkit/fileapi/media/native_media_file_util_unittest.cc b/webkit/fileapi/media/native_media_file_util_unittest.cc
new file mode 100644
index 0000000..aeacdfe
--- /dev/null
+++ b/webkit/fileapi/media/native_media_file_util_unittest.cc
@@ -0,0 +1,201 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <set>
+#include <string>
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/scoped_temp_dir.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_operation_interface.h"
+#include "webkit/fileapi/isolated_context.h"
+#include "webkit/fileapi/media/native_media_file_util.h"
+#include "webkit/fileapi/mock_file_system_options.h"
+#include "webkit/fileapi/native_file_util.h"
+#include "webkit/quota/mock_special_storage_policy.h"
+
+#define FPL(x) FILE_PATH_LITERAL(x)
+
+using namespace fileapi;
+
+namespace {
+
+typedef FileSystemOperationInterface::FileEntryList FileEntryList;
+
+struct FilteringTestCase {
+ const FilePath::CharType* path;
+ bool is_directory;
+ bool visible;
+};
+
+const FilteringTestCase kFilteringTestCases[] = {
+ // Directory should always be visible.
+ { FPL("hoge"), true, true },
+ { FPL("fuga.jpg"), true, true },
+ { FPL("piyo.txt"), true, true },
+ { FPL("moga.cod"), true, true },
+
+ // File should be visible if it's a supported media file.
+ { FPL("foo"), false, false }, // File without extension.
+ { FPL("bar.jpg"), false, true }, // Supported media file.
+ { FPL("baz.txt"), false, false }, // Non-media file.
+ { FPL("foobar.cod"), false, false }, // Unsupported media file.
+};
+
+void ExpectEqHelper(base::PlatformFileError expected,
+ base::PlatformFileError actual) {
+ EXPECT_EQ(expected, actual);
+}
+
+void DidReadDirectory(std::set<FilePath::StringType>* content,
+ bool* completed,
+ base::PlatformFileError error,
+ const FileEntryList& file_list,
+ bool has_more) {
+ EXPECT_TRUE(!*completed);
+ *completed = !has_more;
+ for (FileEntryList::const_iterator itr = file_list.begin();
+ itr != file_list.end(); ++itr)
+ EXPECT_TRUE(content->insert(itr->name).second);
+}
+
+void PopulateDirectoryWithTestCases(const FilePath& dir,
+ const FilteringTestCase* test_cases,
+ size_t n) {
+ for (size_t i = 0; i < n; ++i) {
+ FilePath path = dir.Append(test_cases[i].path);
+ if (test_cases[i].is_directory) {
+ ASSERT_TRUE(file_util::CreateDirectory(path));
+ } else {
+ bool created = false;
+ ASSERT_EQ(base::PLATFORM_FILE_OK,
+ NativeFileUtil::EnsureFileExists(path, &created));
+ ASSERT_TRUE(created);
+ }
+ }
+}
+
+} // namespace
+
+class NativeMediaFileUtilTest : public testing::Test {
+ public:
+ NativeMediaFileUtilTest()
+ : file_util_(NULL) {
+ }
+
+ void SetUp() {
+ ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
+
+ scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
+ new quota::MockSpecialStoragePolicy();
+
+ file_system_context_ =
+ new FileSystemContext(
+ base::MessageLoopProxy::current(),
+ base::MessageLoopProxy::current(),
+ storage_policy,
+ NULL,
+ data_dir_.path(),
+ CreateAllowFileAccessOptions());
+
+ file_util_ = file_system_context_->GetFileUtil(kFileSystemTypeNativeMedia);
+
+ filesystem_id_ = isolated_context()->RegisterFileSystemForPath(
+ kFileSystemTypeNativeMedia, root_path(), NULL);
+
+ isolated_context()->AddReference(filesystem_id_);
+ }
+
+ void TearDown() {
+ isolated_context()->RemoveReference(filesystem_id_);
+ file_system_context_ = NULL;
+ }
+
+ protected:
+ FileSystemContext* file_system_context() {
+ return file_system_context_.get();
+ }
+
+ IsolatedContext* isolated_context() {
+ return IsolatedContext::GetInstance();
+ }
+
+ FilePath root_path() {
+ return data_dir_.path().Append(FPL("Media Directory"));
+ }
+
+ FileSystemFileUtil* file_util() {
+ return file_util_;
+ }
+
+ GURL origin() {
+ return GURL("http://example.com");
+ }
+
+ fileapi::FileSystemType type() {
+ return kFileSystemTypeNativeMedia;
+ }
+
+ FileSystemOperationInterface* NewOperation(const FileSystemURL& url) {
+ return file_system_context_->CreateFileSystemOperation(url);
+ }
+
+ private:
+ MessageLoop message_loop_;
+
+ ScopedTempDir data_dir_;
+ scoped_refptr<FileSystemContext> file_system_context_;
+
+ FileSystemFileUtil* file_util_;
+ std::string filesystem_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeMediaFileUtilTest);
+};
+
+TEST_F(NativeMediaFileUtilTest, DirectoryExistsAndFileExistsFiltering) {
+ PopulateDirectoryWithTestCases(root_path(),
+ kFilteringTestCases,
+ arraysize(kFilteringTestCases));
+
+ for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
+ FilePath path = root_path().Append(kFilteringTestCases[i].path);
+ FileSystemURL url(origin(), type(), path);
+ FileSystemOperationInterface* operation = NewOperation(url);
+
+ base::PlatformFileError expectation =
+ kFilteringTestCases[i].visible ?
+ base::PLATFORM_FILE_OK :
+ base::PLATFORM_FILE_ERROR_NOT_FOUND;
+
+ if (kFilteringTestCases[i].is_directory)
+ operation->DirectoryExists(url, base::Bind(&ExpectEqHelper, expectation));
+ else
+ operation->FileExists(url, base::Bind(&ExpectEqHelper, expectation));
+ MessageLoop::current()->RunAllPending();
+ }
+}
+
+TEST_F(NativeMediaFileUtilTest, ReadDirectoryFiltering) {
+ PopulateDirectoryWithTestCases(root_path(),
+ kFilteringTestCases,
+ arraysize(kFilteringTestCases));
+
+ std::set<FilePath::StringType> content;
+ FileSystemURL url(origin(), type(), root_path());
+ bool completed = false;
+ NewOperation(url)->ReadDirectory(
+ url, base::Bind(&DidReadDirectory, &content, &completed));
+ MessageLoop::current()->RunAllPending();
+ EXPECT_TRUE(completed);
+ EXPECT_EQ(5u, content.size());
+
+ for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
+ FilePath::StringType name =
+ FilePath(kFilteringTestCases[i].path).BaseName().value();
+ std::set<FilePath::StringType>::const_iterator found = content.find(name);
+ EXPECT_EQ(kFilteringTestCases[i].visible, found != content.end());
+ }
+}
diff --git a/webkit/fileapi/obfuscated_file_util.cc b/webkit/fileapi/obfuscated_file_util.cc
index ac11d2e..782ca00 100644
--- a/webkit/fileapi/obfuscated_file_util.cc
+++ b/webkit/fileapi/obfuscated_file_util.cc
@@ -960,21 +960,13 @@ bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType(
// Delete the origin directory if the deleted one was the last remaining
// type for the origin, i.e. if the *other* type doesn't exist.
FileSystemType other_type = kFileSystemTypeUnknown;
- switch (type) {
- case kFileSystemTypeTemporary:
- other_type = kFileSystemTypePersistent;
- break;
- case kFileSystemTypePersistent:
- other_type = kFileSystemTypeTemporary;
- break;
- // These types shouldn't be used.
- case kFileSystemTypeUnknown:
- case kFileSystemTypeIsolated:
- case kFileSystemTypeExternal:
- case kFileSystemTypeTest:
- case kFileSystemTypeDragged:
- NOTREACHED();
- }
+ if (type == kFileSystemTypeTemporary)
+ other_type = kFileSystemTypePersistent;
+ else if (type == kFileSystemTypePersistent)
+ other_type = kFileSystemTypeTemporary;
+ else
+ NOTREACHED();
+
if (!file_util::DirectoryExists(
origin_path.Append(GetDirectoryNameForType(other_type)))) {
InitOriginDatabase(false);
diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi
index 6df08f1..1bd5b5f 100644
--- a/webkit/fileapi/webkit_fileapi.gypi
+++ b/webkit/fileapi/webkit_fileapi.gypi
@@ -72,6 +72,10 @@
'local_file_stream_writer.h',
'local_file_system_operation.cc',
'local_file_system_operation.h',
+ 'media/media_path_filter.cc',
+ 'media/media_path_filter.h',
+ 'media/native_media_file_util.cc',
+ 'media/native_media_file_util.h',
'native_file_util.cc',
'native_file_util.h',
'obfuscated_file_util.cc',